What's New

Release notes for K2. Updates are published to GitHub.

v0.46.2

Latest
October 19, 2026

0.46.2 — The tunnel stays up

K2 Connect

-A failed certificate renewal no longer takes your server offline. When your tunnel certificate is still valid but due for renewal, K2 now starts the tunnel with it straight away and renews in the background, retrying in 1 minute, 2, 5, 15, 30 and then every hour until it works. Only an expired or missing certificate keeps the tunnel down. If starting the tunnel fails at boot for any reason (the certificate service, the network or the relay), K2 now retries after 15 seconds, 30 seconds, 1 minute, 2 minutes and then every 5 minutes. It stops when the tunnel comes up or you disable it. Before, a renewal that failed at boot left .k2.dev unreachable until you turned the tunnel back on by hand. K2 also gives the certificate service up to 4 minutes per request, up from 1, and tells it how long it will wait, so the service's new DNS checks and retry have time to finish.

Projects

-Agents read and post only in their own projects' chats. An agent can now read a project's chat (k2 project read) or post in it (k2 project msg) only when its workspace is a member of that project; any other project's chat answers not_a_member. An agent also always posts as its own workspace. You, your Connect logins and the desktop app see and post in every project's chat as before, and App guests still can't.
-Load older project chat messages. GET /cli/project-group/messages takes before_seq and limit (up to 500) to page back through a project's chat, so the phone can scroll back instead of showing only what it already has. Servers advertise it as project-chat-paging-v1.

Chat

-Long chats stay quick. The Thread, ticket chat and project chat now keep only the messages near what you're reading on screen (about 30 to 50) and draw older ones as you scroll back. Typing no longer redraws every message, so a chat with hundreds of messages responds as fast as a short one.
-Phone polish on the desktop. The expanded activity detail shows the same icon beside each item as its collapsed counter, the + in the message box lights up while you press it, and Send brightens while pressed.

v0.46.1

October 18, 2026

0.46.1 — Apps leave preview

Apps: the wall

-New --cmd services run in a wall. On a server with the App runtime set up, a new k2 publish run --cmd … becomes an open-path App: a container with a fresh copy of your folder at each start. Keep anything that must last in $K2_APP_DATA (/data). Your --port stays the port inside, it can go out to the internet through its own proxy (every host it reaches is logged), and it reaches K2 through its own door. Run it again to deploy your changes; k2 publish stop|start|rm work as before. k2 app list labels it Open (container) and says how to move it to guarded. Services you already published keep running exactly as they do today. On a Mac, or a server not set up for Apps, --cmd works as before and says why.
-Agents ask before publishing open Apps. An agent's new --cmd service needs "Allow this agent to manage Apps" and "…and publish open Apps" on its workspace; without them it waits for you in k2 app approvals.
-Builds run inside the wall. When an App's manifest declares a build, k2 app build and k2 app deploy --folder run it in a container, never on the server itself: only the command you declared, a lockfile is required next to a package.json, only the package registries are reachable, and on guarded Apps a dependency's install scripts never run.
-Memory is yours to decide. Apps have no memory limit unless you set one (k2 app config --memory 1G); with a limit, Node's heap gets half of it. An App that runs out of memory stops whole and restarts, it never swaps, and each deployment's log is capped at 50 MB (k2 app logs).
-Agents can't starve the server. On a prepared server, agent sessions get their own memory budget (75% of the server by default), so a runaway one slows down instead of crowding out K2, Postgres and mail. k2 app doctor shows it.
-Box services answer at once. A box service that's waiting for you or was revoked now refuses straight away instead of hanging, and revoking one cuts the connections it had open.
-Podman from K2's own mirror. k2 app box prepare --install-podman downloads K2's Podman bundle from K2's mirror (mirror.alakazamlabs.com, with a second way in) and installs it only when it matches the pinned checksum and carries K2's signature; the source code of its GPL parts sits beside it. Offline, --podman-from takes the tarball and its .minisig.
-After updating, reinstall the App engine (k2 app engine install): this release speaks a new engine protocol, and k2 app doctor says so until you do.
-Apps know their public address. Every App now gets K2_APP_ORIGIN (its main public https address: a custom domain bound to it, else https://..k2.dev) and K2_APP_ORIGINS (all of them), so it can check where requests and websockets come from. Bind a custom domain to an App with k2 domain name add app.example.com --role app:; the App sees changes on its next deploy or restart. An App with no public address gets neither.
-Quieter App logs. On some Linux boxes a guarded App's log filled with pasta "ERROR on epoll_ctl(): No such file or directory" lines. They're harmless, so K2 now shows the first and folds the rest into one line. Other errors are always shown.

Apps: the door

-Stop an App in one step. k2 app suspend ends every pass the App holds at once, so its very next call to K2 is refused, stops it and freezes its deploys and starts. Anyone who can see the App may do it, its agent included; only you bring it back, with k2 app resume from a terminal outside K2.
-See every call an App makes. Each call an App makes through its door is recorded: who, what, which room, the answer, the bytes and how long it took. k2 app audit shows them (--since 1h, --denied, --verb), and --verify checks that no line was changed or removed. The record lives in its own file, ~/.k2/apps/app-audit.db; after 30 days it is kept as daily totals for a year.
-Limits per App. Each App may make 50 calls a second (bursts of 200), hold 64 connections and 256 live subscriptions, and send bodies up to 8 MB (100 MB for uploads). Over a limit it gets a clear answer with the limit and when to retry. k2 app quota shows them; lowering one applies at once, raising one is yours (an agent's raise waits for you).
-Its agent hears about trouble. An App's agent is told when the App is refused more than 20 times in 5 minutes, uses a write action for the first time, shows a pass at the wrong door, or hits a limit.
-New permissions wait for you. An App's first install, and any later deploy that asks for permissions you haven't approved, wait in k2 app approvals while the running version keeps serving, even when you deploy it yourself. The App's pass carries only what you approved. Apps already behind the wall keep what they have.
-Agents without "Allow this agent to manage Apps" ask instead. Their install, deploy, stop and other changes now become one request you approve or deny, and run as asked when you approve.
-Approvals in Settings. Settings → App Approvals lists what is waiting, in plain words, with Approve (Touch ID or your password) and Deny with a note. On a server where you can't confirm in person yet (no vault password and no owner login), it says so, and k2 app doctor does too.
-Apps hosted elsewhere. k2 app token rotate gives an App that runs on another machine its own pass for K2: it expires (30 days by default), carries only the App's approved permissions, works on K2's main address and tunnel but never at an App's door, and is ended by suspend. k2 app remote-pass lists and ends them.

Apps: the server SDK, guest rooms, members and folders

-A server SDK for App code. sdk/server (@k2/server, TypeScript, Node 22.18 or newer, no dependencies) is how an App's server talks to K2. fromEnv() reads K2_GATEWAY_URL, the App pass file (K2_PASS_FILE, /run/k2/pass in a wall) and K2_APP_ID/K2_APP_NAME. k2.login({username, password}) logs a guest in through your App; after that every call acts as the guest of the request you're serving (k2.withGuest(pass, …) or k2.middleware()), and a call with no guest fails guest_required instead of quietly acting as the App. Acting as the App is always written out: k2.asApp(). It covers the Thread (with a live socket), files (including resumable uploads), k2 db (db.query, db.rows and row writes, with the guest's identity for your RLS), tickets, the wiki, heartbeats, activity and the agent's name and picture, plus your App's users and rooms through the App key. Answers are typed, and fields K2 doesn't promise (host paths, session ids) are dropped. K2 rotates the App pass every hour; the SDK reads the file again each call and retries once when K2 says the pass is stale.
-One list of what Apps can call. Every route an App can reach is now a row in K2's verb catalog, and the list both App doors use (the browser helper and each App's gateway) is generated from it, so a route can't be open to Apps without being written down. The rows never use field names K2 keeps from Apps (a file's path is relPath). k2 study app-api lists every one with its method, route and permission.
-Who am I. GET /cli/skin/me tells a guest or an App its kind, its rooms with the permissions it has in each, and which features this server has (k2.me.get() in the SDK).
-Row previews for guests. GET /cli/thread/latest now answers App guests and Apps for their own rooms: the last message per room in one call, up to 50 rooms. A room the pass doesn't hold answers the same skin_room as one that doesn't exist.
-Apps set their own guests' rooms, no owner token. Give an App the right once with k2 app grant --kind guests-rooms [--room ]…, and its server can read and reset its own guests' rooms with its own pass (k2.asApp().guests.setRooms({username, rooms}), or GET|POST /cli/skin/guests/rooms). It reaches only its own guests, only the rooms you listed plus its own, and never more than a guest's role allows. Setting the same rooms again changes nothing, every change is recorded with before and after (k2 app history ), and an App may make 60 of these calls a minute. Agents do the same within your grant with k2 app guest rooms [set …]. A Garden widget can too (k2.guests.setRooms, for any App on this computer), and K2 asks you on its own sheet before every change.
-The must-not-break contract. Dannon's and NSI's routes (login with its token answer, login by email, the 423 lock, the Thread and its live socket, files with a guest pass, db/query, db/rows) are pinned as contract tests that run through the SDK against a real daemon, outside the wall and from inside it.
-Who has access to a room. An App can now show who holds access to a room: its guests and agent logins, with their role and what they may do there. The list comes from the access you granted, not from who happens to be online, and everyone who logs in to K2 itself is one line, "admins of this box". It's a new permission, room:members, off by default; grant it per room like any other (k2 app role room --caps thread:read,room:members). An App sees only its own guests. In any room you can hide guests' names from Apps with k2 app room-names hide; you still see every name, and so do your Gardens. Agents read the list with k2 app members, and an App hears room_members_changed on the room's live socket when it changes.
-An App can check on itself. app.self tells an App its id, the version that is live, whether it is running, and when it went live; app.usage gives its limits, its live connections and how many calls it made to each K2 action (from its own call record). Each App sees only its own; asking about another App gets the same answer as asking about one that doesn't exist. You and its agent read the same with k2 app self and k2 app usage , and the App hears app_deployed when a new version goes live.
-Gardens get both. A Garden widget can call k2.room.members(…) (with every name, since a Garden acts as you), k2.app.self(…) and k2.app.usage(…) for any App on this computer, and k2.widget.self() for its own id, live version, who made it and its last seven days of saves. k2 study app-surfaces has the details.
-Give an App login only some folders of a room. k2 app role paths --read jobs/J1/,jobs/J3/ --write jobs/J1/photos/ limits that role's logins to those folders in that room. It works on any room the role holds, not only a login's own room, and agent logins (k2 app user agent) get exactly the same walls as people. Anything else in the room is refused with the same answer as a missing permission, whether or not it exists. A listing shows only the way down to the granted folders, a link inside a granted folder can't reach outside it, live file updates carry only those folders, and k2.me.get() lists them. --clear gives the whole room back. --upload-dir sets where an upload lands when it names no folder.
-File details in one call. files.stat (GET /cli/fs/stat) returns a file's or folder's kind, size, modified time, extension and content type, under the same folder rules, so an App doesn't have to list the parent folder to show a download's size.

Sew chat and calls

-K2 sign-in for Sew chat. Hearth and Meet sign people in with K2: a login with a chat grant (k2 app grant --kind chat) gets a short-lived chat pass, on each App's own link, several Apps per box. Removing a grant or a login ends its Sew sessions, and Connect logins can sign in to Sew too.
-Sew 0.2.1. K2 pins Sew 0.2.1 with its voice engine, transcriber and recorder, installs their licence notices beside them, and k2 hostchat upgrade and rollback move the voice engine with the core; a refused upgrade now says why.
-Calls on port 443. k2 front enable puts a small router on the box's port 443 so people on networks that only allow 443 can join calls (Sew 0.2.1's TURN passthrough behind the :443 front), with Caddy behind it and hosted mail optional (--mail).
-k2 front enable restarts the K2 daemon once to take port 443 (systemd hands it the socket); if port 443 is already in use, it names what's holding it.
-Meet gets its address. k2 hostchat meet bind points meet..k2.dev at your Meet App; unbind takes it back.
-Sew reminds you to set its public URL. k2 hostchat status (and enable) warn until Sew's public URL is set, and show the command that sets it, so password setup links and invites open from outside the box.
-Chat hints point at real commands. Switching sign-in type points at k2 hostchat purge, rollback and restore hints point at k2 hostchat backups and k2 hostchat restore, and the PostgreSQL hint no longer names a setup flag that doesn't exist.
-Voice options are refused where they don't apply, instead of ignored. --voice, --voice-url and --node-ip only apply to k2 hostchat enable, and --media-tarball to enable, upgrade and rollback; elsewhere K2 now stops and points you at k2 hostchat media install --tarball.

Mail and calendars

-Microsoft mail and calendars. A linked Microsoft inbox reads and drafts mail over Microsoft Graph, and k2 calendar works on its calendars (list, events, create, update, delete, free/busy); Settings adds a calendar to a link that was consented for mail only (k2 mail link calendars).
-Google calendars. k2 calendar works on a linked Google account too, including a calendar-only link. Writes never send invitations.
-k2 hostmail status shows the certificate mail apps really get. It now checks ports 443, 465 and 993 with the mail hostname and reports the worst one, so a self-signed fallback on 465 or 993 no longer reads as issued. A certificate for the wrong name or an expired one says so. The ACME task state is read fresh, and a task older than the certificate now served reads unknown instead of a stale Pending.
-A passing k2 hostmail doctor unlocks direct sending for that domain. It runs every server check too, so you no longer need a separate bare k2 hostmail doctor first. When direct is still locked, the message names the exact command to run.
-Agent refusals name the workspace. When an agent can't manage hosted mail, the refusal says which workspace's "Allow agents to manage hosted mail on this host" switch K2 checked, so you can turn it on for the right one. The help now lists what agents may do with it on.
-k2 hostmail domain show stops recommending records that can't work yet. On a domain whose DNS isn't on K2's nameservers, the MTA-STS and mail-client autoconfig records now say "skip for now" and are left out of the zone file, because those names can't get a certificate there yet. The DMARC record it lists always includes rua=mailto:postmaster@.
-Hosted mail fixes its own certificate in more cases. K2 now asks for a new mail certificate when the live one has expired or doesn't match the mail server's name, not only when it's self-signed. It checks every hour and waits longer between tries if it keeps failing. Certificate status now comes from what ports 443, 465 and 993 actually serve.
-Hints and agent instructions now say k2 hostmail create (the old k2 mail create moved).

Phones: previews, unread counts and Homes

-Message previews in push. A Thread push can show the start of the agent's message, per device and behind an owner switch; titles use the workspace's display name, and no push carries a person's name.
-Message previews switch. Owners and admins can turn message text in phone notifications on or off in Settings → Notifications. With it on, the text passes through K2's push relay and Apple or Google.
-Unread counts from the server. Threads and project chats keep one read cursor per person, so the desktop and the phone agree on what is unread and what is waiting on you; k2 thread unread shows yours, and a Thread or project chat can be muted.
-Reading a Thread in a Home room from another server, or in a Garden conversation whose agent lives on another server, marks it read on that server too.
-Chats open from the phone's cache. A Thread or project chat read can ask for only what's new since the last message the phone has (after_seq), oldest first, along with any card answered, voided or expired since then, so K2 Companion shows a chat at once and catches up behind it (feature thread-delta-v1).
-Homes sync. Your Homes sync with your own server, local-first, with a sync badge on Home and Settings → Homes Sync.

Secrets between agents

-Agents hand each other secrets by name. k2 vault send NAME --to (or k2 msg … --secret NAME) sends a secret to another agent, on this server or another one, sealed vault to vault; the receiver accepts or declines (k2 vault incoming, accept, accept-from), and asks, replies and unsend work too. The value is never in a Thread or a file. Settings → Logs → Access Audit has a "Vault handoffs" filter.
-You hear when an agent moves secrets off the box. When an agent with "Allow managing server-wide secrets" runs k2 vault carry export, you get a ticket naming the agent, the secrets (names only, never values) and where they went. Settings → Logs → Access Audit highlights the export.

Gardens

-The Kanban talks like the Thread. The Kanban's Thread panel now looks like K2's Thread, in K2 Companion's colours (light or dark, as your Garden is): rounded bubbles, yours on the right and the agent's on the left, "author · time" under each, markdown, a round Send (Enter sends, Shift+Enter is a new line), and a working tab with the agent's counters and clock. Kanban Gardens that sync with K2's default get it; one you keep as your own copy stays as it was. To keep your Garden theme's colours, set look = "garden" under the board's [widget.props.config].
-Data-source cards that do more. The k2:*@2 cards take several sources, soft warn and crit levels and named lists; sources gain age, version and field-compare rules with per-rule thresholds, and k2 sources secret a b c NAME sets one secret for several sources at once.
-A widget dev loop. Keep a widget outside ~/.k2 and check, preview and write it whole (k2 zen validate --dir, k2 zen widget preview --dir, k2 zen widget put --dir); a plain validate no longer signs and "pending" exits 0.
-More for custom widgets. A widget that reads sources keeps the thread:post and store:write it asks for, reads a neighbour's data with manifest reads and {from}, and a page holds 10 custom widgets with [[widget]] weight. The widget SDK has typed errors, subscriptions that re-subscribe on their own, shape guards and uPlot charts.
-Unread in Gardens. Garden 1's pins show unread counts, conversations read their Thread while you look at them and show cards waiting on you, and Gardens that sync with K2's default get a bell to mute an agent's Thread.
-Garden widgets can't post without permission. A Garden widget can send to an agent or answer a card only if its approved permissions include sending; K2's server now checks this as well as the app.

Messaging

-People who log in can always message any agent. The owner, Admins and Members can message every agent from its Thread or the terminal composer, whatever its remote switch says. The switch is now Let agents on other servers message this agent (and, for all agents at once, Let agents on other servers message every agent in Settings → K2 Connect): off means connected servers don't see the agent and their agents can't message it.
-Fixed: an agent was shown to other servers whenever 'Allow agents to create connections' was on. Now only 'Let agents on other servers message this agent' (or the master in Settings → K2 Connect) makes it visible. If a connected server's link to one of your agents stops working after updating, turn that switch on.
-A message sent while the agent works joins its turn. It no longer ends the running turn and starts a new one; the activity strip keeps one turn and counts your messages in it.
-File paths in a Thread are links when they point inside the workspace. Click one (or press Enter) to open the file at its line, or to show a folder in Files. Paths outside the workspace stay plain text. Option-click (Alt-click on Windows and Linux) opens the file in the background so you stay where you are; hover a link or a file chip to see where it goes. Links also work in Threads from a K2 server that hasn't updated yet.
-Agents can pick their own picture and color. From its own session an agent runs k2 agent identity --color '#22c55e' --image me.png (or --clear-image), and every client updates at once. It can change only its own look, never its name or handle (it's told to ask you), and at most 20 changes every ten minutes. k2 agent identity with no flags shows the current look; from your terminal it still sets any agent's name, color and picture. k2 workspace set-agent-identity keeps working and points to the new command.
-One picker to add a connection. In a workspace's Settings → Connections, one + now lists every agent you can connect to: this server first, then each paired server A to Z. Search by name, handle or server (rpm cort finds Cortana on rpm), and use ↑/↓ and Enter. Agents you already connect to show checked, and the picker stays open so you can add several. A server that doesn't answer within 5 seconds shows Offline with Retry, instead of a long wait followed by a message blaming its settings; a server paired with the older code shows Re-pair. k2 fed peers and Settings → Connected Servers list paired servers in the same A-to-Z order.
-Agents can attach files to a Thread message. k2 thread "The report is ready" --file docs/report.pdf --file src/session.rs:212 puts a file chip under the message (up to 10; three or more become a list); click one to open the file at its line. A chip points at the workspace's own file, it isn't a copy: it gets an amber dot when the file has changed since it was sent, and offers Find in Files when the file has moved. Only files inside the agent's workspace can be attached, and anything that looks like a secret (.env, keys, tokens, credentials in the text) is refused. App guests see a file only when their own file access already covers it; otherwise they see "A file (not shared with you)". Push notifications say [file], never the file's name. The server is ready for K2 Companion to preview and download them on the phone.
-One list of secret files. Clone, retiring an agent and Thread attachments now share one list of what counts as a secret file. A clone now also leaves out key files (*.pem, *.key, *.p12, ssh keys), .ssh/, .npmrc, .netrc and similar unless you choose to carry secrets, and retiring an agent warns about them.

Compute

-Runs from a worktree use the worktree. k2 compute run inside .claude/worktrees/x finds its workspace (even with no K2 session), runs that worktree's own commit, and --dirty sends that worktree's changes. Each run prints which code it sent, and the "uncommitted changes" note no longer appears with --sha.
-Wait without the logs. k2 compute wait … blocks until jobs end and exits with the job's exit code. --max-wait 9m stops waiting first. k2 compute run … --wait prints the job id, then waits, and sends no second [compute] message.
-Cancel never hits the wrong job. A cancel can no longer race a job starting. Cancelling a job that already started now needs --force, and k2 compute get shows who cancelled.
-See what's ahead. A queued job shows its position, the jobs ahead of it and their age, and the CPU and memory numbers when it's waiting for resources. k2 compute nodes shows free CPU, free memory and your grant.
-k2 compute status. Every node at a glance: state, foreign-lock waits, running and queued jobs, free CPU and memory, load, and disk against its floor, plus this Mac's free disk and Time Machine snapshot count.
-Limits up front. A --timeout over the grant is refused before anything is sent, with the grant and the command to raise it. A job too big for its node is refused at submit; one already queued is failed with the reason and you get its message. A job killed for memory gets a hint.
-Let an agent look after your compute machines. A new Agent switch, "Allow managing compute nodes" (Settings → Workspaces → → Agent, or k2 compute manage on --workspace ), lets that agent add and confirm machines, rename, pause, drain, resume, retire and route them, and grant or revoke them for any workspace, without asking you. Every act is in Access Audit, and adding or confirming a machine sends you an inbox note. Turning compute on or off, removing a machine and the switch itself stay yours. It's off by default, only you (the owner) can turn it on, and it only works for agents on this computer.

Project settings

-A calmer project settings page. Settings → Projects now shows one project in two halves: General and Dashboards on the left, Agents on the right. Each half scrolls on its own, the dashboard picker stays in view, and on a narrow window the halves stack. The second row of tabs is gone.
-What you can change follows who you are. Admins can change everything again, even with the window on the eye, and members see a short note saying what only the owner or an admin can change. Only the owner, an admin, or an agent with 'Manage K2 projects' can delete a project, since that removes its chat too.
-Adding a file to a dashboard no longer undoes someone else's change. K2 adds or removes that one file itself, so two people editing a dashboard at the same time both keep their changes.
-No more dead ends. If the project list can't load you get the reason and Retry, not an endless "Loading…". "Open project" takes you straight to it, and right-clicking a project (in the list or the narrow rail) offers Project Settings. Labels say "Point of contact" in full.
-k2 project rename, pin and delete. Rename or pin a project from the terminal; k2 project delete --yes deletes one (owner or admin only).

CLI fixes

-k2 msg who only ever looks up a sender. An id that didn't start with m_ used to send a live message to a workspace named "who".
-Clear answers when a command is refused or finds nothing. k2 settings from an agent now says it needs the owner or an admin instead of showing blank settings. k2 inbox read with an unknown id says so. k2 users list from an agent points to k2 connections list --users. k2 compute get with an unknown job exits 4. k2 sources shows one hint, not two.
-k2 activity takes --help and --json, and shows dates. Before, those flags were read as the number of events. Errors from the server now show instead of "No activity.".
-k2 hostmail status on a computer without hosted mail says so in one line. Hosted mail runs on Linux K2 servers; for linked inboxes use k2 mail inboxes.
-Smaller fixes. k2 compute jobs shows the whole reason a job waits. k2 app token list says "No App tokens.". k2 zen widget errors says what it checked, and two errors at the same moment no longer share a number. Help text names the right commands and variables.

Polish

-Clone, smoother. Threads that came with a cloned agent appear under "Imported Threads" in Chat History and open read-only. When an agent proposes a clone, you can review it on its Thread and open the Clone dialog already filled in, and approving takes a single Touch ID or password confirm, even when it copies secrets. The Clone dialog now uses the same controls as the rest of K2 and no longer freezes while it checks what to copy.
-Split view shows status. Tabs in Split view panes show working and waiting marks, like the main tab strip. Zen themes get an "ok" colour for finished work.
-Ticket replies and the project chat now look and work like the Thread in every Style: the same bubbles, markdown and message box (Enter sends). Each shows the working strip of the agent it reaches: the ticket's workspace agent, or the project's point of contact.
-Settings → Projects is quick and steady. Switching projects no longer flashes "Loading…" (a project you've opened before shows at once). Renaming, pinning and changing the point of contact show the change straight away, and put it back with the reason if the server says no. The picture no longer pops in late, and a busy project chat no longer makes the page reload itself.
-Thread on a narrow pane. When the Thread, ticket chat, project chat or a Garden's Thread is narrower than 480px (a phone, say), messages and cards use the full width instead of about three quarters of it. Yours still sit on the right and theirs on the left. The Kanban's Thread panel does the same.
-Messages no longer scroll inside their bubble. A message ending in a file path or a code block used to scroll up and down by a few pixels in the Thread, ticket chat, project chat and Garden Threads. Long code still scrolls sideways.
-Settings → Notifications → People shows one line per person (name, role, and how many workspaces can push them). Open one person to see or change their switches; opening another closes the first.
-The Connections picker closes when you click outside it or press Esc, and Esc puts you back on the +.
-Agents learn to attach files. The k2 guide every agent reads now explains k2 thread … --file, so agents attach the files they mention.
-The "Which account is yours?" prompt uses the same square radio buttons as the rest of K2.
-Completion sound volume and choice. Settings → General → Workspaces sets the completion sound's volume and picks one of five chimes, the same on every client.
-Linux packages update in the app. On Arch, deb and rpm installs, Install & Relaunch checks the package against the release's checksums, installs it with your password and restarts the local daemon.
-Terminals no longer drop a character after an accented letter that lands on a read boundary ("ïcø" could show as "ïø"). K2 now ships a patched copy of the terminal parser.
-On Linux, an agent killed for using too much memory no longer stops and restarts the whole K2 daemon. Only that agent stops, and your other sessions and the tunnel stay up. Existing servers pick this up when they update.

v0.46.0

October 17, 2026

0.46.0 — Runtime for Apps

Getting your Apps ready for 0.46.1 (nothing is taken away yet)

-See what would break. In 0.46.0 only guarded Apps (k2 app deploy … --engine guarded) run behind the wall. Your existing k2 publish run --cmd services keep running as before (legacy, unwalled), with clean mode to opt in early and warnings for what they rely on. In 0.46.1 their inherited environment ends; the wall for them comes when you move them over with k2 app adopt. This release takes nothing away; it adds the new ways and tells you what each service still needs. k2 app warnings (or every server App at once) reads the App's code and lists, with file and line, the environment variables it only gets from K2, any read of K2's own files (like the owner token file), the programs it finds only through your own PATH (like node in ~/.local/bin), and, on Linux, each K2 call it made with the owner token. Each line comes with the fix. Owner-token tracing is Linux only for now; on a Mac, warnings and clean mode say so instead of staying silent.
-Try 0.46.1 now, one App at a time. k2 app clean-mode on runs that App the 0.46.1 way: a clean environment, the system PATH, its own home folder, and on Linux any owner-token call from it is refused. Turning it on is always allowed (an App's agent can do it); turning it back off is the owner's call.
-An App key instead of the owner token. k2 app key mint --scopes users,rooms,fetch makes a key that works for that one App only: it can manage the App's own users and their Thread rooms (only the rooms you allow), send password-reset links to people who use only this App, and call outside services through K2 with a secret by name, so the App never holds the secret. Minting asks you to confirm in person; K2 puts the key in the vault and the App reads it from $K2_SECRETS_DIR/K2_APP_KEY at its next start. Agents never see a key. Every App now also gets K2_APP_NAME and K2_GATEWAY_URL, and services from before 0.45.4 now get the secrets you grant them.
-More App settings. k2 app config now also sets CPU weight, tasks, disk, outbound hosts, extra ports, recycling, the wall, the path, the risk level, the App's private database and its disk speed. Changes that only take something away apply at once; a wider one waits for you, and a new outbound host, a lower wall or a raw database connection always waits, even when you ask yourself. Moving an App to a weaker engine is never a deploy flag: it goes through k2 app config and your approval.

Owners widen, agents ask

-One list of requests. Everything an agent asks for (an App key, clean mode off, a wider setting, a new outbound host, a new --cmd service) is one request in k2 app approvals. k2 app approve asks for your Touch ID or password from a terminal outside K2; not even your own owner token approves without it, and an agent never can. k2 app deny says no and tells the agent why; an agent can withdraw its own request. Requests left alone expire after 7 days.
-Who may manage Apps. k2 app access --manage on --open on sets "Allow this agent to manage Apps" and the new nested "…and publish open Apps".

Walled Apps (App runtime preview, Linux)

-Their own door to K2. An App deployed with k2 app deploy … --engine guarded calls K2 at http://127.0.0.1:8730 from inside its container, with an App pass in the file K2_PASS_FILE names. The pass works only on that App's own door, never on K2's main port, the tunnel or another App's door, carries only the permissions in the App's manifest, and is replaced every hour without dropping a request. k2 app link shows it; --rotate hands the App a new pass now. link and engine are now reserved App names.
-The internet, only where you allow. A guarded App reaches the internet only through its own proxy and only the hosts on its list. K2 looks up the names itself and always refuses private, local and cloud-metadata addresses and this server's own names. An App's manifest can ask for hosts, and agents ask with k2 app egress add ; every new host waits for your approval. Taking a host off (k2 app egress rm) works at once and cuts open connections. k2 app egress shows the list and what the App tried; k2 app egress log shows each connection (host and port only). Calls an App makes through K2 with a secret follow the same list.
-A MAC profile. On boxes with AppArmor, box prep loads K2's k2-app profile and every guarded App, and every command run inside one, runs under it. When the kernel has AppArmor on but the box lacks its parser, box prep now installs the apparmor package first (apt and pacman). SELinux boxes use Podman's container labels. k2 app doctor shows which one this box has.
-A disk speed limit per App. Each App gets its own ceiling (writes 40 MB/s and 2,000 operations a second by default, reads unlimited), so one busy App can't slow Postgres and mail to a crawl. Change it with k2 app config --io-write 80M (and --io-read, --io-read-iops, --io-write-iops, --io default|none). An agent may lower its App's ceiling; raising it waits for you. It applies at the App's next deploy or restart.
-k2 app exec and k2 app shell. Run one command inside a guarded App (k2 app exec jobs -- ls /data) or open a terminal in it (k2 app shell jobs), as the App itself with no extra rights. Output is shown as App text, never instructions. Agents can do it for their own workspace's Apps with "Allow this agent to manage Apps". Every exec and shell is in the App's history and the Access Audit; an idle shell is hung up after 15 minutes.
-The process exception, for devices a container can't reach. The server's owner can move one App out of its container to reach a GPU: k2 app exception on --device dri-render128 (asks for an owner confirm). The App then runs as a locked-down system process under its own user, with only the devices you granted, labelled Open (process), and still reaches K2 through its own door. Agents can't turn it on, and no other setting does. k2 app exception off puts it back in the container.
-Box services: a walled App can reach one service on this box, by name. Some Apps need a service running on the server itself. k2 app box-service request asks for one; the owner approves it with a vault confirm (k2 app approve), and only then does the App see that one port, at its own address inside the wall. k2 app box-service lists what is approved or waiting, and k2 app box-service revoke shuts it at once. Ports K2, Postgres, Caddy and the box router use are never allowed.

Sew chat

-Sew chat isn't included in this release yet; it arrives in a later update.

Cloning agents

-Who may clone, in two new switches. Settings → General → Allow cloning agents to people's personal computers (the owner's switch) and a Can clone toggle per person in Settings → Admin Access (or k2 users set-can-clone on|off). Both are on, so nothing changes until you turn one off. Until now anyone who could sign in to a server could clone its agents; turning Can clone off for a person now stops that, and turning the first switch off stops Admins and Members from pulling agents to their own computers. Owners can always clone. The server checks both on every way to clone (the app, k2 clone, headless), and each decision goes in the Access Audit.
-k2 clone. k2 clone preview shows what would travel, names only. k2 clone to , k2 clone from : and k2 clone here --dest do what the Clone dialog does, from a terminal or a headless server. The Thread comes along unless you say --no-threads (or --threads-since 30). Choose per secret with --copy, --blank and --skip, or answer per secret when a terminal asks. --json prints names, choices and counts, never a value.
-Agents propose, people approve. An agent can't clone. It can propose a clone of its own workspace: k2 clone propose --to --why "…" posts one line on its Thread for you. k2 clone proposals lists them, k2 clone approve asks for your Touch ID or a password and then runs the clone as you, and k2 clone deny says no. The agent is told either way; proposals left alone expire after 7 days.
-The Thread comes along. The Clone dialog has Bring the Thread, ticked: the agent's main Chat and its sidecars arrive on the clone under an "Imported from sales on rosson.k2.dev" line, with other people's messages shown by name. Imported lines are read-only and Chatter never travels. k2 thread export , k2 thread import --to and k2 thread imports move Threads outside a clone (owners and admins).
-Secrets, one by one. A Secrets step lists the agent's vault secrets by name: Copy, Leave blank or Skip each one (API keys copy, sign-ins skip by default). Copying asks for Touch ID or your password, and the values travel encrypted to the other server's vault, never in the clone itself. Leave blank puts a card on the clone's Thread asking for the secret.
-.env files ask first. "Include secrets" in the Clone dialog is now Send .env files as files. It sends them as plain files inside the clone, so it now asks for Touch ID or your password first (an owner or admin), and offers to move them into the vault instead (k2 vault import .env). Members with Can clone can clone, but can't send .env files or copy secrets. A .env.k2 that holds only k2v:// references now travels with the clone.
-k2 vault carry is stricter. It never carries K2 logins, App passes or engine credentials, and k2 vault carry import now puts secrets into the workspace with the right id instead of any workspace with the same name.
-Every carried secret is on the record. Agents allowed to manage server-wide secrets can still carry them without you, but each carry now writes who did it, which secret names, from which workspaces and to which vault, in the vault audit and in Settings → Access. Values are never written.

Grok Bots

-K2 keeps every Grok Bot message it sees in your Threads, so history builds up even for bots whose live chat runs elsewhere. A bot's chat in K2 starts the day K2 starts collecting, with a line that says so, and grows from there: new messages from the bot and everything you send from K2, the same on every computer you use. When K2 can only see a bot's latest message at each check and it wrote several in a row, K2 marks where earlier ones may be missing; open Grok Bot to read them all. People who can see Grok Bots can also read a bot's chat with k2 thread gb:. Agents and App guests still can't.

Gardens

-Garden 1 looks like K2 Companion. A new built-in Glass theme (black canvas, glassy cards, iMessage blue) is Garden 1's default, nine pinned agents fill three rows of three, and the Agents list starts with the most recent. Garden settings now let you pick this Garden's theme, how many pins the grid holds, and whether it starts recent-first. A Garden whose theme you picked, or your own copy, keeps its theme.
-Agents can run Gardens end to end, if you let them. A new per-agent switch, Manage Gardens and data sources (Settings → Workspaces → the workspace → Agent, off by default), lets the agent approve, pause and pin data sources, bind secrets it can already use, enable triggers, and edit Gardens and widgets (k2 zen garden put, k2 zen widget put), with every act in Access Audit. Without the switch, an agent's Garden or widget change becomes a proposal you approve or reject (k2 zen proposals). K2's built-in widgets are never written.
-One confirm for many sources. k2 sources approve a b c --secret NAME binds one secret to every source in one go, with a single confirm. It binds all or none.
-Custom widgets read their data sources again. A widget bound to sources.* was always refused as "not bound"; it now reads and subscribes to the sources its placement names.
-Rail icons. Garden 1's rail and settings cog use K2's new icons.

Security

-Wiki: public chat is off, the local wiki site is locked down. Public chat let anyone who could reach a served or published wiki start your workspace's agent in your real folder, with no sandbox and with auto-approve on. It is now off on every workspace and comes back once rebuilt on the K2 runtime. On start, K2 turns chat off wherever it was on, undoes the skip-permissions setting that chat added, removes the hidden chat keys, and records each change in k2 users audit. The local wiki site only answers requests addressed to itself or its own published subdomain, sends no CORS headers, and no longer shows your folder path or dot-folder notes. Serve and Public chat are hidden in the app for now; agents can still use k2 wiki serve|publish|unpublish, and k2 wiki chat on stops with exit 3.

Changes tab

-See and ship your git changes without leaving K2. The tab bar's + menu offers Changes when the workspace is a git repo. It lists staged, unstaged, untracked and conflicted files with +/- counts (as a list or a tree), updates live as files change, and lets you stage, unstage, discard and commit (Cmd/Ctrl+Enter), or compare against another branch. Discarding never deletes: anything that would be lost goes to the Trash first. The diff viewer shows changes inline or side by side, with syntax colours, collapsed unchanged lines, View all, and next/previous change (F7 / Shift+F7). Agents get the same with k2 changes (diff, stage, unstage, discard, commit), on their own workspace only.
-Review notes. Select changed lines in the diff and leave a note on them; Send passes all your open notes to the workspace's agent as one message, and the agent marks each one resolved when it's fixed (k2 changes notes). Notes follow their lines as the file changes and say when those lines have changed. Open in editor opens the file, k2 changes open brings up the tab, and a folder that isn't a git repo yet gets Initialize repository (k2 changes init), with the first commit working too. Untracked folders stage in one click.

Design mode

-Point at a page and tell your agent what to change. Each workspace gets a pinned Design tab next to Inbox (more from the + menu). Open a page in it, press Select (or S), click the elements you mean and write a note on each. Send posts your notes to the workspace's Thread, marked "via Design", and hands them to the agent's Chat once. The page's address loses its query string, and the HTML that goes along is cleaned of scripts and anything that looks like a secret. Turn the Design tab off per workspace in Workspace settings → Design mode (or k2 workspace design-mode set off). Agents and scripts can file the same note with k2 browser note.

Status marks

-One status language everywhere. The Agents list, the Active drawer, Home, Grok Bot rows, room tabs, the pinned Chat and Running agents all draw the same marks: a 3x3 grid while an agent works (in the theme's accent), then needs you (orange), failed, done, monitoring or no update, else a live (green) or reaped (grey) square. Orange now only ever means it needs you. Tabs never change width when a mark appears, and hovering a tab shows its close button in the mark's place.
-People are chips. Everyone connected shows as a small square in their own colour, with a corner mark for owner or admin, on the top bar, in agent rows and on ticket assignees.
-Gardens use the same states. Zen keeps its circles, but ranks them like the app, and shows an unseen done or failed as a ring.

Thread

-The Thread beside an agent wears the Garden's look. Bubbles (yours on the right), "author · time" under each, cards inside the bubble, and a round message box with + and Send. The working strip is now the activity drawer on the box's top edge, with Stop, and running subagents spin the same 3x3 grid. The "/" menu, send history, drafts and every key that reaches the agent still work.
-A roomier message box. Past three lines, the text gets its own full-width line with + and Send under it, in the Thread and in Gardens.
-Messages scroll under the box, behind frosted glass that blurs gently at the top and more at the bottom. With reduced transparency it's a plain fade.
-Square corners, cut. In K2's square Style, bubbles, the box, Send, chips and cards get chamfered corners.
-Thread pushes, from the Workspace tab. A phone button next to the completion bell turns your own Thread push notifications for that workspace on or off.

Tabs

-Pin any tab. Right-click a tab and choose Pin Tab. Pinned tabs sit right after Chat and Inbox, keep their place across restarts, and Close Others / Close All leave them open.
-Tabs fit their titles. A tab is as wide as its name (within limits) instead of a fixed width.
-New agents open in the view you choose. Settings → General → Workspaces → New agents open in: Terminal, Chat, Thread, Chatter, or Split view with the two sides you pick. Agents you already set a view for keep theirs.
-Switch pages from the keyboard: ⌃⌘1 My Home, ⌃⌘2 Agents, ⌃⌘3 Projects, ⌃⌘4 Tickets (Ctrl+Alt+1–4 on Windows and Linux). You can change them in Settings → Key Bindings.

Usage

-One Usage page. Settings → Language Models → Usage is headed with the server it shows (Usage on and its name): a strip with each tool's limits, token totals for Today, 7, 30 or 90 days or All (uncached input, cache read and write, output, requests, and an estimated cost that is not your bill), a day chart per tool, and breakdowns by workspace, model, login and tool. Click a row to filter the whole page. Activity lists each request, newest first, with a link to its chat. Days follow your own time zone.
-Truer token counts. Codex now counts every model request, not just the last one in a turn; input is counted uncached for every tool; logins K2 manages and custom tool homes are included; and new lines are read as they arrive.
-Every login's limits, live. Settings → Language Models → Subs / Tokens shows each login's limits as bars (amber at 75%, red at 90%, with a pace mark and a reset countdown), how fresh each reading is, and why a login has no numbers, with a Refresh per login. The top-bar usage chip uses the same bars, says how old its numbers are, and marks a failed check instead of showing stale numbers as current. Limits update live from running Claude and Codex sessions.
-k2 usage. k2 usage tokens, k2 usage turns and k2 usage limits [--refresh] from a terminal. An agent sees its own workspace. Owners and admins see the whole server; members can't.

Publishing

-Slow starters get time to start. k2 publish run --probe-timeout 10m gives a service up to 15 minutes to open its port (the default is still 15 seconds), and restarts and reboots use it too. While it waits, k2 publish ps and status say "starting (waiting for port 3047, 4m12s left)", and a tunnelled service's public address goes live once the port answers. A local service that binds late turns running instead of staying unhealthy. Only when the time runs out is the run rolled back, and it then shows no public address.

Browser

-Menus and dialogs show over the Browser tab. The web page in a Browser tab used to cover every K2 menu, dialog, toast and drag that crossed it. Now, while one is open over the page, the page turns into a still picture of itself, so the menu draws on top and nothing flashes blank; the live page comes back when it closes. Menus elsewhere in the window leave the page live. Dragging tabs and sliding drawers freeze it the same way.
-The page sits exactly on its pane. No more one-pixel seams or overlaps on Retina and scaled Windows screens, the page follows a live resize, and on Linux it holds its place in the window.

A new look

-Settings → Language Models. The LLMs group is now Language Models, with Subs / Tokens, Providers / Models and Usage, in that order. Old links and search still land on the same pages. The Subs / Tokens actions (Use this token, Sign in again, Rename, Remove, Add) are proper buttons.
-Top bar. Page tabs are icons, with a new Wiki tab. The server switcher is a compact chip whose server icon shows the connection light. A profile button next to the Gardens toggle opens your profile, where a Connect login can change its own password. Help (it was the cheat sheet) opens an explorer of every k2 and k2-node command and k2 study page, with search (Cmd/Ctrl+K). When Home shows an agent on another server, the title reads server / agent / branch.
-Profiles and names. Your profile now edits everything in place: any colour (a hex value, or Automatic from a new palette), an optional first and last name, your password, and recent sign-ins under Security. Every person can have a real name; agents see it in their roster ("z3thon — Rosson Long") and k2 users list shows it, but messages are always sent and assigned by username. On the computer K2 runs on, K2 asks once which Admin Access user is you (or helps you create one), replacing the old "This is me" checkbox and "Your name"; your messages to agents then read [from z3thon]. Settings → General → Your account changes it later.
-Drawers. Drawers slide open and closed, and their » / « toggles moved from the top bar into the tab bars and panel headers. The right drawer's Agent tab (it replaces Changes there; Changes is now a tab of its own) shows the agent's picture, colour, name, handle and permissions.
-Wiki. The Wiki opens on the whole server's map, with a workspace picker in its header and three views: a reading view (notes on the left, the note and its links on the right), 2D, and a new 3D map that falls back to 2D on machines that can't draw it. Esc goes Home, then closes back to the page you came from.
-Smaller things. Drag to reorder agents in the Agents list, like on Home. Home no longer shows the beta notice and opens the top agent when none is selected. Tickets' "Waiting on me" includes tickets that need discussion. Settings → General shows the app font under the CLI version. Your own Thread message reads "just now" as soon as you send it.

Fixes

-k2 tunnel status no longer stops with a Python SyntaxError (broken in 0.45.7).
-k2 workspace create makes missing parent folders instead of failing.
-The Thread's activity strip stays up when you send a message while the agent is working, instead of disappearing and coming back.
-External Data answers with one confirm code: anything that needs your Touch ID or password says vault_confirm_required (a 0.45.x server's confirm_required is still understood).
-Help reads its glossary from the server shown in the top bar.
-Each Chatter line now carries its message's delivery id, so k2 msg who can look up who sent it.
-A closed drawer's arrow has the same dividing line as the tabs next to it.
-Closing a drawer or the project chat no longer flickers open for a frame.
-Home and Agents each remember their own selected agent, and moving to Home or Agents follows your workspace-switch focus setting (the Thread's message box first).
-The Tickets badge now counts only tickets waiting on you, including ones marked Needs discussion, so it matches the Waiting on me list.
-Owners can turn agent email sending on from any computer, not only a Mac: k2 mail sending off|approval|on, or Email sending in the workspace's settings, which shows what is in effect. k2 mail inboxes shows each inbox's real send state, and the hint when sending is off now names the right command.

After updating

-The inherited environment now ends in 0.46.1, not 0.46.0. Run k2 app warnings to see what each of your Apps still needs.
-From 0.46.1, an agent starting a new --cmd service needs both App switches on its workspace; until then k2 publish run only warns, and says so.
-Guarded Apps need the new App engine: run k2 app engine install (a deploy on the old engine stops and says so).
-Lines K2 already collected for a bot whose chat runs elsewhere move into that bot's Thread once.
-K2 rebuilds its token usage history once after the update (it reads your tools' logs again), so Usage may look empty for a few minutes.
-For live Claude limits, K2 adds a small status line script (~/.k2/hooks/statusline.sh) to ~/.claude/settings.json, only when you have no status line set. Yours is never replaced.
-Wiki public chat is off on every workspace (see Security).
-Gardens that follow K2's default themes pick up the new working colour (the theme's accent; Haunted's is bone). Garden 1 moves to the Glass theme unless you picked a theme for it. Your own copies keep theirs.
-Scripts that checked External Data for confirm_required should also accept vault_confirm_required.

v0.45.7

October 15, 2026

0.45.7 — Grok Bots at home

-Grok Bots on your server show up in K2. If Grok Bot runs on the same computer as your K2 server, K2 can find its agents and list them in Agents with a Grok Bot tag. Click one to read its chat, or right-click → Add to Home to keep it on My Home and in your Gardens, with live Working / Needs you / Idle status. Questions, connect requests and credential requests from a Grok Bot show as cards you answer in Grok Bot itself; K2 never asks for or shows a secret. Turn it on in Settings → 3rd Party Bots → Grok Bot, which first shows the folder and the agents it found. It's off until you turn it on, and only the owner or an admin can change it. Agents and App guests never see Grok Bot chats.
-Message a Grok Bot from K2. A separate Send switch, also off by default, lets the owner and admins message a Grok Bot from its chat in K2. Each message runs a billed Grok turn and arrives as [from ], so the bot knows who wrote it: your display name from Settings, or your login if you signed in to this server. In K2 the chat shows your name on the message instead of the tag. K2 limits how fast you can send, and never passes messages between K2 agents and Grok Bots on its own. If a bot's conversation now runs somewhere other than this computer (another box, or Grok's cloud), its chat in K2 says so and keeps the older history from this computer. You can still message that bot from K2: your message reaches its live conversation, and K2 shows its new replies under a "Live since" line as they arrive. K2 only sees the bot's latest message at each check, so when a bot writes several in a row, K2 shows the last one and says earlier ones may be missing; open Grok Bot to read them all.
-A Kanban board Garden. New Garden → Kanban gives you a board that starts with To do, Doing and Done and three small cards that show how it works; change everything after that. Add, edit and delete cards (notes take markdown), drag them between columns or up and down, and add, rename, reorder or delete columns (a column with cards asks where they go). Your agents can add and move cards too, inside the grant you give them (Settings → Gardens → Local Data); For agents on the board shows the exact command. The board follows your Garden's theme, light or dark, can open a Thread beside it, and exports as markdown.
-Your tunnel finds a working relay by itself. K2 now asks k2.dev for the current list of relays when it starts, every few hours, and right after you pair, so every computer and server knows all of them, not just the first. If a relay goes down, your tunnel moves to another one. When the main relay is healthy again, K2 checks it a few times and then moves back by itself, so nobody has to restart anything. k2 tunnel status shows which relay you're on and where the list came from.
-Tunnels ride out a paused or sleeping machine. When the computer wakes up, K2 no longer restarts a tunnel that is still connected. Applying the same tunnel settings again leaves the tunnel running and doesn't rewrite tunnel.json. If the settings can't be read right after a wake, the running tunnel stays up instead of going dark. Every tunnel stop and every tunnel change now goes in the daemon log with the reason and who asked: the owner, a Connect user, an agent, or a client over the tunnel.
-A locked vault never unpairs your tunnel. If K2 can't read the tunnel token from the vault for a moment (locked, busy, or just after a wake), it keeps the token and leaves the tunnel as it is, then tries again later. Before, saving any tunnel setting during that moment could erase the token and disconnect this computer from its subdomain. Releasing the tunnel still removes the token as before.
-k2 publish and other Connect commands work on desktops again. Since 0.45.4 the tunnel token lives in the K2 vault, so k2 publish status and k2 publish subdomain list/create/point/rm said "no K2 Connect tunnel token". The K2 server now makes those calls for the CLI with the token it holds; the token never leaves the server. k2 connect status reports the vault token too.
-Secrets reach tools under the env name you gave them. When you share a secret with an agent's workspace under a name (k2 vault grant --to ws: --as env --env-name MY_VAR), the agent now gets it as MY_VAR. Before, the workspace's own default delivery won, and a secret with a dash in its name (my-api-key) couldn't be delivered as an env var at all; now it becomes MY_API_KEY. k2 vault delivery … --env-name used to say OK and do nothing; it now refuses and points you to k2 vault grant.
-Agents publish and remove their own subdomains with k2 publish, no Settings needed. From its K2 terminal an agent can run k2 publish run, k2 publish subdomain create , change where it points with k2 publish subdomain target (same as point), and k2 publish subdomain rm . A label an agent creates belongs to its workspace, and an agent can only change or remove its own workspace's labels: never your main subdomain, the reserved skin, meet, chat and mail, or another workspace's. An agent can create or remove up to 20 subdomains an hour per workspace.
-Add published subdomains from Settings. Settings → Network → Tunnel → URLs now has Add published subdomain: type a label, see the full address, enter where it points (like localhost:3000) and, if you want, pick the workspace that owns it. Each row has Change target and Remove (Remove asks first). The new address shows up right away. Only the owner or an admin of this server sees these controls, and not while you're viewing another server. Nested subdomains still need the Pro plan; Settings says so if you don't have it. Before, this was only k2 publish subdomain create in a terminal.
-No false "fresh look" on a Diary. After an update, a Diary Garden that follows K2's default no longer gets a "has a fresh look" card when nothing about it changed.
-The sign-in button opens the whole link. When you add an AI login in Settings → LLMs → Tokens, Open sign-in page now opens the complete sign-in link. Before, a long Claude link could be cut short, so you had to copy it from the login terminal instead.
-See when each login's usage refreshes. In Settings → LLMs → Tokens, each subscription's usage now shows how long until it resets, like the usage menu in the top bar (for example "Session 42% · 3h"). Each token counts down to its own reset, and nothing shows when K2 doesn't know the time yet.
-Settings is sorted into clearer sections. After the top pages come these groups, in order. LLMs: LLMs (default agent, launch bar, presets and CLI install), Tokens (your subscriptions and API tokens: switching, Sign in again and each token's usage; it used to be the right half of the LLMs page) and Token Usage. K2 Server is now two groups: Access (Admin Access, User Access, User Templates, API Keys and Vault, each with a link to the login history in Logs → Access Audit) and Network (Tunnel, Custom Domains, Connected Servers and K2 Companion). Between them sits Gardens: Gardens (your Gardens, Lock and Keep in sync, the theme and the folder), Local Data (each custom widget's data on this computer, its grants, It's mine, export and delete; it was Widget data) and External Data (the checks this server runs for Garden cards and agents; it was Data Sources). Where there are no Gardens, External Data sits at the end of Network. Editors / Fonts now includes Key Bindings. Sidecars is now called Cores: Email Hosting, Chat Hosting (coming soon), Compute (moved here from the top pages), Database and Apps. Local Grok Bots is 3rd Party Bots → Grok Bot, the last group, which also lists Hermes, Instinct, Muse and Dots as coming soon. The app's Font family and Font size now also sit at the top of Settings → General; they are the same setting as Editors / Fonts → Code, so changing one changes both. Old links and search land on the same pages.

After updating

-Local Grok Bots stay off until you turn on Show (and, if you want to message them, Send) in Settings → 3rd Party Bots → Grok Bot.

v0.45.6

October 15, 2026

0.45.6 — Live cards and hired hands

-Live cards from the outside world. Your server can now watch outside services for you: an HTTP JSON check that runs on a schedule, even with no window open. Each item is rated ok, warn or crit, with a short history. Agents propose a source with k2 sources propose; you approve it in Settings → K2 Server → Data Sources, with a vault confirm when it uses a secret. Built-in Garden cards show it (fleet grid, version spread, relays and DNS, deploys, money alerts), and custom widgets can read it too. A trigger can wake an agent when something really changes, never on a brief blip. Keys stay in the vault and are bound to one exact site. You can also choose to store only states and never the values.
-Garden widgets keep their own data. A custom widget can now save and share data (notes on a board, rows in a tracker) in a store the daemon keeps on this computer. Agents work on the same data with k2 store, but only with the grants you give them in Settings → Gardens → Widget data. Big edits land all at once, changes appear live in every open window, and K2 keeps 7 daily and 4 weekly snapshots you can export or restore (k2 zen data …). An agent signs each widget version it makes. A version nobody has signed gets no data until you click It's mine.
-Garden 1 learns from K2 Companion. Your pinned agents sit in a grid of pictures at the top of Garden 1's list, three across. While an agent works on your message, a drawer above the message box shows what it's doing, its tool counts and a clock; click it for the detail. Garden 1's cog opens Garden settings, where Recent agents first (off until you turn it on, this computer only) puts the agents you last messaged from a Garden first, below your pins. New Garden now offers Garden 1 by name, next to the Diary. Gardens that sync with K2's default get the pin grid, the activity drawer and Garden settings. Your own copies keep their look; Settings → Gardens.
-Hire agents through the API. Software built on K2 can now create agents in one all-or-nothing call: it sets up the folder, role, connections and App logins together. Turn it on per API key in Settings → API Keys → Allow hiring agents, with limits, and confirm it as the owner. An agent it creates never gets more than the key allows, including how far into your Apps its logins reach (the key's App access limit). k2 agent hire now uses the same engine, and k2 msg who shows K2's own record of who really sent a message, so agents don't have to trust text that only looks like a sender tag.
-Switching AI logins is clearer. Settings → LLMs now confirms which login you're switching from and to, shows usage for each login separately, and offers Sign in again on any login that has gone idle. Every switch is recorded in the audit log.
-Add an agent to Home from the sidebar. Right-click an agent in the Agents view and choose Add to Home (under Pin/Unpin). With one Home it's added straight away; with several, pick which Homes. Agents from other servers stay linked to their own server.
-Projects permission per agent. Each agent has a Manage K2 projects switch (on by default, as before). Every project change an agent makes is now recorded in the audit log.
-Your own agent programs get Thread. Agents that run a custom preset now get a pinned Thread conversation, and any program can report its status to K2 with k2 hooks emit.
-Cards show who answered. When you answer a Thread card yourself, it shows your display name. Garden cards now show who answered and when they expire.
-App guests can't edit an agent's settings. People using your Apps can no longer write into an agent's config folder (.k2) by default. If an App really needs it, add the files:agentconfig permission to that App's role. App login lockouts now count per person, not per typed name, and App pages serve WebAssembly, modules, fonts and modern images correctly.
-The tunnel fixes itself. If K2's connection to the relay breaks or keeps crashing, K2 rewrites its settings before every restart and reports the problem instead of staying offline.
-Messages and heartbeats arrive whole. A file sent to an agent on another server with a wake now wakes it. Long heartbeat prompts are no longer cut off, and a heartbeat only counts as fired once the agent got it.
-Smaller fixes. Column widths you drag in a split now stay put when you switch workspaces or pages and come back, and after a relaunch; each window keeps its own. k2 agent restart restarts an agent's pinned chat. Removing a workspace now stops its agent sessions. K2 starts on macOS 14 again. Connect only remembers your password when the Keychain actually saved it. k2 root-helper status works inside K2 terminals. A compute job that asks for network = none is refused until K2 can enforce it. The names mail, meet and chat are reserved for K2's own web pages on your server. Data sources can now read sites that require a browser-like identity (such as the GitHub API). On Linux, Settings → General points deb and rpm installs to the new package instead of showing an update error, dark-theme dropdowns are readable, and shortcuts show the real keys instead of Mac symbols. One Esc in a Settings dialog now closes just the dialog.

After updating

-If one of your Apps lets guests write into an agent's .k2 folder on purpose, add files:agentconfig to that App's role.
-Data sources and triggers wait in Settings → K2 Server → Data Sources until you approve them.

v0.45.5

October 13, 2026

0.45.5 — Who's who

-Per-App logins. A login on one App now reaches only that App's rooms. A person needs a grant for each App, and two Apps can give one person different roles. Everyone who could sign in to an App before still can, with the same rooms: K2 copied their box login onto each App at upgrade. The exceptions are App grants you had already written in Settings → Apps (including disabled ones), which now apply, and roles tagged for another App; both are listed in the audit log. New Apps start with nobody: use Add everyone who has the box login (k2 app grant copy-host), or k2 app user add --app for someone who should see only that App. Custom (--cmd) Apps get K2_APP_ID, K2_HOST and K2_PORT, and can name themselves when they sign people in; without that, login works exactly as before. App logins also accept an email, and a locked login says how long to wait.
-Thread knows who's talking. In a shared Thread, "You" now marks only your own messages; everyone else's show their name. Mark your own Connect login with This is me (owner) in Settings so its messages count as yours too.
-Cards wait while you talk it over. Typing in a Thread no longer closes a pending card, so people can discuss a choice and tap an answer later. Cards have a time frame (7 days unless the agent sets another, k2 thread ask --expires 3d or --no-expiry), show "expires in…", and close on their own at the deadline. The agent is now told who really answered (an App user's or Connect user's name, not the owner's), and the card shows "answered by". Agents close cards that no longer apply with k2 thread void.
-Thread on your phone. Thread messages can push to the K2 Companion, per server and per workspace, and pushes for a Thread go quiet while you're looking at it.
-Renames show up everywhere at once. Renaming an agent, or changing its color or picture, updates every open window, Connect users on the web or desktop, and Home rooms on other servers, without anyone leaving and coming back. App users can be allowed to name their own agent and set its color and picture (Settings → User Access → Agent identity); changing its address is a separate permission (Agent handle).
-Handles are never reused. A deleted workspace's handle stays retired for good, so messages can never reach a different agent by mistake. A connection to an agent that no longer exists on another server shows as Gone (Re-add for owners and admins) instead of quietly re-matching by name.
-Lock a Garden. Settings → Gardens now shows two checkboxes per Garden. Lock garden stops your agents from changing it: its layout, widgets and widget code stay exactly as they are, and K2 puts back any edit to its file (the edit is kept in history). You can still rename, retheme, reset or delete it, and theme changes still reach it. Keep in sync with future template updates is Garden sync as one box, with a tag showing which template the Garden follows. The rest of the page is simpler too: drag Gardens to reorder them, search them by name, rename one by editing its name in place, and Delete asks in a dialog. The global theme and folder sit in their own Advanced column. Garden agent rows now carry each agent's color and picture.
-Big uploads for App users. People using your Apps can upload large files (plan sets, videos) that resume where they left off if the connection drops, into the rooms they're allowed to write.
-Databases know who's acting. When an App writes to a K2 database, k2.actor_kind() tells a person (guest) from an agent (agent), and k2.actor_info() says which. Only you can mark an App login as an agent's (k2 app user agent ). App-user writes through the database door now work like regular queries (including RETURNING), errors read plainly, K2's own tables are closed to App users, and one write is capped at 5,000 rows.
-Manage compute nodes from here. Settings → Compute shows approvals, each node's health, updates and alerts, and k2 compute node admin … does the same from the CLI. Node updates are now signed with K2's root key and the Mac node is notarized. A job that asks for a tool the node can't install is refused before it starts, and nodes can now install cmake, ninja and protoc. Per agent, Allow this agent to operate compute nodes sits next to Allow compute nodes.
-Agents from other servers open here. Home opens agents on your other servers on every OS, with no setting to turn on first.
-CAD and 3D previews. DXF drawings and 3D models (STL, OBJ, glTF and more) open as previews in Files.
-The working strip keeps up. Background jobs an agent starts now show in its pane, and a Thread message never starts or ends a turn on its own.

After updating

-People who use your built-in App pages sign in once more.
-Compute nodes: run node setup once from the new app on each Mac node (or k2 compute node update if it already runs remote admin); after that, updates arrive signed.

v0.45.4

October 11, 2026

0.45.4 — Vault, root door and mail that delivers

-K2 Vault. One encrypted vault per server holds the secrets that matter at runtime. That covers secrets you hand an agent through a Thread secret card, secrets your published Apps need (saved once by name and handed to the App when it starts, never written into code), and K2's own keys that used to sit in plain files. On a Mac the vault's key lives in your Keychain; on Linux it lives with the root helper. Your everyday .env files keep working as before. Set up the vault's recovery key in Settings → Vault: confirm with Touch ID or your Mac password, write down the 24 words, and type three of them back. See also k2 vault.
-Published services start clean. New k2 publish services no longer inherit K2's own environment. Services from before this update keep it for now and show that this ends in 0.46.0: switch each with k2 publish env clean and grant only the secrets it needs (k2 publish secret add).
-One root helper on Linux servers. A single signed, self-updating k2-root-helper replaces the separate mail and database helpers. It accepts only updates signed with its own key, and installing it removes the old helpers (backed up first). Your hosting provider rolls it out box by box.
-Hosted mail on Stalwart 0.16.25. Fixes outgoing mail that stalled on a false DNSSEC "Bogus" result for mail servers without IPv6, and spam rules that failed to load. k2 hostmail upgrade moves a box up (after the root helper is installed), checks the result and rolls back on its own if Stalwart doesn't come back healthy. An upgrade interrupted by a restart now finishes or rolls back at the next start, so mail is never left stopped.
-Tickets your way. Settings → Tickets, under Projects, lets the owner choose whether agent tickets need an HTML brief or an assignee (Off, Warn or Require; both start at Warn), and who gets agent tickets that name nobody. Agents can read the rules with k2 tickets settings but can't change them. The Tickets page now opens on Waiting on me (or All, or your last tab), and says "Nothing is waiting on you" when that's true (GitHub #75).
-Compute nodes get a home in Settings → Compute. See your nodes, grant them to workspaces, and pause or remove them. "Make this computer a node" installs the node program for you. Jobs can declare the tools they need (Node, Python, Rust and more), and nodes install them on demand. System packages install only from a list the node's owner approves.
-Compute in two switches. Settings → Compute starts with "Machines you can use" (CPU, RAM, free disk and online for each machine, with a "Use compute from this machine" switch). Which agents can use them is set per agent, next to its other permissions: Settings → Workspaces → → Agent → "Allow compute nodes". On means it can k2 compute run on every machine you switched on, including ones you add later, with sensible limits you can change (k2 compute grant). Switching a machine off lets its running jobs finish, then removes it. Your other servers with "Make this computer a node" on will list here for one-click joining once K2 Connect is updated; until then add them with an enroll code.
-Safer federation pairing. Connected servers now pair with a commit-then-reveal code, so the 6-digit code can only be checked live during pairing. Federation also gets its own identity key: pairs survive a server rename, and peers get a signed "same server, new address" notice. Older pairs keep working and show "Re-pair recommended".
-Switch your Connect name without a restart. Changing a server's K2 Connect subdomain moves its listener, certificate and routes in one step, and rolls back if anything fails.
-Turning off access takes effect right away. Switching off or removing an App user's access now ends their open sessions immediately instead of when the session expires, and taking a room away from a user removes it from their open sessions too.
-URL labels belong to one workspace. A workspace can no longer take over a published label another workspace owns. Owners can still move one on purpose with --transfer, and every move is logged.
-Clean status dots in the terminal. Claude's ⏺ marks (and similar symbols) no longer show as clipped grey emoji buttons on Linux, Windows and the web client; K2 now draws them itself. Thanks to the K2 Companion team for the fix.
-Change an agent's picture on a remote server. The file picker for a server's disk opened hidden behind Settings, so you couldn't pick an image (or a folder for New Workspace). It now opens on top.
-Readable tables in Thread. Markdown tables keep short columns readable instead of squeezing them to one letter per line; wide tables scroll sideways.

v0.45.3

October 9, 2026

0.45.3 — Quiet keychain, your own compute

-No more password prompts after updating. After 0.45.1 or 0.45.2, macOS could ask for your password over and over for "K2 Connect sign-in" or for Claude's login. K2 now writes every keychain item the way macOS expects, so reads stay silent. Items an earlier update broke repair themselves the first time K2 starts. If one can't be repaired, Settings → LLMs (and k2 llm tokens) shows the one command to run in Terminal. Thanks to Appa (Baden) for the report.
-Compute nodes (preview). Run builds and tests on your own Macs and Linux boxes through K2. Turn it on with k2 compute preview on, then k2 compute node add prints a one-line installer for the machine you're adding; confirm the 6-digit code it shows, grant it to a workspace, and agents can k2 compute run -- . Output streams back and the command's exit code comes with it. The machine's owner can pause or drain it at any time. This is a preview: CLI only, off by default, and it may change. Read k2 study compute first.
-Gardens can use the whole window. A full-window Garden's widget can now put its own buttons in the top bar (k2.canvas.setHitRegions) and make any of its own elements drag the window (k2.window.startDrag). K2's menu, Garden switcher and Zen toggle always stay on top, so you can never lose your way out. See k2 study zen.
-"This computer" stays put. It's pinned at the top of the server picker, above the list of other servers, so it never scrolls out of reach.

v0.45.2

October 9, 2026

0.45.2 — A haunted Diary

-The Diary, reborn. Your words stay in dark ink once sent, and both sides write in markdown (headings, lists, quotes, code). When the page is empty, a ghost writes teases into it, then smudges them away; it never asks for passwords or account details. While the agent works, a pen scribbles in frustration instead of loading dots, and the page glides up smoothly as the reply writes itself. The paper has grain, candlelight that flickers with the candle in the room, and a little ink bleed; pages have square corners and curl only when you reach for them. One Diary menu sits at the top left.
-Music for the study. Quiet ambient music, made live on your computer (no audio files), fades in when you arrive on the Diary and out when you leave. Mute it with the speaker at the top left, or press M.
-A sharper haunted study. The Haunted theme's room is redrawn at 3840×2400 with far more detail: moonlit window, shelves, cobwebs, and a few things that shouldn't be there.
-Ghosts and scary things. While an agent works, the Diary says how many ghosts are out (its subagents) and how many scary things have happened (its tool calls this turn). The built-in Agents widget shows the same numbers plainly: "2 subagents · 14 tools · 5 commands".
-Counts for Gardens and Apps. Agent rows in Gardens, and the activity pulse Apps receive, now carry counts (subagents, tools and commands this turn), numbers only. Custom widgets and Apps can show them; the SDK types include the field.
-Reload where it belongs. A custom widget that fills its whole Garden no longer floats a ⋯ over the page: Reload is in the Garden's menu.

After updating

-Diary Gardens synced to K2's default move to the new Diary and the sharper Haunted room. Gardens you made your own copy of don't change (Settings → Gardens).

v0.45.1

October 8, 2026

0.45.1 — Gardens you build

-Build your own Zen widgets. Ask an agent (or write it yourself) and a widget appears in your Garden, running in a sealed frame that can't reach the network or your files. It can talk to your agents right away: no permissions to click through. If a widget posts too much, K2 pauses its posting until you click Resume on it. Widgets that post to Thread show as "You · via ". A standard library ships with K2 (three.js, Phaser, D3, ECharts, Lottie, Tone.js, Leaflet, KaTeX and more), and other libraries download on first use. k2 zen widget new gets an agent started.
-New Garden, and the Diary. "+ New Garden" opens one window: name it and pick from the catalog. The first entry is the Diary, a haunted journal with one page per agent on this computer: write on a page, the ink sinks in, and that agent answers in handwriting. Turn the page to talk to another agent. The Diary fills the whole window: the book lies on a candlelit desk in a misty study (a new built-in theme, Haunted, that any Garden can use), with no window buttons in the way. New users get it preinstalled, and a small card next to What's new tells you when a new Garden arrives.
-Your Gardens stay yours. Each Garden is either synced to K2's default (it gets our improvements) or your own copy (it never changes on update). Choose per Garden in Settings → Gardens. Gardens you customized became your own copy on this update, so nothing changed on screen.
-Thread survives a tab rename. Renaming a chat or sidecar keeps its Thread working: old addresses still reach it, replies show the new address, and the agent is told its new name. Chats opened from history get their own Thread.
-Agents can use calendars. k2 calendar lists, reads and drafts events on hosted inboxes (never sends invites on its own). Owners and IT agents can create groups and shared team calendars with k2 hostmail group and k2 hostmail calendar share. An assistant agent with access to a person's inbox sees that person's shared calendars.
-Hosted mail, steadier. Mail to providers without IPv6 no longer gets stuck. k2 hostmail status shows the real certificate names and the last certificate error, domain add lists the A records you need, and spam rules that newer rule downloads broke are repaired. New: k2 hostmail outbound. k2 hostmail backup plan measures how much space a backup would need.
-Domains go live by themselves. After you switch a domain's nameservers to K2, the server notices within minutes; no more k2 domain refresh.
-Message any agent by either name. k2 msg works with a workspace's handle and its agent name. k2 agent hire --name keeps the name you give it.
-Move a chat to another tool. k2 workspace swap-canonical moves a workspace's main chat to another AI tool and hands over the recent conversation. Thanks to Sterling Long (Luzzotica) for this one.

Security

-Published Apps can no longer be shown inside other websites. If you embed your App on your own site, allow it with k2 publish frame --allow https://your.site (owner only). Apps published with --cmd run their own server: k2 publish ps warns when one sends no frame protection.
-Stronger login protection against password spraying, without ever locking out your own logins through K2.
-Only a person can answer a secret card, and an answered card can't be changed.
-K2's own folder and databases are readable only by you, and tokens never appear on a command line.
-Messages between servers are only delivered to workspaces and names that server actually lists.
-Network, air-gap and companion settings, and "Reset settings", are owner-only.

Fixes

-Switching LLM tokens on a Mac works with large Claude logins, and every swap is checked and rolled back if anything goes wrong. If a swap failed on 0.45.0, sign that token in again.
-Settings → LLMs shows the server you're looking at, not this computer.
-A file that's too large gets a clear "too large" error instead of a dropped connection.

After updating

-If you saved a connection as agent.md::, add it again with the agent's name.
-Servers with the Postgres add-on get the safer database helper the next time the helper is reinstalled.

v0.45.0

October 8, 2026

0.45.0 — See your agents work

-Thread shows the agent working. While an agent works, Thread shows a live strip under your message: the time since you asked, the current step ("Running a command", "Thinking… 8s"), any subagents, and a Stop button. It stays up after the reply while subagents or background tasks are still running, and says plainly when the agent is stuck on a permission prompt or a question.
-Activity you can trust. The server, not each window, now decides whether an agent is working. Every window, the web app, My Home and Zen show the same state, and it no longer gets stuck on "working". Older servers keep showing their dots in the new app.
-LLM tokens. Settings → LLMs → Tokens holds several subscriptions and API tokens for Claude, Codex and Grok (API tokens for Gemini too). Each tool has one server default. Use next token switches when one runs out, and running chats pick up the change. Any chat tab or workspace can use its own token: open the Token menu in the chat header, or right-click the tab. K2 keeps your saved logins fresh. Logins stay on this server and never travel in a clone. From the CLI: k2 llm tokens.
-Hosted mail: calendars groundwork and steadier certificates. Servers get ready for calendars and contacts. There's an Apple setup profile (k2 hostmail profile) and an explicit Stalwart upgrade to 0.16.20. Certificates K2 issues now renew themselves before they expire.
-Mail you stay in control of. k2 mail send --bcc, and an owner "always BCC" setting per workspace that the agent can't remove. Agents send only through K2, so your rules always apply. An agent allowed to manage mail can now do what you can for other mailboxes, except loosen the rules on its own mail.
-k2 sidecar. Agents can start, list and stop side chats for Claude, Codex, Grok, Gemini, Cursor, Pi and Hermes. Each can be resumed later. Turn it on per workspace with k2 sidecar access on.
-Rename agents from the sidebar: right-click → Rename agent. The handle stays the same, so messages keep working.

Fixes

-Codex: each chat runs its own background server, so Thread replies and k2 commands act as that chat. Messages you send before Codex's first reply no longer disappear. If Codex was already open, restart it once after updating.
-A Thread message to a chat opened from history now goes to that workspace's agent, never another workspace's.
-Terminals no longer hang or print (eval) errors when the login shell prints extra output at startup.
-Published apps on localhost load even when the server lists IPv6 first. An app that isn't running shows "Service not reachable" (502) instead of a 404.
-My Home remembers the view (terminal, chat, split) for agents on other servers.
-The LLM launch bar starts hidden; turn it on in Settings → LLMs.
-The Zen permission banner just states that the agent is stuck, with no button. Zen widgets get the full set of agent states (working, monitoring, needs you, no update, idle).

Server owners: to use the calendar features, re-run the mail helper installer once with --version 0.45.0 (sudo bash install-mail-helper.sh --version 0.45.0). New servers we set up get it automatically.

v0.44.4

October 7, 2026

0.44.4 — Security update

-Important security fixes. K2 now checks where every browser request comes from before it acts on it, for the web client, apps and live connections. Please update the app and your servers.
-Actions use the right method. Every action that changes something now needs a POST request. Reading still works as before. Update the desktop app along with your servers: an older app connected to a 0.44.4 server can read but can't make changes until it's updated.
-Apps. An app's guest sign-in now expires after 7 days, and app requests from other sites are refused. Apps calling their own address keep working as before.
-Agent switches. Only Admins and Owners can turn agent permissions on or off (DNS, connections, mail sending, database access). An agent can't grant itself database access.

v0.44.3

October 7, 2026

0.44.3 — Gardens your way

-Put the controls anywhere. A Garden file can now place the Garden switcher, the Zen toggle, usage and the theme picker wherever you like: the top band, a new bottom band, the top or bottom edge of a column, or inside a menu. Leave one out (usage, for example) and it's hidden. A Garden can drop the top band entirely; a thin strip stays so you can still drag the window.
-Menus. A menu button can hold the switcher, the Zen toggle, the theme picker and usage. It works with the keyboard: arrows to move, Enter to pick, Esc to close.
-The nav rail in the top band. slot = "top" puts My Home, Agents, Projects and Tickets as a row of icons next to the Garden switcher.
-Always a way out. The Garden switcher and the Zen toggle must each be on screen or one click away in a visible menu, or the Garden won't validate. A closed menu never trips safe mode. On a narrow window, usage and theme hide before anything you need. ⌃⌘Z, View → Exit Zen Mode and Shift-for-safe-mode work in every layout.
-k2 zen guide. A user guide in the CLI with 10 topics and copy-paste examples (bottom bar, both buttons in a menu, the rail on top…). It works even when K2 isn't running. k2 study zen points to it, and validate errors name the page to read.
-Older K2 apps ignore the new layout and keep today's top band.

v0.44.2

October 6, 2026

0.44.2 — IMAP repair works without the mail helper

-IMAP check on startup, fixed. In 0.44.1 the startup check for the IMAP listeners (143 and 993) skipped itself whenever the mail helper wasn't installed yet. Now it reads the listeners first. If both are there, it does nothing. If one is missing, it adds it, then restarts the mail server through the helper or the server's existing permission to restart it. If neither is available, it keeps the new listener and logs the one command to run.

v0.44.1

October 6, 2026

0.44.1 — Hosted mail installs again, and air-gap fixes

-IMAP on older mail servers. A server that turned on hosted email before 0.40.147 never got IMAP on ports 143 (STARTTLS) and 993 (TLS). On startup, the daemon now adds whichever of those two is missing and restarts the mail server once. If both are already there, it does nothing. Nothing else in the mail setup changes.
-Air-gap stops the usage check. With air-gap on, K2 no longer checks your Claude, Codex or Grok usage, so nothing goes out to those services in the background. The usage chip reads "Off (air-gap)".
-Mail helper ships with the release. Turning on hosted email needs a small root helper on the server. It now comes with every release, along with a one-line installer that someone with root runs once per server. If the helper is missing, k2 hostmail enable stops before downloading anything and prints that exact command instead of "Permission denied". k2 hostmail status shows helper: installed, missing, or not allowed by sudoers.
-Reverse DNS reads right. k2 hostmail ptr set judges "aligned" by what k2.dev actually published. If this machine's DNS cache still has the old name, you get a note saying it clears on its own, instead of "not aligned".

v0.44.0

October 5, 2026

0.44.0 — Zen Gardens

-Zen Mode. The ensō at the top right of the top bar turns a window into Zen: a calm, personal page instead of the admin panel. ⌃⌘Z leaves Zen from anywhere (Ctrl+Alt+Z on Linux). Hold Shift when turning it on for safe mode. Zen is per window, and it's on the Mac and Linux desktop app only.
-Gardens. Inside Zen you see your Gardens. They're personal pages kept on this computer, and nobody else on the server sees them. Garden 1 has a thin rail (My Home, Agents, Projects, Tickets) beside your agents and a conversation. Garden 2 starts empty: ask your agents to build it, or click Start with the default. ⌘⌥1–9 switches Gardens. + New Garden asks whether to start with the default or empty.
-Inside Garden 1. My Home shows your Homes' agents. Agents shows this server's agents, with a GROUP: picker when focus groups are on. Tickets shows the Tickets board in glass, with chat only. Projects is coming soon. Picking an agent, or coming back to it, puts the cursor in its message box. Agents' pictures show where they have one.
-Themes. Basic (K2 blue), Midnight and Paper. ⌃⌘. cycles them, and each Garden can have its own. The usage chip and the theme control sit at the top right, and every tile has the same soft glass edge.
-Agents can build it. k2 zen garden list|new|rename|reorder|delete|template and the k2-zen skill let your agents arrange and restyle Gardens for you. Settings → Gardens manages them too.
-My Home. The Home tab is now called My Home, and its tooltip says it's your own page on this computer.
-Thread stays in sync. A message sent from a Garden, the Agents page, Home, another window, another person, or an agent now shows up live in every view of that Thread. A view that loses its connection reconnects and catches up by itself.
-Fixes. Typing no longer hides the working dots, and a growing message box keeps the newest message in view while you're at the bottom. Dropdowns in cards are no longer cut off.

v0.43.3

October 4, 2026

0.43.3 — Tickets go live for apps

-Live tickets in apps. An app with ticket access now hears ticket changes the moment they happen, on the same activity socket it already uses: new tickets, comments, answers, status changes, assignments, and resolves or dismisses. Each person only hears about tickets in rooms where they're allowed to read them. Briefs are never sent over the socket. Apps fetch them on demand.
-Apps catch up with the new tickets. Apps that can post to tickets can assign a person, with the same warning for names that aren't on the server. Answering with a suggested option or a typed message, changing the status, and reading a brief are all covered.
-Privacy. Ticket reads for app guests no longer include file paths on the server or internal session IDs.
-For app developers. k2 study app-tickets documents the events and the ticket calls.

v0.43.2

October 4, 2026

0.43.2 — Agents from other servers open right on Home, and tickets you can read

-Other servers open in place. On macOS and Linux, picking an agent from another server on Home opens it right there, and your window stays put. If you turned this off before, it stays off. The setting is Settings → General → Experimental → Open agents from other servers here. Windows keeps the old behavior for now. Servers older than 0.41.0 still switch the window, and 0.41 and 0.42 servers open view only.
-Switching servers keeps your rooms. Changing servers in the top bar no longer reconnects the agents open on Home.
-The top bar follows the agent you're looking at. For an agent from another server, the server name, people, usage (for example "akzm | 42%") and Keep awake show that server. The timer and the Tickets badge stay on your window's server.
-Home shortcuts. Rows on Home show their number. ⌘1–9 opens a row, and ⌘⌥1–9 switches between your Homes.
-Tickets, redesigned. A narrow list sits on the left, with short cards showing status, who it's assigned to, age, and an HTML mark. The agent's write-up fills the middle. The chat sits on the right, with Thread and Agent tabs, and a message box that has the agent's suggested answers above it. Change the status or the assignee from the ticket's header. Filter by Mine, Waiting on me, or All. Collapse the list to agent pictures. Open a ticket in its own window.
-Answers and discussions. Picking one of the agent's suggested answers marks the ticket answered. Writing your own message moves it to Needs discussion until the agent settles it.
-Agents write their requests up. An agent asking you for help can attach an HTML brief covering the problem, what it tried, what it needs from you, and the options. It opens in a locked frame with no scripts, and its links open in your browser. Agents should also assign every ticket to a person on this server. For now a missing brief or assignee is only a warning.
-Keep awake without the password prompt. Choosing a mode no longer asks for your Mac's admin password. "Also with the lid closed" is its own switch, and its one-time setup runs only when an Admin or Owner clicks Set up on that Mac. Only Admins and Owners can change Keep awake. Members see it read-only.
-Live status everywhere. Working dots update live for agents from other servers too. Email settings refresh on their own. The usage figures in the top bar update within a minute of each check.
-Mac touches. The daemon shows up as K2 Daemon with the K2 icon in Activity Monitor. The window buttons stay centered when you zoom with ⌘- and ⌘=. The Tickets page has no leftover close button.
-Fixes. An agent can no longer open or change the inbox of a workspace it isn't connected to. Codex host sessions start again with codex 0.154.

v0.43.1

October 3, 2026

0.43.1 — No more "Something went wrong" after 0.43.0

-The 0.43.0 crash. On 0.43.0, the window could fall into "Something went wrong" soon after opening, on your own server or another one. After the Keep awake button checked its status, other requests on the same connection could get that status back instead of their own reply. Every reply now matches its request.
-Crash guards. A list that comes back in the wrong shape no longer takes down the window. This covers the usage chip, presets, the chat list, Heartbeats, token usage, Projects, saved split layouts, and ten more places.
-Crash panel. "Something went wrong" has a Details section with Copy details, so a report names the part of the app that broke.
-Grok usage. At 0% used, the menu shows Weekly 0% with its reset time instead of "No usage window".
-Thread. An empty Thread says "No Thread messages yet" in the middle of the pane and names the agent you can message.
-HTML safety. HTML files, dashboard HTML, and HTML email can no longer reach the local K2 server or plain-http sites. Scripts and styles still work where they did.
-Keep awake. The menu uses square controls like the rest of Settings, and the mug is redrawn at full size. It fills up to show the mode.
-Settings. The last round checkboxes are now square.

v0.43.0

October 1, 2026

0.43.0 — Home, heartbeats that fire on their own, and apps

-Home (Beta). A Home tab sits between the gear and Agents. It looks like Agents, but the list is yours: agents from any server you have saved, in named Homes, and switching servers doesn't change it. Add Agent offers This server or From a server. Rows show live, offline, or Sign in, and the initials of whoever else is on that agent.
-Remote rooms (preview). Turn on Settings → General → Experimental → Remote rooms, and an agent from another server opens right on Home without switching your window. You get its tabs, drawers, chat history, and presence. You can type, open and close tabs, and split, and it all saves on that server. A server that's too old opens view only and says why.
-Heartbeats fire on their own. The daemon now runs the schedule itself every minute, on Mac, Linux, and Windows, even with no window open. A heartbeat missed while the computer slept fires once when it wakes, if it's less than 12 hours late. Turning one on or editing it waits for its next slot.
-Wake this computer for heartbeats. One switch in Settings. On a Mac it asks for your admin password once. "Also on battery" stops below 20%.
-Keep awake. A new control next to the timer in the top bar: Off, While agents are working, or Always. It says what it can actually hold, for example "lid closed will still sleep". Keeping a Mac awake with the lid closed uses the same one-time admin approval.
-Heartbeat drawer. It shows the real next fire, or the reason it's waiting, such as "needs instructions", "invalid schedule", or "retry in 2m". It never shows a stuck "now". New heartbeats need instructions. History shows who made each change. Only the Owner can delete a heartbeat for good; everyone else archives.
-Apps and heartbeats. An app can list, add, edit, turn on and off, fire, and archive the heartbeats in its room with heartbeats:read and heartbeats:write. App developers can read k2 study app-heartbeats. Apps can hear "agent working" again.
-Split view. Two windows on the same workspace share columns. A tab closed in one window stays closed in the other. A Browser tab no longer follows the other window's navigation or flickers.
-Tickets badge. The badge counts only tickets you can see. Tickets left from a removed workspace show under Unlinked workspace with Resolve and Dismiss. A badge that can't refresh dims instead of showing a wrong number.
-Roles. The Viewer role is gone. Logins are Owner, Admin, or Member. Use apps to give someone limited access. A Viewer account is turned off on update, and Settings lets you turn it back on as a Member.
-Stability. A rare error inside a window event no longer quits the app; it's logged to ~/.k2/client-event-faults.log. Mac stoplights stay centered after moving between displays, waking, or switching light and dark.
-Claude usage. The top-bar chip shows the greater of the 5-hour and weekly limits.

v0.41.6

September 30, 2026

0.41.6 — Notes you can page, and a lock you can clear

-Read what's new. Settings → General opens on the newest note. The arrows walk back through 0.41.0 and every later note in this series, and they stop before 0.40. Closing the popup still marks this version seen. The button still opens after this version was already dismissed.
-Login lock. k2 app user unlock clears an app guest's lock and leaves the password alone. k2 users unlock does the same for a box login. A name with no lock still succeeds. Changing an app user's password leaves the lock in place. Changing a box user's password still clears that lock.
-Thread. A message sent as the room shows the room's name. You is a message typed in the compose bar.
-Apps. An app with a room can add a file to that room's resource list, rename one file in the room, and hear when an agent there is working. Settings → Apps lists activity:read on its own. files:read and files:write do not include it. A new file name is one name, not a path.
-Database grant. k2 db grant can name the tables or views another workspace may use. Repeating --relation replaces that list. Leaving --relation off restores the whole public schema. A later migrate keeps the same list.
-Guest query. On the Linux database, an app session can send one SQL statement. K2 fills in the signed-in person, and the statement cannot choose someone else. A read uses store read. A change uses store write.

v0.41.5

September 29, 2026

0.41.5 — Nested workspaces, and menus that stay put

-Nested workspace. A workspace that lives inside another workspace keeps its own terminal. The outer workspace's session list no longer shows the inner one. Opening a saved pane leaves the other workspace's live terminal alone.
-Menus. A dropdown opened from Settings, or from a dialog, paints solid and sits above the layer that opened it. A list that used to clip inside the page now opens on the page.
-Read what's new. Settings → General opens the latest notes. It does not replay the older pages in this version series.

v0.41.4

September 29, 2026

0.41.4 — User access, apps, and shortcuts in the front window

-User Access. K2 Server lists Admin Access, User Access, User Templates, Custom Domains, Tunnel, Connected Servers, API Keys, and K2 Companion. User Access, User Templates, and Apps are marked Beta. You add a person on User Access. Each app lists its users, and adding one gives that person a role on the app.
-Apps. Pick an app on the left and its users and roles are on the right. Platform tokens and the sign-in issuer stay on Host. The old Caddy group is no longer on this page.
-Connected agents. The mark next to a connected agent is a square.
-CLI on Linux. Settings → General shows the k2 command that is already on the machine, including an Arch install. It no longer offers a Mac-only install button when that command is missing from the Mac path.
-Front window. Command-K, Command-J, and Command-Shift-L open in the window you are using. Other K2 windows stay put.
-Wording. User Access says app users.

v0.41.3

September 28, 2026

0.41.3 — Window chrome, and a crash after a long run

-Top bar. The K2 icon is the menu on Linux and Windows. Projects, Tickets, Settings, and Wiki use the same logo and the same right-hand cluster as Agents. New Window is Ctrl+Shift+N on Linux and Windows, and still Command+Shift+N on Mac.
-Linux window buttons. GNOME shows close, minimize, and maximize. Other Linux desktops, including Hyprland on Arch, show close only. The squares sit 1px lower in the bar. A divider next to the drawer buttons hides when those buttons are not on the page.
-Long run. After the app had been open for many hours, a missing method name inside a window event quit the process. That event is skipped. The app stays up.
-Email Link. The Primary workspace menu on Connect an inbox stays readable and can be clicked. It no longer opens as a see-through list inside the page.
-Mac and Windows. Mac keeps the system stoplights. Windows keeps minimize, maximize, and close on the right.

v0.41.2

September 27, 2026

0.41.2 — Arch download, and quieter stoplights

-Arch updates. On an Arch package, Settings → General no longer asks the Mac updater list for a Linux entry. A newer release offers the pacman package (k2--x86_64.pkg.tar.zst). The app does not install it. The same version stays quiet.
-Stoplights. When the window is not selected, the square stoplights stay the same grey and become 80% translucent.

v0.41.1

September 27, 2026

0.41.1 — Server switch no longer quits the app

-Square close button. Switching to another server changes the window title. On the Square style that update asked the close button for theme-button calls it did not have (setEditedFlag:, setTemporarilyDisabled:), and the app quit. Those calls now go to the system button. The square paint stays.

v0.41.0

September 27, 2026

0.41.0 — Usage, chat continuation, and a desktop that stays put

Everything since 0.40.150. The window, the browser, usage, and how a chat continues.

-Subscription usage. Signed-in Claude, Codex, and Grok show a chip on the top bar with the harness icon and the percent used. A harness you are signed out of stays hidden. The menu has the allowance bar, recent turns, and Refresh. Settings → Token Usage (under Context Catalog) charts daily tokens and can filter by workspace and model. The host ledger records Claude, Codex, and Grok. Gemini’s subscription meter is not in this build.
-Continue in a new chat. From history or from pinned Chat, continue in another harness. The menu shows that harness’s icon and where the chat came from. Claude, Codex, Grok, and Gemini can also show the session itself as chat.
-Plus menu. The tab bar has a plus menu. Hold Option and the preset you clicked opens in a sandbox. Launching an agent installs that one CLI if it is missing.
-View menu. One View menu replaces the old strip. Terminal is listed, then Chat. The button is named for the mode you are in. A plain shell tab uses a window icon and does not wear agent chrome. Inbox and pinned Chat stay on screen while the rest of the strip scrolls.
-Tab icons. File tabs use the same icons as the files drawer. A browser tab shows the site’s name and icon.
-Images and notices. Drop an image on Thread or on chat compose. Pane notifications sit at the top right.
-Square window. On the Square style, the stoplights and the window corners are square. Status marks are square. Radios and checkboxes are square. The window title is K2 and the server name. The logo opens the K2 dashboard. The Running Agents button is gone from the top bar. The nav collapse button sits at the bottom of the sidebar. The collapsed rail uses the same Active list as the open sidebar, without the old corner dots.
-Menu bar. On a Mac, a helper stays in the menu bar after you close the window and says whether this Mac’s daemon is running. Clicking it opens that menu.
-Browser. Back and forward live on the browser tab. The address field is square, and devtools is a cog. The page stays up when another app is in front, and still steps aside for other K2 tabs, Settings, and open menus. ⌘L selects the address on a browser tab, and opens the server switcher otherwise. ⇧⌘L is still the workspace assistant. A new browser tab starts with the address selected. Dragging a file in from Finder works. The Mac pane names the WebKit it is actually running, so sites serve the normal page. The embedded browser is on the current system webview.
-Server switcher. A click no longer dies because Settings, or another page, left a hidden copy of the switcher open.
-Sidecar refresh. Refresh resumes the same conversation and keeps the same tab. The terminal inside redraws. Closing the session still removes the tab.
-Sidecar Thread. Send waits until that extra chat has an address. Your draft stays if it is not ready yet.
-Heartbeats. Clicking a heartbeat opens the session that is already running. After the first fire, Own session points at the session it opened.
-Files. Long names in the drawer keep the end of the name visible.
-k2 workspace resources. list, add, and remove for a workspace’s resource files.
-Arch package. The release-tag build of the Arch/Omarchy package runs again.

Not in this build: Gemini’s subscription meter, and Home.

v0.40.150

September 23, 2026

0.40.150 — People, grants, and mail an agent can stand up

A skin user can have a full name, and Settings shows that list as People. Who may open an app is a grant. An agent on the box can bring hosted mail up with the CLI.

-People. Optional full name on the skin user (64 characters). Settings → People is that list. It is not Server Access. k2 app user full-name sets or clears it.
-Grants. A role is the rooms and caps for one app. A grant says who has that role. The subject is a skin user or a workspace. k2 app grant list|add|rm is owner-only. There is no separate people table.
-Host login. The first boot copies every existing guest onto a host grant and keeps an assigned role. A new guest gets a host grant. A missing host grant fails login the same way a bad password does. Deleting that grant stays deleted.
-k2 app. The human-facing command is k2 app. k2 skin still runs and points at it.
-Mail from the box. User k2 can run k2 hostmail enable from zero. A root helper does the system steps, so enable does not need a second admin at the keyboard. A partial enable resumes instead of stopping because this box is already listening on port 25.
-Arch and Omarchy. A release tag builds k2--x86_64.pkg.tar.zst on the Arch runner and attaches it to the GitHub release. One package for both. pacman -R k2 leaves ~/.k2 in place.

Not in this build: a Windows runner, a grant required per app address, mailbox and database grants applied to mail or Postgres.

v0.40.150a

September 23, 2026

Arch and Omarchy package for 0.40.150. The Mac release is v0.40.150. The package file is k2-0.40.150-x86_64.pkg.tar.zst.

v0.40.149

September 19, 2026

0.40.149 — Agents can attach hostnames; doctor refreshes; certs over CNAME

Mail-manage / DNS-manage agents can add mail. themselves once the apex is on the box. Thread posts from k2 thread remind agents the overlay paints markdown.

-Hostname add/remove is dns_manage. k2 domain name add [--role mail|publish|direct|other] and name remove use the same grant as k2 dns / k2 cert issue. Apex k2 domain add|remove stays owner (exit 3). e2e on lztek: idempotent add of mail.discover-nocode.com, scratch add+remove, apex still owner_only.
-Thread markdown nudge. After a successful k2 thread write (not --json), a stderr hint on the first post and every 10th: Thread renders markdown (bold, lists, code, fences, links). Help and AGENTS.md Tooling say the same.
-Doctor refreshes. k2 hostmail doctor POSTs /cli/mail/doctor (runs probes now). It no longer GETs the last stored run, which stayed stale after PTR/DNS already moved.
-Cert issue vs CNAME. If the apex is dns_write, k2 cert issue uses DNS-01 on _acme-challenge. (not the mail CNAME). It waits until ns1 and ns2 both have the TXT, then 8.8.8.8 and 1.1.1.1, before telling Let's Encrypt (querying public DNS too early caches NXDOMAIN from a lagging NS). Finalize accepts an already-Valid order. Issue JSON reports inventory PEM SANs, not live TLS through a CNAME. e2e: scratch-le4.discover-nocode.com issued YE2. If the hostname is a CNAME and the zone is not dns_write, it fails loud instead of HTTP-01 following the CNAME onto a closed :80.

Not in this build: People hub, hide XOAUTH2 when no IdP, Omarchy pacman package.