Skip to content

cloud: v0.39.0

Choose a tag to compare

@github-actions github-actions released this 12 Oct 16:37
2aaebd3

0.39.0 (2026-10-12)

Features

  • ai: chart groups with a shared cursor, more chart kinds and one render path (#965) (98fd68a)
  • ai: explore a computed dataset in the chat with views, filters and comparison (#986) (cf55b85)
  • ai: serve Assistant models through an OpenAI-compatible endpoint with models-only keys (#969) (fff481b)
  • ai: show charts and tables computed in code runs without retyping their values (#949) (49399e0)
  • ai: show key figures, record details and linked Cloud objects from code runs (#972) (0898cc3)
  • ai: show the time on approval receipts, live and in history (#959) (d585ebc), closes #810
  • assistant: keep Cloud skills compatible with Agent Skills (#987) (a04da4b)
  • assistant: let cld work with local files and folders (#971) (0926d75)
  • assistant: run the Cloud Assistant in editors through ACP (#980) (df00d89)
  • chat: create chats and manage direct members through Cloud access (#1004) (39303fa)
  • chat: deliver live updates and recover after reconnects and gaps (#1029) (953aad1)
  • chat: post messages in gapless order with idempotent retries (#1017) (33fe78d)
  • cloud-login: approve Cloud actions from the Cloud Login app (#973) (73eab63)
  • cloud: approve pending actions inside Cloud, in the owning app and in the Assistant (#963) (cf15171)
  • cloud: keep Zod out of the mailbox first load and add a validator-free isCommandPath (#1009) (0843aec)
  • mail: keep quotes and code blocks in sent Markdown mail (#1022) (ac68216)
  • mail: keep the signature outside the editable mail body (#967) (a46c9e3)
  • mail: move a sender's or domain's mail in bulk and list failed commands (#1035) (ae17250), closes #487
  • mail: queue sender verification behind running provider work instead of rejecting it (#956) (d6cbf8d), closes #879
  • mail: show recent failed sync runs with their reasons (#962) (bc98b91), closes #877
  • notebooks: Enter, Backspace and list buttons behave like Docs (#1019) (7d48648)
  • notebooks: list numbers repair themselves, indent without Tab, and move items with their sub-items (#1010) (6e7b973)
  • notebooks: lists indent by structure with guides and show numbers 1./a./i. like Book (#1001) (8015de4)
  • notebooks: one 44rem reading column and one typography for writing, reading and Book (#1030) (75a70f9)
  • spaces: day and week views with a 06:00 day start, folded nights and scrolling between days (#1025) (d8d1bdf)
  • spaces: step through items with J and K while the detail panel is open (#1040) (d1d84b4)
  • ui: give the detail panel the full height and drop page titles the sidebar already shows (#1003) (081daf9)
  • ui: show row actions only on the hovered row when a tablet has a mouse (#989) (32bb9d0)

Bug Fixes

  • ai: let the model repair a malformed tool call instead of ending the turn silently (#968) (6e28096), closes #833
  • ai: stop chat compaction when the model provider stalls (#993) (7b938cd), closes #960 #961
  • cloud: mark required flags in cld help and document Mail template variables (#951) (c69438b)
  • cloud: update the MCP SDK past its OAuth credential advisory (#988) (c019fc5)
  • mail: keep a mailbox sending when its saved design has a value the stricter CSS check rejects (#966) (2813bf6)
  • mail: keep move sets short so new mail arrives while a bulk move drains (#984) (a2147f3), closes #913
  • mail: let a folder sync bring in new mail on time while body hydration runs (#999) (8079951), closes #983
  • mail: run incoming automations once per message and never on an all-mail copy (#950) (be81604), closes #882
  • mail: send a long message with the built-in design when the mailbox design would make it too complex (#1005) (030c38f), closes #991
  • mail: show formatting warnings in the automatic-reply preview (#1027) (4672035), closes #990
  • notebooks: hide a collaborator's name label after a few idle seconds (#975) (3ba2233)
  • notebooks: make text selection and collaborator cursors reliable in the editor (#985) (d7f2a6b)
  • scripts: let the page-weight baseline accept the mirrored Bun image (#1006) (e358c33)
  • spaces: count a task as overdue from the day after its deadline in the List and My tasks (#954) (0a3e7ef), closes #818
  • spaces: count and order List groups across all matching items (#964) (e72935c)
  • spaces: count only the shown month's entries in the month view (#1008) (ca62338), closes #809
  • spaces: move Kanban cards with the keyboard from their grip (#1024) (1219c21), closes #821
  • spaces: show a completed item's status in its column's color in the Table (#1002) (8fbba5b), closes #823
  • spaces: show the Kanban card grip and claim button on touch screens, with 44 px targets (#1011) (7758751), closes #819 #820
  • spaces: translate Kanban and List labels and call the List view "List" everywhere (#958) (3649fbc)
  • ui: give sidebar rows the same inset on the right as on the left (#974) (514b9f9)
  • ui: keep the conversation composer's placeholder on one line on phones (#995) (3cbd442)
  • ui: keep the selected week or day calendar event beside the tablet detail drawer (#1032) (f220f1e), closes #945
  • ui: let one Escape close a dialog whose first field is a Combobox (#970) (c68cb37)

Performance Improvements

  • notebooks: show the note text in the first paint (#1039) (18dae60)

Operator notes

TL;DR: No new environment variables, no new images and no Compose change, but five things need attention during the rollout. Reverse proxy timeout (#969): the gateway now waits up to 4 minutes for an application's response headers, so a reverse proxy in front of Cloud must wait at least 5 minutes. Update Core first, then Assistant and Mail right after (#963, #973, #987): people can now decide pending approvals in Cloud, in the owning app, in Assistant and in the Cloud Login app. Replace all Mail replicas at once (#967, #956, #962): drafts keep their signature in a new column, sender verification waits in line instead of failing, and sync.states in mail operator status now counts the last 24 hours. Cloud Login drops its app PIN (#973): deploy the new cloud-pwa-auth image and tell people that the phone's own screen lock now protects their approvals. Update cld and its plugins for cld acp, local files and folders, Skill sync and the new Mail commands (#971, #980, #987, #1035). The new OpenAI-compatible endpoint stays off until an administrator turns on ai.openai_api_enabled (#969). Two Mail CSS hardening fixes close gaps that exist in released versions (#966); see "Security".

Reference pages at this tag: Deployment requirements (sections "Decide pending approvals in Cloud", "Approve Actions in Cloud Login", "Mail draft signatures", "Queue Mail sender verification behind provider work", "Reuse Agent Skills folders", "Run Assistant in editors"), Offer the OpenAI-compatible API, OpenAI-compatible API, Approvals, Cloud Login: protect the app, Assistant in editors, Deprecations and migrations.

Before you deploy

  1. Back up the database right before the update. Every schema change in this release is additive and idempotent, and older versions ignore it, but a backup is the only way back for data written after the update.
  2. Reverse proxy: allow at least 5 minutes until response headers (#969). The gateway now keeps a client connection open while an application works on a slow answer and gives up after 4 minutes with 502 Upstream unavailable; once headers arrive, the 10-second idle limit applies again. A proxy with a shorter header timeout answers first. This matters most for the OpenAI-compatible endpoint, so set it before you turn that endpoint on. When a client disconnects first, the gateway now cancels the upstream request and records status 499 in Gateway Ops; such requests count toward the HTTP error rate but not as server errors or upstream failures, and they write no log.
  3. Update Core first, then Assistant and Mail right after, all replicas at once (#963, #973, #987). Assistant and Mail read the approvals list during server rendering, so Core must have migrated the approvals schema before they serve pages. Core and Assistant together carry the Agent Skills changes. Update the gateway in the same window, because the longer header wait and the upstream cancel live there.
  4. Mail: replace all replicas at once (#967, #956). A replica of the previous version does not read the new draft signature column, so a message it sends from a draft that the new version saved goes out without its signature. Previous-version replicas leave waiting sender verifications to updated ones.
  5. Cloud Login: deploy the cloud-pwa-auth image of this release (#973). A newer Cloud also works with an older Cloud Login server, which answers Action wake-ups with 400; Cloud ignores that. Paired phones keep signing in and show Actions after the app updates, without pairing again.
  6. Other applications: update them in any order after Core. Notebooks and Spaces carry their own editor, calendar and keyboard changes; the rest carry the shared library and UI changes. Pages of an older application image keep the previous detail panel and title layout until that image is updated (#1003).
  7. CLI: install the cld binary of this release and run cld plugins update --all. The plugins bring cld assistant acp (cld acp), local file and folder tools, cld assistant skills list|push|pull, cld mail sender move, the new cld mail command list options and the pending-verification output of cld mail identity verify (#971, #980, #987, #1035, #956). A cld from before this release prints Verified for a sender verification that still waits, so update cld together with Mail.

Migrations

All migrations run on the owning service's first start, are idempotent, and need no manual step. Rolling back leaves them in place; the previous version ignores them.

  • Core: approvals (#963, #973, #971). Core widens the decided_via CHECK constraint of approvals.requests to allow acp_bridge and cloud_login (only when the existing constraint lacks them), adds the nullable columns actions_at, action_wake_at and action_wake_ref to auth.app_devices, adds the column consumed_inline (default false) and the partial index idx_ai_pending_actions_approval to ai.pending_actions.
    • Rollback: an older Core keeps the wider constraint and the new columns and ignores them. It does not apply the ACP restriction, does not serve the new approval lists, and does not wake Cloud Login phones for Actions. Existing sign-in commands and pairing keys stay valid.
    • Check after the rollout: ask Assistant to send a Mail draft. Open My account → Approvals, the Assistant's Approvals view and the draft, and check that each shows the waiting request. Try to approve a confirm request through a client that sends x-cloud-client: acp: it must return 403 and leave the request open. Then approve it in Cloud and find the decision in the audit log.
  • Mail: draft signatures (#967). Mail adds the nullable column mail.drafts.signature_template_id. Existing drafts move a recognized signature out of the body when they are opened or saved; drafts that are not saved again still send with their in-body signature.
    • Rollback: rolling Mail back keeps the column, and drafts saved after the update then send without their signature.
    • Check after the rollout: open a new message in a mailbox with a default signature and check that the preview shows the signature below the text.
  • Mail: sender verification commands (#956). Mail replaces the commands_kind_check constraint of mail.commands to allow verify_sender_identity. The new constraint is added NOT VALID, so the table is not read.
    • Rollback: the wider constraint stays and the previous version ignores waiting verifications. After the next update, a verification that waited longer than 10 minutes fails with SENDER_VERIFICATION_TIMEOUT, and the person verifies again.
  • Mail: failed sync runs (#962). Mail builds the partial index sync_runs_resource_not_completed_idx on mail.sync_runs on the first start after the update. The build reads the table once and briefly blocks sync run writes; later starts skip it.
  • Mail: incoming automations (#950). Mail adds receipt_pending (boolean, default false) to mail.message_contents, only when it is missing, so a start does not wait behind a running search index build.
  • Chat (#1004, #1017, #1029) changes its schema, but Chat is not enabled: it stays behind its unreleased Compose profile.
  • No other application changes its schema in this release.

Security

  • Mailbox CSS and received mail (#966). Affects released versions. The CSS value check let a quoted string run across a raw line break, so a value such as font-family: "a<LF>;display:none;position:fixed;…" passed and applied extra declarations in Chromium and WebKit, in mailbox designs and in received mail. A quoted string must now close before a line break, and an escaped quote neither opens nor closes a string. Mailbox CSS also no longer accepts & in values or a quoted string that contains the other quote kind: the inliner decodes character references and rewrites quotes, so a design could reach sent mail with u\72l(…), which CSS reads as url(, or let !important break out. A CSS escape outside a quoted string now stands only for a non-ASCII or non-identifier character; escaped CJK font names in received mail keep working. The design editor's preview frame now has default-src 'none'; style-src 'unsafe-inline', so a stored or typed url() or image-set() no longer loads in the browser of the person editing it. Mailboxes whose saved design now contains a rejected value keep sending (see "Behavior changes").
  • Editors can reject but not approve confirm Actions (#963, #980). A client that sends x-cloud-client: acp decides through the new acp_bridge channel and can only reject a request that asks every time; the person approves it in Cloud or in Cloud Login. cld, OAuth and personal API keys keep their current rights. The editor bridge ships in this release, so no released version is affected.
  • Cloud Login without a PIN (#973). Anyone who can open Cloud Login on an unlocked phone can approve sign-ins and Actions. Device credentials stay encrypted in browser storage, but without a PIN the key is stored alongside them, so copied browser data is a full credential, now also for installations that had a PIN before. After a suspected compromise, revoke the devices in each Cloud and pair again. A device decision binds to a digest of exactly what the phone showed, and a request that changed, was decided elsewhere or expired answers 409.
  • Models-only API keys (#969). Keys with the new ai:inference scope work only on /api/ai/openai/v1; central authentication refuses them everywhere else. Their secret is stored with a separate hash, so an application on an older @k2b/cloud rejects such a key instead of treating it as a full personal key.
  • Local files in cld (#971). The Assistant can now list, read, upload and create files in the folder cld starts in without asking. Appending, replacing, moving, Bash, protected files (.env, keys, .git, any case) and other folders ask first, with Enter meaning No; AGENTS.md and .agents files always ask before they are written. Project AGENTS.md and Skills load only after a one-time trust question per Git root. Everything runs as the person's OS user with their file access.
  • MCP SDK (#988). @modelcontextprotocol/sdk goes from 1.30.1 to 1.32.1 for an advisory in its OAuth client. Cloud uses only the SDK's server transport, so the affected path was not reachable at runtime.

Behavior changes

  • Approvals in Cloud (#963). Every app lists and decides its own pending approvals through GET /api/approvals, GET /api/approvals/counts and POST /api/approvals/:id/decision, which use the per-person API rate limit. My account → Approvals lists requests from every app, Assistant shows an Approvals row above Studio while something waits, a Mail draft shows the requests that would send it, and app icons in the rail and app grid show their open approvals. The new Pending approvals notification tells a person about requests from outside Cloud's pages (cld, an API key, an editor) at most once every 15 minutes; browser delivery is recommended. Approval receipts in the chat now show the decision time (#959).
  • Cloud Login approves Actions (#973). The app lists waiting Actions per Cloud with a review sheet, and a decision continues the waiting chat like the web card. Core wakes phones with a push only for requests asked outside Cloud's pages, bundled per request and on their own budget, so sign-in wake-ups are never starved. A phone that still has a PIN asks for it one last time and then opens without it; connected Clouds stay paired. If someone forgot the PIN, Reset Cloud Login works as before, and they revoke the old device in Cloud and pair again. Rolling the Cloud Login image back keeps working with vaults that no longer have a PIN.
  • OpenAI-compatible endpoint (#969). With ai.openai_api_enabled on, people create a key with AI models only access (or cld account api-keys create <name> --access models) and use their allowed Assistant chat models from external clients through GET /api/ai/openai/v1/models and POST /api/ai/openai/v1/chat/completions, streaming or not. Text only, no Cloud tools, chats or memory. Requests use the person's model grants and chat allowance and appear as task openai-api in usage. Models without reference prices have no usage limit there, as in Assistant; only the per-IP rate limit and the per-person concurrency limit apply, so review model prices before you turn it on.
  • Assistant results from code runs (#949, #965, #972, #986). Code runs put charts, tables, key figures, single records, linked Cloud objects and explorers (one dataset with several views, a series filter and a comparison) straight into the chat as validated files under /views, without the model retyping values. View files are ordinary chat files and count toward the per-chat file budget. Charts can be grouped (2 to 6) and gain boxplot, heatmap, bar gauge and stat. Studio apps, scripts and PDFs draw cloud.chart() through the same mapping, without the chat's size limits; visible changes are a default width of 480 instead of 640, date axes in the viewer's wall-clock time, and renderer errors thrown as invalid. Stdlib-only options outside the chart contract, such as padding, are ignored, and x strings must be ISO dates.
  • Assistant reliability (#968, #993). A malformed tool call no longer ends a turn silently: Cloud records it with an error and lets the model repair it, at most twice per turn. Manual /compact and automatic compaction fail within the 60-second first-byte or idle timeout when the provider stalls, with model_unavailable; a failed /compact keeps the context, and a failed automatic compaction is skipped. Mistral tool-call IDs are mapped per request.
  • Agent Skills (#987). One SKILL.md folder works locally and in Cloud. Extra frontmatter is kept, disable-model-invocation: true hides a Skill from model discovery while people can still start it with /, ZIP import skips scripts and lists them instead of failing, and reference links are stored as written (existing absolute links keep working).
  • Detail panel and page titles (#1003, #1032). From 768 px the detail panel takes a full-height column at the workspace's end; tables and boards end one gap before it, and closing slides the panel out before the room is given back. From 1024 px, the title row and back link disappear when the visible sidebar already marks the current page; the heading stays for assistive technology. On touch tablets, the selected week or day calendar event stays beside the detail drawer.
  • Row actions on hover (#989, #974). On a tablet with a mouse or trackpad, row actions in sidebars, detail panels, discussions, tabs and app lists now appear only on the hovered row instead of on every row; touch-only screens keep them visible, and nothing moves when they appear. Sidebar rows end with the same inset on the right as on the left, also with overlay scrollbars.
  • Notebooks writing and reading (#1001, #1010, #1019, #1030, #985, #975, #1039). Write, read-only, source mode and Book share one centered column of at most 44rem and one typography (16px/1.6), and dark mode no longer paints headings and emphasis purple. Lists indent by their Markdown structure with guides, number 1./a./i. like Book, repair their numbers after edits, indent with Ctrl/Cmd+] and [ or the new toolbar buttons, move with their sub-items (Alt+Up/Down), and handle Enter, Backspace and the list shortcuts like Google Docs, also on German and Swiss layouts. The Markdown source stays untouched except for repaired numbers. Mouse selection starts on links and pills, collaborator cursors sit where the local caret would and their name fades after 3 idle seconds. A note's text appears in the first paint instead of after the editor loads.
  • Mail CSS never blocks sending (#966, #1005, #1027). A mailbox whose saved design contains a value the stricter check rejects keeps previewing, sending and scheduling; Mail leaves out only those declarations and reports ignored_mailbox_css warnings in the preview, in Settings → Writing and on stderr of cld mail compose style get. The "email design is no longer valid" error is gone. Saving a design stays strict, so managers fix designs at leisure in Settings → Writing → Edit design. A long message whose mailbox design would make it too complex is sent with the built-in design and one warning. The automatic-reply preview now lists the same warnings as the composer.
  • Mail signatures, quotes and code (#967, #1022, #951). The signature is no longer part of the editable body: the composer offers Signature below the text, following the sender's default, and Mail places it after the text and before quoted history. Draft copies in the provider's Drafts folder hold only the body. Sent Markdown mail and notification emails keep quotes and code blocks; mailbox CSS can style both. Signatures and snippets name their Liquid variables, and an unknown variable lists the available ones.
  • Mail bulk sender moves and move sets (#1035, #984, #999). People with mailbox-wide write access can move all mail of one sender or domain (cld mail sender move, up to 500 moves per call). Bulk moves skip Sent, Drafts, Trash and Junk, never move kept conversations to Trash, Junk or Drafts, and on Gmail move each message once from the Inbox copy. Sender matching now uses the first From address everywhere, also in incoming automations, and domain matching uses the part after the last @. New mail now arrives on time while a bulk move drains or message bodies download: a move set no longer holds the mailbox for 40 to 50 seconds, and a body batch yields after the current body to a waiting folder sync.
  • Mail automations and sender verification (#950, #956, #962). Incoming automations run once per message and never on an All Mail copy, so messages no longer stay in the inbox with MAIL_WORKFLOW_PRECONDITION_MISSING. Sender verification no longer fails with 409 PROVIDER_BUSY on a busy mailbox: it waits as a command for up to 10 minutes and the identity shows Verification waiting. API clients that verify an identity or set up the default sender must check pendingVerificationCommandId, because a 200 response no longer always means verified. mail operator status lists failed, cancelled and stale-fence sync runs of the last 24 hours with their reasons; scripts that read sync.states.failed as the total of all retained runs now get the 24-hour count.
  • Spaces calendar (#1025, #1008). The day and week views run from 06:00 to 06:00, fold empty nights, and scroll between days instead of paging; the week view is a horizontal strip (seven days wide, three on a phone). Deadlines are dashed lines with a checkbox, free time creates entries, and tasks can be dragged in from below the day. The month view's count covers only the shown month.
  • Spaces Kanban and keyboard (#1024, #1011, #1040). A Kanban card moves with the keyboard from its grip (Space or Enter to pick up, arrows to choose, Escape to cancel), with announcements for screen readers. On touch screens the grip and the "I'm on it" button are visible with 44 px targets, and a long press on the grip drags. With an item open in the detail panel, J and K open the next and previous visible item in List, Table and Kanban; Back closes the panel instead of replaying every step.
  • Smaller changes: in Spaces, a task counts as overdue from the day after its deadline in the List and My tasks (#954), List groups count and order across all matching items (#964), the Table shows a done status in its column's color (#1002), and Kanban and List labels follow the language, with the list view called "List" everywhere (#958). One Escape closes a dialog whose first field is a Combobox, which now opens its results on click, typing or arrow keys instead of on focus (#970). The conversation composer's placeholder stays on one line on phones (#995). Every page and the mailbox load without Zod on first paint again, about 30 KB brotli less per page (#1009).
  • Chat (#1004, #1017, #1029) is not enabled; it stays behind its unreleased Compose profile.

CLI changes

Install the cld binary of this release and run cld plugins update --all.

  • cld assistant acp (shortcut cld acp) runs the Cloud Assistant as an Agent Client Protocol agent over stdio for editors such as T3 Code and Zed, with the person's Cloud login, models, Projects, Skills and tools (#980). Chats stay in Cloud. Actions that ask every time can only be rejected from the editor; the person confirms them in Cloud or Cloud Login. No configuration or infrastructure change is needed.
  • Local files and folders (#971). cld assistant works with the folder it starts in: list, read, upload, download, write and move files, with the questions described under "Security". AGENTS.md and project Skills load after a trust question; /skills lists local and Cloud Skills. Administrators can replace the shipped instructions for local clients with ai.local_client_instructions.
  • Skill sync (#987). cld assistant skills list|push|pull syncs a local .agents/skills folder with Cloud; replacing a differing Skill or overwriting a local one needs --force.
  • Mail (#1035, #956, #962). New cld mail sender move; cld mail command list gains --state, --before paging and an ERROR column. cld mail identity verify and identity setup-default print the pending command and wait with --wait (default 660 seconds). mail operator status shows recent failed sync runs with their reasons.
  • Help and output (#951, #949, #972, #969). Command help marks required flags with Required.; cld assistant prints chat views as tables and references as type:id; cld account api-keys create --access models creates a models-only key, and cld recognizes such a key.

New settings

  • ai.openai_api_enabled (OpenAI-compatible API, AI settings): off by default. Every request checks it, so turning it off stops new requests with existing keys at once; provider calls already running continue (#969).
  • ai.openai_api_max_concurrent_requests: default 4 simultaneous requests per person across all instances, integer 1 to 64. The limit relies on Valkey and is best effort (#969).
  • ai.local_client_instructions (Administration → AI → Instructions for local clients): empty by default, which uses the shipped instructions; custom text replaces them completely (#971).
  • Pending approvals is a new user notification registered by Core (#963).

No new environment variables, no new images and no Compose change. The JetStream reservation does not change for a normal deployment.

Notes for app authors

@k2b/cloud 0.32.0 (depends on @k2b/ui 0.23.0 and @k2b/nessi 0.17.1; @k2b/ssr 0.15.0, @k2b/sync 7.0.0 and @k2b/stdlib 0.28.0 are unchanged)

  • Slow requests (#969): setRequestTimeout(c, seconds) from @k2b/cloud/server raises the idle timeout of one request to 1 to 240 seconds and throws outside that range; REQUEST_IDLE_TIMEOUT_SECONDS and REQUEST_IDLE_TIMEOUT_MAX_SECONDS are exported with it. defineApp passes the Bun server through so the call reaches the socket. Before, Bun closed any request after 10 idle seconds.
  • Approvals (#963): show and decide approvals only through the shared Approvals component from the new @k2b/cloud/approvals/ui and the shared routes; loadPendingApprovals from @k2b/cloud/server renders the first page during SSR.
  • Live updates (#1029): the new @k2b/cloud/events/testing export runs the real live engine in tests (LIVE_LIMITS, memory topic, startLiveOutbox), and getEffectivePermissions() accepts a Bun SQLQuery subquery for large grant sets.
  • First load (#1009): import schema-free values from their named module and parse on demand; isCommandPath from @k2b/cloud/contracts (also @k2b/cloud/contracts/command-path) checks a command path without a validator.
  • Email HTML (#1022): the email sanitizer keeps blockquote and pre with inline styles for mail.send, mail.enqueue and notifications, and the plain Markdown output (links: "plain") renders code blocks, including Mermaid fences, as a bare pre.
  • Chat views and charts (#949, #965, #972, #986): new view exports in @k2b/cloud/ai (cloud.view.chart, table, group, stats, details, explorer); cloud.chart() in apps parses with cloudAiAppChartSchema, without the chat's size limits.
  • Agent Skills (#987): app Skills keep extra frontmatter and relative reference links as written; links are mounted under /skills/<name>/ only when a Skill loads.
  • CLI help (#951): flags declared with required: true and no default show Required. in help.
  • Mail API (#967): drafts and draft seeds no longer return initialSignatureSource; use signatureTemplateId (an ID, or null for none). Compose suggestions return snippets only, and render-snippet refuses signature templates, so integrations that inserted a signature into the body that way must set signatureTemplateId instead.

@k2b/ui 0.23.0 (no export is removed)

  • Workspace (#1003, #1040, #1032): AppWorkspace.Detail is a full-height column from 768 px. The head drops its title row from 1024 px when the sidebar marks the current page, so mark pages deeper than the sidebar with SidebarItem active="ancestor" to keep their back link. AppWorkspace takes flat for overview workspaces that are the page itself. Scrollers marked k2b-detail-trail get the tablet drawer's width as end space. onStep may return the Main element that shows the new selection.
  • Row actions (#989, #1010): use k2b-progressive-row and k2b-progressive-action instead of own media queries; reveals hide only under (any-hover: hover). Buttons and button links with aria-disabled="true" get the shared disabled look.
  • Calendar (#1025): the new dayHours option gives day and week views the 06:00 day start, folded nights and scrolling.
  • Charts and data (#949, #965, #972, #986): ChartExplorer switches between several charts of the same rows and takes legend, headingLevel, an empty slot and a table row cap; ChartFilterControls gains seriesLabel and a compare pin; DataTable sorts on the client through onSortChange; a five-cell StatGrid leaves no empty slot and StatCell can wrap.
  • Inputs and status (#970, #963, #995): Combobox no longer opens its results on focus alone. AppWorkspace.SidebarItemStatus gains a waiting count with its own accessible phrase. A conversation composer placeholder longer than the field ends with an ellipsis.

Known issues

  • Spaces calendar: the month view's right-hand days sit under the tablet detail drawer (#1026); a week or day calendar in a Main narrower than 40rem is clipped on desktop with the detail panel open (#1031); entries that end at midnight or are due late in the day can spill onto the next day (#1007).
  • Mail: when two incoming automations change the same message, the later flag change or move can fail instead of skipping (#1036).
  • Notebooks: restoring an older version as a new note fails (#994).
  • Email rendering: notification batch emails still show code language labels and the Mermaid loading text (#1020), and Markdown math turns into garbled text in email (#1021).
  • Assistant: one-off chat apps still send source text inside files arrays of code_check and code_present, which some OpenAI-compatible backends cut to the first line (#931).

Also in this release

These commits are in the tag but missing from the changelog above, because release-please hides their types. None changes runtime behavior:

  • #957 test: every worktree gets its own integration database ending in _test.
  • #955, #1018, #1037 test: steadier Notebooks Mermaid, page-trail and Kanban drop-order browser tests.
  • #997 docs: the frontend docs, the @k2b/ssr README and the ssr skill say that islands re-render in the browser instead of hydrating.

#1006 appears under Bug Fixes but changes no runtime behavior either: the page-weight baseline script (scripts/perf-baseline.ts) accepts the project's mirrored, digest-pinned Bun image again, and a test now checks it against the repository's own Dockerfile.