What's New
Release notes for K2. Updates are published to GitHub.
v0.45.0
Latest0.45.0 — See your agents work
k2 llm tokens.k2 hostmail profile) and an explicit Stalwart upgrade to 0.16.20. Certificates K2 issues now renew themselves before they expire.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.Fixes
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.(eval) errors when the login shell prints extra output at startup.localhost load even when the server lists IPv6 first. An app that isn't running shows "Service not reachable" (502) instead of a 404.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
0.44.4 — Security update
v0.44.3
0.44.3 — Gardens your way
slot = "top" puts My Home, Agents, Projects and Tickets as a row of icons next to the Garden switcher.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.v0.44.2
0.44.2 — IMAP repair works without the mail helper
v0.44.1
0.44.1 — Hosted mail installs again, and air-gap fixes
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.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
0.44.0 — Zen Gardens
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.v0.43.3
0.43.3 — Tickets go live for apps
k2 study app-tickets documents the events and the ticket calls.v0.43.2
0.43.2 — Agents from other servers open right on Home, and tickets you can read
v0.43.1
0.43.1 — No more "Something went wrong" after 0.43.0
v0.43.0
0.43.0 — Home, heartbeats that fire on their own, and apps
heartbeats:read and heartbeats:write. App developers can read k2 study app-heartbeats. Apps can hear "agent working" again.~/.k2/client-event-faults.log. Mac stoplights stay centered after moving between displays, waking, or switching light and dark.v0.41.6
0.41.6 — Notes you can page, and a lock you can clear
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.activity:read on its own. files:read and files:write do not include it. A new file name is one name, not a path.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.v0.41.5
0.41.5 — Nested workspaces, and menus that stay put
v0.41.4
0.41.4 — User access, apps, and shortcuts in the front window
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.v0.41.3
0.41.3 — Window chrome, and a crash after a long run
v0.41.2
0.41.2 — Arch download, and quieter stoplights
k2--x86_64.pkg.tar.zst ). The app does not install it. The same version stays quiet.v0.41.1
0.41.1 — Server switch no longer quits the app
setEditedFlag:, setTemporarilyDisabled:), and the app quit. Those calls now go to the system button. The square paint stays.v0.41.0
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.
k2 workspace resources. list, add, and remove for a workspace’s resource files.Not in this build: Gemini’s subscription meter, and Home.
v0.40.150
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.
k2 app user full-name sets or clears it.k2 app grant list|add|rm is owner-only. There is no separate people table.k2 app. The human-facing command is k2 app. k2 skin still runs and points at it.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.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
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
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.
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.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.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.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.
v0.40.148
0.40.148 — Hosted-mail PTR and bans, skin files, server switcher hotkey
Hosted-mail operators can set this box’s SMTP reverse DNS and unban Mail.app users after a migration. Skin guests can move PDFs and images without an owner token. ⌘L opens the server switcher.
k2 hostmail ptr show|set writes the SMTP banner name and asks k2.dev to set the OVH reverse for this box’s origin IP. Doctor PTR/FCrDNS now queries 8.8.8.8 and 1.1.1.1, not the box’s own stub cache. One IPv4, one PTR — not one per hosted domain.mail. hostname (mail.lztek.io), not mail..k2.dev .k2 hostmail bans list|clear|migrate and k2 hostmail allowlist list|add|remove. Default bans list shows reason counts and real-user (authFailure) rows first; scanner IPs are a summary (full list: --json).k2skn_ can read-binary / upload-binary / create / copy / move in rooms with files:read / files:write. Pin lookup is find-only (200 if Chat is live, 404 if not — it does not start the agent). Thread posts still wake a sleeping Chat the same way k2 msg does. Admin Skin Access stays owner.k2 agent hire --focus-group Ops --color "#22c55e" (also rgb(r,g,b)). Settings → workspace → Agent tab has a hex/rgb field next to the swatches.Not in this build: People hub, hide XOAUTH2 when no IdP, k2 hostmail reload, guest spawn of a pinned Chat, Omarchy pacman package (release.sh still does not build one).
v0.40.147
0.40.147 — Custom domains, IMAP 993, and hosted-mail operator tools
Attach a real domain to this server — Settings → K2 Server → Domains, or k2 domain add then k2 domain name add mail.example.com --role mail. That does not move nameservers and is not a K2 edge. Hostnames on this box get a Let's Encrypt certificate here (k2 cert issue / renew); cert.k2.dev still only covers *.k2.dev. After issue, the mail server reloads the new PEM (no hostmail disable).
Hosted mail now listens for IMAP on 143 (STARTTLS) and 993 (IMAPS) as well as the existing submission ports. Mail.app can use 993; 443 ALPN is no longer the only IMAP door.
Mail-manage operators get the rest of the hosted-mail CLI (e2e'd on lztek.io). k2 mail … for these verbs still exits 2 and points at k2 hostmail.
k2 hostmail catchall|alias|forward. An alias is an extra address on an existing mailbox, not a new mint. Plus-tags (user+tag@) already work and are not aliases. Forward dest must be minted on this host; --keep leaves a local copy. Out of office and forward share one Sieve script — unset one leaves the other.k2 hostmail ooo (vacation auto-reply on that mailbox) and k2 hostmail footer (one host-wide outbound plain-text footer). --domain on footer is reserved.k2 hostmail list (mailing lists — not k2 mail list), spam (train Junk, allow/block sender, quarantine), queue (outbound only), acl (IMAP/JMAP share between minted users — not k2 mail access grant), autoconfig show|apply (print or plant client-config DNS).k2 hostmail app-password add|list|revoke — extra labeled secrets. Shown once. Rotating the mailbox IMAP/SMTP password does not kill them.k2 hostmail dkim show|rotate|retire and dmarc show|report-to. Rotate keeps the previous selector until you retire it. report-to sets Stalwart's report URI on a minted inbox and prints rua= to plant; it does not rewrite _dmarc.Not in this build: People hub, hide compose unless an LLM pane, skin self-serve password reset, Omarchy pacman package (release.sh still does not build one), autoconfig apply rewriting names off *.k2.dev, swapping live MX off cPanel.
v0.40.146
0.40.146 — Hosted mail cutover tools, and the extra-window crash
Hosted mail is ready to hold mailboxes before you point DNS at the box. Mail-manage agents can mint on a pending receive-only domain, import cPanel Maildirs (including Sent/Archive folders, not only Inbox), raise per-inbox quota, and rotate the one IMAP+SMTP password (k2 hostmail password rotate, and Settings → Email Hosting → Rotate next to Retire). Import waits up to two hours so large inboxes do not look failed at 30 seconds. Doctor no longer returns a fake empty success. Cert status stops lying about self-signed certificates. k2 hostmail cert renew retries ACME without a second enable. Extra LLM-tab / named-chat typecheck leftovers from 145 ship here if your 145 build missed them.
Typing in Message-the-agent on a second window should no longer abort the Mac app (nil WebKit URL on IPC). Same crash as viewing several windows.
CLI honesty: k2 workspace open/create no longer crash on empty extra args; k2 terminal spawn does not print success on an error; k2 workspace triage rejects extra args and the help says it is this workspace’s inbox list.
Not in this build: hide compose unless an LLM pane, listen on IMAP 993 (use 443 ALPN), mail aliases, skin self-serve password reset, Omarchy pacman package (release.sh still does not build one).
v0.40.145
0.40.145 — Login history, 5/5 password delay, tabs that resume
Password guessing is capped at five tries per IP per five minutes — a delay, not an account lock (there is still no forgot-password on Connect). The Worker already does this on https://. This build puts the same cap on the daemon login POST (dashboard, LAN, a raw IP) and on skin guest login. Sitting at the machine (loopback) is not capped. Unsigned tunnel login is still 404 from 0.40.144.
Settings → Logs → Access Audit shows this host’s sign-in log (k2 users audit): who got in, from which IP, when. Owner-only.
After an update, extra LLM tabs in the strip come back as that agent (claude --resume), not a login shell. Pinned Chat already did. Named chats keep the name you saved on the tab (not “grok” / “claude”).
New workspaces skip “Do you trust this folder?” for Claude, Codex, Grok, and Gemini — K2 writes the same grants those tools already use, and re-asserts them on spawn and after a daemon restart. Never your home directory. Cursor may still ask.
Adding a folder that is already a workspace says workspace already exists \
Hosted mail. Mail-manage agents get the rest of k2 hostmail (grant, doctor, approvals, import, IMAP once-password, leaf --help). k2 hostmail status matches systemd. This is the cut for lztek / it-email / Mara once this daemon is on the box.
Thread, Chatter, Project, and Feedback use Meslo. Long words wrap. Shift+Enter is a real line break. In split view, Message-the-agent under Thread gets the caret and is the default when that setting is on. Selecting Thread text should not shrink the terminal by a pixel.
Companion 3.1.1 is enough; no 3.1.2. Skin guests no longer see Chatter frames on the overlay socket.
Not in this build: dark-tunnel (the API hostname still 302s / to app.k2.dev), local workspace duplicate.
v0.40.144
0.40.144 — Password sign-in moves behind the K2 edge
Your server's tunnel address (https://) no longer serves a login page, and no longer accepts a username and password from just anyone on the internet. Those were being scanned. Password sign-in now goes through https://, which is fronted by Cloudflare and signs each login for your server; the K2 app does this for you when you connect to a .k2.dev server, and the hosted web client already lives there. Everything that carries a token — your existing desktop sessions, the CLI, terminals — is unchanged. Self-hosters without the K2 edge can set Password sign-in over the tunnel to *Any client* in Settings → K2 Connect → Policies, or turn it off entirely.
If an admin created your account with a temporary password, the K2 app and the web client now walk you through choosing a new one on first sign-in, wherever you signed in from: the server switcher, Settings → Connections, or a sign-in prompt. Opening the tunnel address in a browser now sends you to your server's app.k2.dev address instead of an account page; on the server itself the local account page still answers.
Every sign-in attempt is now recorded with time, user, outcome, and where it came from: k2 users audit. Sessions last 7 days instead of 30; the app signs you back in from your saved password. Server owners can reset a user's password from the dashboard and force a change on next sign-in.
Hosted mail. k2 hostmail status now asks systemd whether the mail server is actually running instead of trusting what K2 last recorded, and tells you plainly when the two disagree. Re-enabling after a disable really restarts the server, and a new mail hostname sticks. Owners and admins can let a specific workspace's agent turn hosted mail on and off and manage domains for that workspace; minting addresses, sign-in setup, and removal stay owner-only.
HTML file tabs, dashboard HTML panes, and HTML mail in the Inbox no longer render blank.
v0.40.143
0.40.143 — Highlight and copy in Thread
Click-drag to highlight Thread posts and copy them. Double-click already selected a word; a background poll was focusing the terminal mid-drag and killing the range. Growing the Message box and staying on the latest post after you leave and come back shipped in 0.40.142.
v0.40.142
0.40.142 — Inbox you can read, and WebGL terminals
The pinned Inbox tab is a reader, not a kanban. Left: K2 Inbox (packages from k2 inbox / k2 msg) plus any hosted or linked mail for that workspace. Middle: the list. Right: the body — markdown for K2 Inbox, text or sandboxed HTML for mail. Open a message and Chat about this sends a note into that workspace’s pinned Chat with an id the agent can k2 inbox read or k2 mail read. Stay on Inbox; it is not a mail reply. Inbox / Active / Done are no longer statuses.
Workspace Published rows show live status and PID. Details (the blue chip on the second line) opens a view-only sheet: launch command or official skin gateway, cwd, port, host. A hostname from k2 publish subdomain create in this workspace still lists here even if the tunnel map is empty (label, target if known, Details — no fake PID). Create/point/rm now fail if they cannot stamp that workspace. Unowned account hostnames stay in Settings → K2 Connect. The Workspace drawer scrolls when it overflows.
Terminals paint with WebGL by default. Anyone still on the DOM painter is moved to WebGL; DOM remains an opt-out in Settings → Terminal, and a pane still falls back if WebGL2 is missing. Reopen a terminal (or reload) so it remounts. Thread, compose, tickets, and the code editor default to 13pt (terminal was already 13). A size you already saved is unchanged.
Focus Window actually opens (⌘⇧F). Each extra window keeps its own drawers and rail. Project chips on Agents come back after you switch hosts. Right-click menus follow the cursor after Cmd+= / Cmd+−. Agent tiles no longer jump when the working spinner appears.
After an update, the Chat you had selected comes back as that agent conversation — not a plain terminal. Thread (and split: terminal + thread) stays on the latest message when you return; growing the Message box pushes the list up so the latest post stays in view.
The server switcher highlights the top match as you type; arrows and Enter pick a host. Connected Agents in the workspace drawer uses a robot-head icon.
v0.40.141
0.40.141 — Local sites in Browser, and k2 db for BYO skins
Opening http://127.0.0.1 (a local preview, k2 publish, a markdown link) no longer replaces the K2 window or crashes it. Those links open in an in-app Browser tab. The Browser tab can still load local sites on this Mac. If you are connected to a remote host, loopback in that pane is this Mac — not the server — and K2 refuses it.
k2 db migrate now grants the workspace agent on new schemas and identity sequences, not only public tables. SQL comments are not mistaken for FORCE RLS. Migrations that try to CREATE ROLE are refused (roles are cluster-wide). k2 db --test mints a disposable database that does not count against the cap. SQL helpers k2.set_principal / k2.clear_principal / k2.principal_hygiene SET LOCAL on a checkout so a BYO pool starts empty.
---
v0.40.140
0.40.140 — Project pane shortcuts follow Message agent
On a project board, ⌘1–⌘9 now follow When moving between workspaces, auto-select. If that’s Message agent, the shortcut lands in that pane’s message box — not the terminal. Terminal still focuses the grid when that’s the setting.
---
v0.40.139
0.40.139 — Skin guests can have an email for password reset
Skin Access guests have an optional email. Username is still required. Forgot-password only mints a reset when that guest has both a password and an email — then the site (not the browser) gets the address to send mail. Guests can type the username or the email on login and forgot. K2 still does not email guests. Official --skin still cannot mint or send. Grid and the terminal stay off.
Owner sets email in Skin Access or k2 skin user add --email / k2 skin user email. Empty email clears it. Guests with a password but no email cannot use forgot until the owner fills the address.
---