mnml 0.3.3
Release notes for mnml 0.3.3, the release a new user can install — the setup wizard on a first launch, one data root, and sessions you can number and take over.
mnml 0.3.3 is the release a new user can install. A first launch from your home folder now opens the setup wizard, and a build from source and an installed mnml keep one data root between them. Integrations add rows to each other's menus. SESSIONS reads Claude Code's own list of live sessions, can take one over from another terminal, and numbers its cards so one key reaches each. Claude tokens renew on macOS, Linux and Windows. A ticket key or pull request hovers with its title, from a recent-items cache the integrations fill as they poll. The terminal library and seven syntax grammars are brought current.
This release is 1 contributor over 207 commits since 0.3.2.
Highlights
Integrations add rows to each other's menus
An integration's manifest can now put rows in mnml's own right-click
menus. A row aimed at ticket, pr, pipeline or link — or at one
pane's rows, as pane:<id>:<kind> — joins the menu of every link of
that kind and of a Jira ticket row, under a muted header with the
contributing integration's name. Picking it runs that integration's
command with the clicked row's {key}, {repo}, {n}, {id} and
{url} filled in, and a when such as state=OPEN narrows where it
shows. Older manifests with a plain string target still load. The sample
integration contributes Echo ticket key and Echo pull request as the
worked example. See Menus on links.
The setup wizard on a first launch
A first launch from your home folder — the way a new terminal window opens — shows the setup wizard. Until now it showed the "where to?" picker instead, and the wizard never came; the picker returns on later launches once the setup is done. A dialog already up on a first launch, such as the workspace trust question, no longer cancels the wizard: it opens as soon as that dialog closes. See The first launch.
One data root for every build
A build from source and an installed mnml now share one data root,
~/.config/mnml, one session file and one statusline. The dev profile
is gone: MNML_PROFILE and --profile are no longer read, and the
dev chip and the [dev] window title went with them. --sandbox,
--demo and MNML_DATA_ROOT still pick a root of their own, and the
new mnml paths prints where everything lives. See
One data root.
Claude tokens renew on every system
A Claude account whose token is turned down renews it with the
account's own refresh token — every account, on macOS, Linux and
Windows — and the renewed login is written back to that account's file.
The account's line reads expired — refreshing… meanwhile; only a
refused renewal shows expired — Re-auth. Re-auth itself works on Linux
and Windows now, reading the login claude login leaves in the CLI's
credentials file. In the usage pane each account has its own state line
and its own Re-auth, and a login for another account is never filed
under the one being re-authed. See
Spend and usage.
Sessions from Claude Code's registry, and taking one over
Sessions running in another terminal are listed from Claude Code's
live-session registry as well as its transcripts: a session you named
shows that name and its exact state — busy, idle or waiting —
and one with no transcript yet is listed too. The registry is
undocumented and may change, so an unreadable entry is skipped and the
transcripts stay the listing; sessions.registry = false turns it off.
Two new verbs act on such a session. Ask what it is doing
(sessions.ask_external) sends it one message asking what it is working
on and whether it is safe to interrupt, and shows its reply as a toast
within 60 seconds (not on Windows yet). Take over…
(sessions.take_over) ends an idle or waiting session in its own
terminal and resumes it in a pane here, after a confirm. A working
session is refused, and a session that does not exit within 10 seconds
of the request is left running. See
Every session on the machine.
Sessions by number
Each of the first nine SESSIONS cards wears a muted digit to its left,
and the sessions table has a # column with the same numbers.
sessions.focus_1 … focus_9 go straight to that session —
Space a 1 … Space a 9 under vim, Ctrl+Alt+1 … Ctrl+Alt+9 under
standard — bringing up its tab page, or swapping it into the focused
column in the sessions mode. In the sessions view, plain Ctrl+1 …
Ctrl+9 do the same in both profiles; everywhere else they stay the
tabs'. See Moving between sessions.
A ticket key says what it names
Hover a ticket key the Jira integration has lately polled — in a
terminal, on a session card, anywhere it links — and it reads
ACME-123 · Fix the login redirect · In Review; its right-click menu
leads with the same line. A pull request does the same with its title,
state and author. The titles come from a shared recent-items cache that
the integrations write as a side effect of the polls they already make,
so no request is made for a hover. Recent tickets and pull requests
(picker.recent_items, Space f i under vim, Ctrl+K Ctrl+E under
standard) lists what is cached, newest first, and mnml cache reads and
clears it from a shell. recent_items.enabled = false turns all of it
off.
mnml 0.3.3 reads the cache; the Jira and Bitbucket halves that write it ship as Jira and Bitbucket 0.2.3. An mnml 0.3.4 install lists them in its Marketplace, so a 0.3.3 install upgrades to 0.3.4 to see them. See What a link names.
Dependencies brought current
The terminal library behind every shell pane, ghostty, moved 366 commits on, to its current main. Nothing changed that we could see: colour, scrollback, selection and a long prompt redrawn through narrowing and widening behave as before. Seven syntax grammars were updated: Scala, Swift, Regex, Dockerfile/Containerfile, Protobuf, OCaml and Haskell. See Built on libghostty.
Changelog
What a 0.3.2 user notices. The full list is the v0.3.3 section of CHANGELOG.md and the GitHub release.
First launch and the data root
- A first launch from your home folder shows the setup wizard, not the "where to?" picker; a dialog already up, such as the trust question, delays the wizard instead of cancelling it.
- One data root (
~/.config/mnml) and one session file (.mnml/session.zon) for every build.MNML_PROFILE,--profile, the first-launch seeding andmnml profile seedare gone. mnml pathsprints the data root, session file, IPC mailbox and running-instance marker. It replacesmnml profile; on Windows,run.ps1 paths.--versionreadsmnml 0.3.3+g<sha>for a source build, and the start page showsmnml 0.3.3 · <sha>; a release reads its version alone.
Sessions
- EXTERNAL rows read Claude Code's live-session registry for a
session's name and state;
sessions.registry = falseturns it off. - Ask what it is doing (
sessions.ask_external) and Take over… (sessions.take_over) on an external session. Take over checks the process is stillclaudeand only ever asks it to exit; it never forces one. sessions.focus_1…focus_9, with a number on each of the first nine cards, a#column in the sessions table, and the chord in the card's hover. Past the last card it says so.- In the sessions view, plain
Ctrl+1…Ctrl+9follow the card numbers. The sessions mode's oldCtrl+1…Ctrl+9counted sessions without the docked ones and could miss by one;sessions.show_1…show_9are gone with it. - A Claude Code or Codex session on the launcher dock wears its tab's look — the product's mark in the session's own colour — instead of the grey terminal glyph.
Open ×N ▸ Columnswith something already on the page leaves it the width the first session's split gives it and shares only the rest between the N sessions; an open editor is no longer squeezed into an equal column.
Claude accounts
- Each account in the Claude usage pane has a state line under its
name —
signed in · resets 3:20am,expired,keychain holds another accountorno login yet— with a Re-auth button where it needs one. Re-auth is also on the account's right-click menu, the Claude chip's menu andai.claude_reauth. - Re-auth opens
claude loginin a pane, watches for the login, and files it under the account when its email is that account's. The separateRcapture step is no longer needed. - A login for another account on file is never filed under the one being re-authed: a box says whose it is and offers File under that account, or Cancel.
- An expired account is re-captured on its own when the keychain holds that same account's login again, with one toast.
- Tokens renew with the account's refresh token on macOS, Linux and Windows; on macOS the keychain is tried first when it holds that account's login.
- Re-auth works on Linux and Windows, reading the CLI's credentials
file (under
~/.claude, orCLAUDE_CONFIG_DIR). - Pasting a token by hand moved behind the account menu's Advanced ▸ Paste a token…; adding an account no longer opens it.
- The compact meter's warning account shows its letter and percent in
yellow or red on the chip's coral, then a
!. The hover names the account and why; a click on a chip with a!opens the usage pane at that account.
Claude Code's review and worktrees
- A session's proposed change is drawn by the git panel's diff view,
with the same Hunk / Inline / Split toolbar, cycled by
t. Until you pick a view, a pane at least 80 cells wide opens in Split and a narrower one in Hunk. Each hunk header says[✓ accept]or[ skip ]. Y, the header's Accept all chip, orai.apply_accept_allaccepts every hunk and applies them in one step. Space orastill toggles one hunk.- The review no longer covers the session that asked for it: it opens
in the split holding the file, else an editor split, else a new split
beside the session, and accepting, rejecting or Esc puts the focus
back on the session.
ai.review_placement(.editor,.beside, or.tabfor the old placement) and a row in Settings ▸ AI choose. See What the session can do. - A session started in a worktree of its own gets it in a shared
.worktreesfolder beside your repository, one folder per repository: a repository at~/code/appputs its trees in~/code/.worktrees/app/<name>. A repository at the top of a disk uses~/.worktrees/app/<name>. - Existing worktrees stay where they are and keep working. To keep the
old
<repo>-worktreesfolder, setai.default_worktree_rootto"../app-worktrees"with your repository's name in place ofapp. See A worktree per session. - A worktree name is one folder name: letters, digits,
-,_and.. A name with/is refused with the reason.
Links and the recent-items cache
- A ticket key or pull request that is in the recent-items cache hovers
with its title, and its right-click menu leads with the same line. An
old or failed poll keeps the title and adds
as of 3h ago. - Recent tickets and pull requests (
picker.recent_items) lists the cache newest first, a stale entry marked; Enter opens it where its link would. mnml cache get <kind> <id>,mnml cache ls <kind> [--source S] [--limit N]andmnml cache clear [kind] [--yes]read and clear the cache from a shell.recent_items.enabled = falseturns the cache off: mnml reads none of it, and the integrations it starts write none.recent_items.current_releasenames the release the cache callscurrentoutright, instead of the nearest unreleased release date.- A bare
Pull request 5505,PR #5505orpipeline 10554links to the repository whose numbers hold it, from ranges the Bitbucket integration publishes, allowing 50 above the highest. With several candidates the menu listsOpen in <repo>for each; with none, no link. See Pull-request references. - What the cache holds is the shape of the record — key, summary, status, assignee's display name, priority, type and fix versions for a ticket — and never a description, an account id or an email.
As with the hover titles, the Jira and Bitbucket side of the cache and of the bare-number ranges ships as Jira and Bitbucket 0.2.3, which an mnml 0.3.4 install lists in its Marketplace.
Integrations and the SDK
- A manifest's
context_menu[]rows reach mnml's menus, as above. - The SDK's confirm box (
confirmBox) let a click on its OK or Cancel chip land on the box behind it, so neither did anything; Jira's and Bitbucket's merge confirms both had it. The chips now win. - A mounted pane's hover can name the command its element's click runs
(
Help.runs(id)andMount.hoverHelp), and the info view then ends with that command'sKey:chord, as mnml's own controls do. sdk.cache:put,failed,getandqueryover typedTicket,Pr,PipelineandReleaserecords, with the file format documented as a contract.- A
links[]entry may resolve against published ranges (.resolve = .range) and put{repo}in its address;Ipc.linkRangespublishes the table it reads. sdk.pane.columns.fittakes each column's longest visible cell and afixedflag, so a wide pane gives its spare width to the columns being cut instead of leaving it blank. A narrow pane gives way as before.- mnml hands every integration it starts its installed manifest's chip
glyph as
$MNML_CHIP_GLYPH, and a segment can write{chip}in its resting text for it. Installing an integration whose segment rests on a different private-use glyph than its chip now warns, naming both. - The Jira Work chip's icon is Atlassian's work-items card with a
check, baked into
MnmlSymbols.ttfatU+F1C19; run./run.sh install-fontto pick it up.
The SDK is documented in
docs/SDK.md.
The Jira and Bitbucket changes in this list — the measured tables, the
confirm fix, the chip glyph — ship as Jira and Bitbucket 0.2.3, which an
mnml 0.3.4 install lists in its Marketplace.
Tables and tab strips
- A table no longer cuts a name with
…while the right of the pane is empty. The requests log, the git graph's author and branch, a request's header and parameter tables and the Files listing follow the same rule. - A narrow pane keeps its tab's close button. The pager goes first,
then the
+; only then is the tab's name cut, down to six cells, and after that the pane buttons go from the left. The close is the last thing to go.
The statusline
- Right-click the statusline between its chips for Segments ▸: every
segment, ticked while shown. A row hides or shows its chip at once and
writes
.statusline.hiddento the home config. RESTRICTED and the sandbox chip never hide. - Every segment that can move ends its menu on Move left / Move
right, and the row's own menu has Reset order; the order is written
to
.ui.statusline_segment_order. A chip that had no menu of its own gets one. - A theme can colour the segments:
statusline_lsp,statusline_wrap,statusline_languageand eleven morebase_30keys, each falling back to the colour the segment wore before. - The session pager has a ground of its own (
statusline_pager), with its arrows and count in the dark ink the other coloured chips use. - The bell's right-click marks the unread warnings read and copies the last message or the whole log; the mode chip's offers Toggle keymap.
- The spinner is eight-dot braille and sits on the text's centre.
mnml --demopins the Jira and Bitbucket launchers to the activity rail.
Keys and hover help
- Under vim, an Alt chord the keymap binds beats the menu bar's
Alt+letter:
Alt+Hfrom an editor toggles NvChad's scratch terminal instead of opening Help, andAlt+Rtoggles regex search instead of opening Run. Unbound Alt letters still open their menus; standard keeps every letter for the menus, as VS Code does. - A button, chip, rail icon, launcher dock entry, menu or palette row
whose click runs a command shows
Key: …right under its info-view entry's title — that command's chord in your profile. See TheKey:line. - A menu row that only says something, such as the sidebar divider's
Width: 42 cells · 21%, is its own help instead of no help written yet. - The sidebar divider's right-click menu opens with the column's width, in cells and as a share of the window; the keyboard cursor starts on the first row below it.
Fixes
- The now-playing chip's Beatport mark is in the
MnmlSymbols.ttfmnml ships and installs; with the 0.3 face it showed a blank. - OCaml gains the OxCaml keywords and types and no longer paints a
#!first line as a comment; Haskell paintscasesas a keyword.
Tooling
.testscripts can click with a modifier:click X Y ctrl(orsuper,alt,shift).
Upgrading
Homebrew, winget and the installers move you to 0.3.3 on your next upgrade:
brew upgrade mnmlwinget upgrade ChrisMcLennan.mnmlOr run the installer for your platform again, from Install. winget is Microsoft's community repository and merges each version on its own schedule, so 0.3.3 can reach it some time after the other channels.
0.3.3 no longer reads ~/.config/mnml-dev, or a workspace's
.mnml/session-dev.zon. If an older build from source left them behind,
they are ignored: delete them, or move what you want from them into
~/.config/mnml, by hand.