Release notes

What’s new in Nori.

Every release of Nori, newest first. Updates install from the app, and every update is included with a licence. Follow them with the RSS feed.

Nori 1.9.0

Added

  • Choose the code font, size and ligatures for file diffs, blame and the inline conflict resolver in Settings ▸ Diff. Nori includes familiar monospaced fonts and can use fonts installed on this Mac.
  • Show author pictures in History and commit details, with initials as the fallback. Settings ▸ Appearance offers None, Initials and Avatar; pictures load only when Avatar is selected.

Changed

  • The ambient background follows the open repository's marker color, with a smooth transition when switching repositories.

Nori 1.8.1

Fixed

  • Buying Nori from the app unlocks this Mac at once: no License Key to paste, no second email.

Nori 1.8.0

Nori holds a fifth of the memory it did: on git/git (82,000 commits), 99 MB at rest instead of 523 MB.

Changed

  • The sidebar builds only the branch and tag rows on screen: −180 MB on a repository with 1,000 tags.
  • The diff page loads when a diff is about to open and is released 3 minutes after the last one closes: no WebKit process until then, −120 MB at rest.
  • The ambient background is drawn from small images (−80 MB), and the History graph keeps its colours and edges in a fraction of the space (−50 MB on wide graphs).
  • The app is 31 MB installed instead of 57, and an 11 MB download instead of 14.

Fixed

  • Updating no longer asks for keychain access several times at launch: licensing state lives in a private file, and this update asks at most once.

Nori 1.7.3

Fixed

  • The title bar counts the Trial's days left instead of showing Unlock Nori, and shows nothing once a License is active.
  • Pushing to the remote's default branch no longer offers to open a pull request.

Nori 1.7.2

Fixed

  • Start 14-day Trial stays offered after Nori's first licence check; it used to disappear on a new Mac.
  • No more Renew links: every update is included with a License.

Nori 1.7.1

Changed

  • Nori starts a 14-day free Trial on first launch, then needs a License: US$40 once, two Macs, every update included.
  • While purchases are not open yet, Buy says so instead of reporting an error.

Nori 1.7.0

✦ AI explains commits and diffs, proposes conflict resolutions and summarises requests for review; ⌘K searches the whole history; branches and commits drag and drop. This release also closes the data-loss and security issues found before the public launch.

Added

  • ✦ Explain for a commit or a diff (whole file or one hunk), ✦ Suggest resolution per conflict hunk, and ✦ Summarise for review in Reviews ▸ Overview (never posted); per-use switches and a shared Max context size in Settings ▸ AI.
  • History search in ⌘K across the whole history, with author:, path:, content:, regex:, before:, after:, between: and hash: filters, a calendar and value completion; Show only these in the graph filters History, 200 per page up to 10,000.
  • File history (⌘⇧H, 100 commits per page up to 2,000, across renames) and blame (⌘⇧B).
  • Drag and drop of branches and commits in the sidebar and the graph: merge, rebase, new branch, cherry-pick, revert or push at the drop point.
  • Checks: a summary bar, required checks listed as Expected, annotations that open their line, GitLab trigger jobs, Re-run job and Re-run failed jobs, a 30 s refresh while running, counts on the list badge and in the Push menu.
  • An External editor setting (Xcode, VS Code, Cursor, Zed, Sublime Text, Nova, BBEdit, JetBrains IDEs, any app): Open in <editor> ⌘⇧E and Open Repository in <editor> ⌃⌥E.
  • App-wide zoom, ⌘+ and ⌘− from 80 to 150 %, kept across relaunches.
  • File ▸ Open Repository… and Open Recent; a folder dropped on the Dock icon or given to open -a Nori opens as a repository.
  • Nori ▸ Check for Updates…, release notes in the update window, and a Help menu: website, release notes, Report an Issue (on GitHub), keyboard shortcuts, diagnostic report, privacy policy and terms.
  • Acknowledgements for the open-source software Nori includes, in About Nori.
  • Recent crash and hang reports in the exported diagnostic report; nothing is sent.

Changed

  • Nori's bundle identifier is now app.meetnori.nori (was com.nori.desktop): settings, tabs and recent repositories carry over; macOS asks again for notifications and folder access.
  • Nori checks for updates automatically, once a day, unless Settings ▸ Updates turns it off; installing stays your call.
  • ✦ AI tools run in a private empty folder with their tools off, never inside the repository.
  • Git and its hooks get the login shell's PATH, proxies and SSH agent: nvm, volta, asdf, mise, fnm and MacPorts tools resolve as in Terminal.
  • Automatic fetch gives way to anything you start, waits until the last fetch is one interval old, backs off up to an hour after failures and never posts a notification.
  • Quitting while a push, rebase or other Git action runs asks first.
  • A push refused because the remote has someone else's commits offers Pull, which rebases your commits on theirs, not Force push.
  • Errors stay on screen until dismissed with ✕ or esc.
  • Settings ▸ Shortcuts lists every shortcut, and ⌘K shows the keys the menus actually bind.
  • Reviews says comments are public as soon as you send them, in the composer and in Submit Review.
  • Reviews offers glab for GitLab remotes and gh for GitHub, connects every signed-in account (github.com and Enterprise side by side), says Merge Request on GitLab, and binds a remote only to an identity on its host, starting on upstream.
  • Push & PR from a fork with an upstream remote opens the request on the parent; on a GitLab remote it reads Push & MR.
  • Merging asks first when commits were pushed after you opened the request.
  • Reviews waits for a spent rate limit to reset, and backs off up to 15 minutes after repeated failures.
  • Merge bar: Checks block only on required checks the forge names; Approvals count against the required number, 1 of 2.
  • The Checks tab lists failures first with completion times; GitHub checks are read up to a thousand; GitLab manual jobs count as neutral; Origin says checks are unavailable.
  • An Overview contributor click adds that author to the History filter.
  • Stash is back in the top bar, beside Branch: its panel pops, applies or drops a saved stash even with a clean working copy.
  • Git 2.36 is the minimum version.

Removed

  • Removed syntax colouring for Ada, AutoHotkey v2, gnuplot, nginx, Org and Racket files, and the Aurora X theme: their grammars are GPL-licensed. Those files show as plain text.

Fixed

  • Fixed ✦ actions running a repository's own Claude Code hooks, settings and MCP servers.
  • Fixed Push & PR publishing a file outside the repository when a pull request template was a symbolic link.
  • Fixed Open in Default App running scripts, apps and installers from a repository; they open as text or in Finder.
  • Fixed Force push overwriting commits a background fetch had brought in.
  • Fixed the branch menu's Push sending a branch started from origin/main into main, and the upstream dialog offering to delete origin/main.
  • Fixed interactive rebase dropping commits made after its plan opened.
  • Fixed checkout of a deleted branch wiping edits to a file of the same name, stash Drop, Pop and Apply acting on the wrong stash, and remote branch deletion removing commits pushed since your last fetch.
  • Fixed a branch being deleted when its Undo snapshot could not be saved.
  • Fixed Undo snapshots, discarded untracked files included, leaving the machine with git push --mirror and showing in git log --all: they now live outside the repository, existing ones move there when it opens, and those of repositories never reopened go after 31 days.
  • Fixed stage and discard acting on the wrong file when a repository's subfolder was opened.
  • Fixed empty diffs and failed partial staging under Git's color.ui, diff.noprefix or apply.whitespace.
  • Fixed a commit or push hanging when a hook left a background process running.
  • Fixed blame on file names outside ASCII.
  • Fixed unknown SSH hosts, an unaccepted Xcode license and missing Command Line Tools being reported as credential failures.
  • Fixed Reviews listing only the first 100 files of a GitHub pull request; up to 3,000 now.
  • Fixed a lost connection leading to a comment, reply, review or merge being sent twice: Nori offers Check if posted.
  • Fixed Reviews' Forget keeping the account's cached data and reconnecting it at the next scan.
  • Fixed Reviews and Push & PR for SSH remotes using a ~/.ssh/config alias or a non-standard SSH port.
  • Fixed one unreadable item (SAML, a missing token permission) blanking a whole Reviews screen.
  • Fixed an unreadable Reviews store locking Reviews out: it is set aside and a fresh one opens.
  • Fixed the open request no longer refreshing after Nori came back from the background, and a hidden tab's Reviews still polling.
  • Fixed "Reconnect required" staying after signing in again, and a new sign-in waiting 30 s after a 401.
  • Fixed GitLab conversations showing the oldest 50 discussions, GitLab lists stopping at 100 requests, and GitHub Changes and Commits stopping at 100.
  • Fixed Origin accounts never connecting.
  • Fixed files with an empty diff showing a loading skeleton forever.
  • Fixed a crash expanding context in GitLab files with accented names.
  • Fixed the status bar tooltip showing credentials stored in a remote URL.
  • Fixed the diff surface keeping every document it drew in memory, and closed tabs staying in memory.
  • Fixed home screen errors not showing, and "git not found" flashing at launch.
  • Fixed tabs on a disconnected drive being forgotten at launch.
  • Fixed VoiceOver reading shortcut symbols as part of button names.
  • Fixed the notification permission prompt appearing at first launch.

Nori 1.6.0

Reviews is back, in the V4 redesign, “Depth”: three planes, one top bar, branch colours that belong to the branch, and an undo for everything local. A branch goes from push to Pull Request in one click, and Overview shows the whole repository at a glance.

Added

  • Added Reviews back to every build: the Git | Reviews picker, the Review menu, ⌃⌘G/⌃⌘R and the Connections and Storage settings, off since 1.0.0.
  • Added Push & Pull Request: push the branch, write the description from the repository's template with your AI tool, open the request on GitHub or GitLab. It is the primary push action when the remote is a connected forge with no request open on the branch.
  • Added Overview (⌘0): a commit timeline with branch lanes, activity, contributors and release markers; a lane or a span filters History to it.
  • Added universal undo: commit, undo commit, branch deletion, stash drop and every discard keep a snapshot under refs/nori/undo, an 8 s toast offers Undo (⌘Z outside a text field), and Operations (⌥⌘Z) keeps 30 days of them.
  • Added the Reviews merge bar: Checks, Approvals, Threads and Branch, Blocked by N or Ready to merge, and a merge menu with a prefilled squash message.
  • Added the working-copy row's Stash and Review & commit buttons, and a pulse ring around HEAD.
  • Added squash merge without a sheet when the repository allows only that, rebase onto the target branch, replies to the general conversation, folding of anchored discussions, and a resizable request list.
  • Added revealing a branch tip on the graph, from the sidebar or ⌘K, without checking it out; older history loads until the tip is on screen.

Changed

  • Changed the window to one 48 pt bar — tabs, then Search ⌘K, Branch, Fetch, Pull, Push and Undo at the right — over a far plane, with content in a bordered card and the right panel floating on History, docked beside a diff. The current branch heads the sidebar, so a long name leaves the tabs their room.
  • Changed branch colours to follow the branch: nine hues, persisted per repository, main in mint and origin/x in x's colour, in the graph, the refs and the sidebar alike.
  • Changed navigation to Overview ⌘0, History ⌘1, Reviews ⌘2 in the sidebar; the conflict sides move to ⌃⌘1 / ⌃⌘2.
  • Changed Reviews tabs to Overview · Changes · Commits · Checks, with All · Unviewed · Threads filters and resolved conversations folded to one line.
  • Changed Settings ▸ AI to list the versioned models each CLI actually offers; old aliases move to their current model, an explicit choice is kept.
  • Changed Claude commit messages to skip extended thinking, which made them slow.
  • Changed commit messages in the detail view to reflow to its width; lists, code, quotes and trailers keep their lines.
  • Changed the conflict resolver header to show each file's directory.

Fixed

  • Fixed Push after a local rename updating the old remote branch and reporting success: it opens the upstream dialog on the new name, with the old remote branch's deletion ticked.
  • Fixed an open diff going stale when a file that was already modified changed again on disk.
  • Fixed opening a diff waiting for the commit hooks of a commit in progress.
  • Fixed amending with nothing staged being refused.

Nori 1.5.0

A mark of your own on every repository tab, pinned tabs that stay put, force push from the toolbar, and a commit box redrawn around what it is about to do.

Added

  • Added repository markers: Settings ▸ Repositories gives each repository a dot, a one- or two-letter monogram, one of eight symbols, or an image of your own, in one of six colours. The marker takes the dot's slot on the tab and in the recent list, and a repository shares it with its linked worktrees.
  • Added pinning to repository tabs: hover the leading dot, click the pin, and the tab joins the pinned group at the leading edge. Pins and their order survive a relaunch, and a drag reorders within its group only.
  • Added Force Push… to the toolbar's Push menu, with the same lease and confirmation as before. It is offered only when the branch has an upstream.

Changed

  • Changed the commit box to a card: the staged facts as chips, the commit flags as pills, one prominent commit action. The ✦ button stays visible with no AI tool configured and opens Settings ▸ AI instead of disappearing.
  • Changed ⌘N to open the toolbar's branch panel, with its base and checkout choices, instead of a separate sheet. Every way of creating a branch now checks it out, as the toolbar always did.
  • Changed light-theme sheets, popovers and dialogs to draw opaque: the scrim behind them no longer bleeds through as a grey haze.
  • Changed sidebar section titles to the text colour, on one line: the divider gives up its width first when the pane is narrow.
  • Changed a line break typed in a commit subject to fold into a space; the 72-character limit still holds.

Fixed

  • Fixed pushing a branch without an upstream from its badge menu ending in an error: it opens the upstream dialog the toolbar button already offered.
  • Fixed the name field of the branch and stash panels sometimes not taking focus when the panel opened.
  • Fixed the syntax highlighting arriving late, and in the wrong palette, on every file after the first: closing a diff terminated the page's worker pool, so each file paid a cold Shiki and never got the chosen theme. First token at 31-75 ms instead of 209-285, on a two-line diff.
  • Fixed the review Overview freezing the window while scrolling a long conversation: the page's lazy stack realised and dropped the rows below the viewport on alternate passes, forever, at 100 % CPU. The page is a plain stack now — every body on it is bounded, so it lays out once in a few hundred milliseconds.

Nori 1.4.0

Commit messages written by an agent CLI you already have, staging down to a single line, and a diff canvas that draws only what is on screen: 253,000 lines open in 0.2 s and hold 0.5 GB, where they took 4.4 GB and never finished.

Added

  • Added Generate to the commit box: a commit message written from the staged diff by an agent CLI you already have — Claude Code, Codex, Gemini, Cursor, or your own command. Nori integrates no API and stores no key; Settings ▸ AI picks the tool, the model and the writing style. claude --model claude-haiku-4-5 answers a small diff in about ten seconds.
  • Added Rename branch… to a branch's menu, in the sidebar and on the graph's badges: the upstream, the reflog and a worktree holding it follow, and so does the graph pin.
  • Added cloning to the home screen: paste a URL, pick where it lands, and the repository opens in the tab — no terminal detour on the way in.
  • Added a Hunks presentation beside Unified and Split: a bar above each hunk with its @@ header and one button to stage or unstage it whole.
  • Added staging and unstaging a single line, or a selected run of them, from the diff's gutter, which now carries both line numbers — the old side, the button, the new side. A replaced line moves as one: taking the new half without the old would leave both in the index. The patch is rebuilt from a fresh git diff at the moment of the click, so a file written since it was drawn is refused rather than half-applied.

Changed

  • Changed the diff canvas to draw only the rows being read: a 253,000-line file now opens in 0.2 s and holds 0.5 GB, where it took 4.4 GB and never finished.
  • Changed a closed diff to release what it was holding: browsing twelve large files in turn settles at 0.4 GB instead of climbing to 2 GB.
  • Changed large files to be drawn as consecutive slices, which is what finally syntax-highlights them: colour in 1.5 s on a 150,000-line file, where a whole document took over two minutes at 80,000 lines and was refused past 100,000.
  • Removed the prepared-diff caches, and the page a heavy diff was drawn in is thrown away when that diff is closed: the memory goes back to the system instead of being held for files nobody has open.

Fixed

  • Fixed the tooltips on the icon-only controls taking almost two seconds to appear: on the diff header's picker the tooltip is the label, so it now appears in 100 ms.
  • Fixed one huge diff wedging the shared web surface: every diff opened afterwards drew nothing until the app was relaunched. A render that goes unanswered for 15 s now rebuilds the page and redraws the file, and a patch over 16 MB is offered rather than sent.

Nori 1.3.0

Merge and rebase say which branch goes where, and a cancelled Git command no longer locks a repository for good.

Changed

  • Changed the branch menu to name both branches: Merge B into A, Rebase A onto B, falling back to the bare verb where there is nothing to name.

Fixed

  • Fixed a Git command cancelled before it started keeping the repository's exclusive key: every later refresh and mutation waited on it, the tab never loaded again and the status bar held working for the life of the process.

Nori 1.2.0

Changed files are read as a tree, a branch badge opens the worktree that holds it, and an update is never staged behind your back.

Added

  • Added collapsible directory trees to the changed-file lists, with stage/unstage on a whole directory and per-pane collapse state.
  • Added Open worktree on double-click of a branch badge already held by a linked worktree, where Checkout is disabled.

Fixed

  • Fixed an update downloading and staging itself with no prompt: a stale SUAutomaticallyUpdate left in preferences is now cleared at launch.
  • Fixed a path that is both a file and a directory losing its subtree, and staging a directory dropping renames that cross its boundary.
  • Fixed the development build showing placeholder version numbers instead of the one in VERSION.

Nori 1.1.0

Branches and tags get their own column, the sidebar picks up more than one row, and a remote branch can finally be removed from the server.

Added

  • Added a dedicated refs column ahead of the graph: one badge per row, the rest folded into a +N chip that unfolds on hover. Double-click checks out, right-click opens the menu.
  • Added Remove branch from remote, on a branch or a whole remote folder. It runs git push --delete, and offers the local copy as an unticked option.
  • Added multi-select across branches, tags, worktrees and working-tree files, with grouped delete and discard.
  • Added a context menu for the stash row: pop, apply, show contents, copy hash or message, drop.
  • Added Open worktree and Reveal worktree in Finder to a branch already held by a linked worktree, whose Checkout is now disabled rather than refused by git.
  • Added T3 Code and Claude Code as worktree attribution providers, beside Codex.

Changed

  • Changed a click anywhere in the window to end a row selection, except the clicks that build the run (Cmd/Shift) or act on it.
  • Changed the graph's leftmost lane to follow the branch furthest ahead when nothing is pinned.

Fixed

  • Fixed auto-fetch stopping in unfocused windows, and running on despite the interval being set to Off.
  • Fixed confirmation dialogs not accepting on Return.
  • Fixed linked worktrees showing up in recent repositories.
  • Fixed the compact scroller reverting to the legacy style, and the working-tree file list resetting its scroll position on every change.
  • Fixed selection waiting on the double-click interval.

Removed

  • Removed remote branch deletion that only dropped the local remote-tracking reference — the branch stayed on the server and came back on the next fetch. git fetch --prune is what removes those references.
  • Removed the Git console toggle, its ⌃` shortcut, and its entries in the command palette, main menu and settings.
  • Removed worktree creation from the new-branch menu.

Nori 1.0.1

A window doing nothing used a third of a core. It now uses none.

Fixed

  • Fixed an idle window sitting at 34% CPU. The early-access pill's sweep was a SwiftUI repeatForever, which never completes: the whole window re-rendered at the display's rate for as long as the pill was visible. The sweep runs on Core Animation now, and an idle window measures 0%.
  • Fixed graph junctions landing one lane away from the line they join once the graph column had been scrolled sideways.
  • Fixed a file diff going blank instead of reporting a render failure, and a syntax theme the catalogue no longer knows leaving the settings picker on an empty row.

Removed

  • Removed the pulsing ring around the HEAD node. It cost a redraw and a display cycle thirty times a second to repeat what the branch badge on the row already says.

Nori 1.0.0

Nori 1.0.0 is the local Git client, and only that.

Changed

  • Changed Reviews to ship off. The Git | Reviews picker, the Review menu, ⌃⌘G/⌃⌘R and the Connections and Storage settings sections are absent, and no review store is opened at launch. The surface stays in the tree, built and tested, behind NoriReviewsEnabled in Info.plist (NORI_REVIEWS_ENABLED=1 for development builds).

Nori 0.10.3

Reviews cannot reach GitHub in a packaged release. This release is that fix.

Fixed

  • Fixed Reviews being unable to ask GitHub for a single Pull Request in every packaged release. The workflow never passed the OAuth App credentials, so the packaging skipped the two Info.plist keys in silence — the release now reads them back from the built bundle and stops without them.

Nori 0.10.2

0.10.1 does not open. This release is that fix.

Fixed

  • Fixed the application trapping at launch on every machine but the one that built it. The diff surface read its resources through Bundle.module, whose only fallback is the absolute .build path of the build machine — baked into the shipped binary as /Users/runner/… — and which crashes rather than reports when it finds nothing. The packaged resources are read from Contents/Resources, where the packaging has always put them, and a miss is logged as it already was.

Nori 0.10.1

Nothing changes in the application. The release pipeline does.

Changed

  • Changed the release to build each configuration once. swift test -c release and swift build -c release shared a build directory but not -enable-testing, so each invalidated the other: 100 s and 49 s of pure recompilation, every run.
  • Changed the suites that wait on a real repository, and the ones that measure a duration, to run on a machine of their own rather than beside the thousand others where their budgets reported the load. They were being skipped and then replayed in seven further swift test invocations on the same runner; that list is gone.
  • Changed the release into five concurrent jobs. 5 min 13 s, against 12 min 53 s for 0.9.0 and 10 min 28 s for 0.10.0 — and for 14 runner-minutes rather than 13, because what the concurrency costs the removed recompilation gives back.

Nori 0.10.0

Two things arrive together. Forge Reviews, whose foundation shipped switched off in 0.9.0, is now a mode of the window: a GitHub pull request is read, discussed and acted on inside Nori, without the local checkout being touched. And the diff canvas is no longer Nori's own — code surfaces render with @pierre/diffs in a WKWebView, which is the one platform exception this project has taken, recorded in docs/adr/0032-render-code-surfaces-with-pierre-diffs-in-a-webview.md. It brings sixty-five syntax themes generated from Shiki, and it costs applying a hunk from the gutter, which no longer has a surface to be offered on.

Added

  • Added Reviews as a mode reached like every other one, rather than behind a default that was absent by default and documented nowhere.
  • Added navigating a request by the tabs both forges give one — Overview, Commits, Checks (Pipelines on GitLab) and Files changed (Changes). The way in used to be an action inside a section that collapses when review is not blocking, so a request needing no review opened onto no file and no visible route to one. Each tab keeps its state across a round trip and reads its own data when it first opens.
  • Added a request's whole conversation, read at its end rather than at its opening. Labels, assignees, milestones, cross references, locks and the commits themselves now arrive; consecutive pushes by one person fold into a single row, and a comment landing between two of them breaks the run. Each entry carries its reactions, whether it was edited, and a link to itself on the forge.
  • Added the anchored discussions to that conversation, filed under the review that opened them. A review with an empty summary and its whole substance on lines used to render as a count where the text was.
  • Added drawing discussions in the code, as annotations of the diff canvas at their own line: a line thread on its line, a range on its last line, a whole-file remark and an outdated thread above the first hunk, where the file is all the placement claims.
  • Added editing a request's metadata where the provider grants it — assignees and labels as immediate mutations verified by re-reading.
  • Added assign yourself as a button rather than a sentence: one click, one mutation, and it adds without replacing whoever is already assigned.
  • Added requesting reviewers, with the request's own author left out of the picker because GitHub refuses to solicit them.
  • Added opening the context a review's patch left out. 12 unmodified lines and Show the whole file did nothing there; the bytes now come from the forge's own API, which keeps Reviews off the local checkout.
  • Added walking a request's changed files, reading the exact provider diff of one at a time, and tracking viewed state, with every line a keyboard target that announces its path, side, number and content.
  • Added the sixty-five syntax themes Shiki publishes, generated at build time from the same source the canvas renders with, instead of sixteen palettes copied by hand.
  • Added a side-by-side and an inline presentation to the conflict resolver, both driven by the shared web surface.
  • Added Settings to the window tab strip, reachable from every mode. It lived in the Local Git context bar, so switching to Reviews left ⌘, as the only door — for an app whose forge connections live behind it.
  • Added opening a collapsed band of context in the diff, and showing the whole file in its final state rather than after a visible reorganisation.

Changed

  • Rendered every code surface with @pierre/diffs in a WKWebView, and deleted the native canvas rather than keeping it as a fallback. One long-lived webview is shared by the working tree, commit, stash, review and resolver surfaces; tokenisation runs on workers instead of the web content process's main thread, and the first diff's fixed costs are paid at launch instead of on the click.
  • Gave the review surfaces a page measure of 1 600 points, centred past it. The old cap of 1 100, leading-aligned, put a request in the left quarter of a wide window with two thirds of the screen empty beside it.
  • Raised every text role one step on those surfaces, together, so the hierarchy is unchanged. Density is worth something in a file tree and nothing in a paragraph, and a review is mostly paragraphs. A conversation event's content also moves to the primary ink; only dates stay quiet.
  • Moved Mark resolved into the resolver's header, beside the picker.
  • Raised the toolbar's available actions and dropped the menu's accent tint.
  • Folded a file's action bar into its own header, and gave each review pane one control plus Collapse all.

Removed

  • Removed applying a hunk from the gutter, and with it the second copy of every diff it forced — PreparedDiff held the patch Git wrote and one patch per hunk. No surface has offered the action since the native canvas went.
  • Removed the discussion inspector. It was an index of discussions that are now drawn at their own lines, and a third pane around the column the tab exists for. Submit Review… moves to the foot of the file pane so a reviewer is not left on the one surface with no way to finish.
  • Removed devibeans and srcery, which Shiki has no equivalent for; a stored selection naming one falls back to the default theme.
  • Removed opening a single gap of context, which is now the all-or-nothing Show the whole file setting.

Fixed

  • Fixed the diff blinking on any refresh that touched Git's metadata — the index, HEAD, the refs, all of which Nori's own git status rewrites. GitFileDiff.id was a UUID minted per instance, so the identity of the view depended on the lifetime of a cache; a loading placeholder was drawn over a diff already on screen; and a surface going away disarmed the one replacing it, which also left an expansion waiting forever and a fold doing nothing.
  • Fixed a page render painting over the surface that replaced it, when Show the whole file made it wait on Git before its first paint.
  • Fixed the review diff pane being blank for every file. GitHub's REST patch begins at the first @@; a renderer that parses a unified diff needs the diff --git header to know where one file ends, and to name the file the language is inferred from. Nori writes it from the paths the change carries.
  • Fixed the conflict resolver reading markers Git did not write, writing picked lines in an order other than the one they were picked in, refusing a side that adds nothing, and losing the bytes read from disk across an inline accept.
  • Fixed search listing commits before branch names.
  • Fixed amending reloading only a commit message's body, not the whole message.
  • Fixed the graph showing more than one row per stash.
  • Fixed a worktree name being cut short of the sidebar's edge, because the removal button reserved its column whether or not it was drawn.
  • Fixed an unmerged path being treated as a status rather than as unmerged.
  • Fixed the review side columns taking a lighter role than the same column in Local Git, and blending with the desktop behind the window.
  • Fixed the request list staying hidden when its coordinator bound after the view had opened.
  • Fixed the readiness actions Nori cannot run yet being offered as if it could.
  • Fixed the file selection landing somewhere other than the first file the selection lives in.
  • Fixed the diff asking the model which file it was drawing rather than the surface, and naming its trailing band for something other than what it does.
  • Fixed offering hunk separators whose expansion would remove context, and said which of the four can be expanded.

Nori 0.9.0

This release sharpens the surfaces the redesign introduced — the diff, the conflict resolver, the graph and the home screen — and fixes a family of defects where Nori asked Git for one thing and displayed another.

Added

  • Added a repository to Nori from the home page, rather than only from the menu.
  • Added cherry-picking a commit from its context menu in the graph.
  • Added taking a whole side of a conflict at once. Doing it used to cost as many clicks as the conflict has lines, and the one broad action — All — in fact applied only to the conflict under the pointer. Each scope now sits where it acts: a column header checkbox for the entire file, which shows when that side is already taken and gives it back on a second click.
  • Added a scrolling tab row on a raised titlebar, so a window with many repositories stops compressing them.
  • Added deferring the automatic fetch while a rebase, merge or cherry-pick is in progress, instead of fetching under a sequencer that has not finished.
  • Added folding the Git console's raw log behind its diagnosis, so a failed command leads with its cause.

Changed

  • Gave the code canvas to the syntax theme. The diff mixed two settings: its syntax colours came from the code theme and its bands composed against that theme's background, but the background actually painted came from the window appearance. In light appearance with a dark theme, a changed line stood out black in the middle of a white file, and the code was drawn in colours calibrated for a background it did not have. The diff, the resolver, the change ruler and the pinned header now all take the code theme's background.
  • Coloured branch reference badges by their lane in the graph, so the drawing and the inspector agree. Local and remote branches now differ by glyph — a fork against a cloud — rather than by colour.
  • Retired the author column and its avatars from the graph, returning the width to the message.
  • Dropped the staged rail from the working tree, and gave the sidebar and the graph one branch menu instead of two.

Fixed

  • Fixed Expand context returning the unexpanded patch. Neither diff cache key carried diffContextLines, though it was passed to Git, so after a first open the cache answered with the original patch: the control promised a number of lines and delivered none. Because the revision cache is only cleared when the repository changes, this lasted a whole session. Four related defects shared the same cause — an input handed to the producer without being carried by what identifies its result.
  • Fixed the appearance being pinned to the window rather than the application, which let one window disagree with the rest.
  • Fixed the All button in the resolver selecting a single conflict instead of every conflict.
  • Fixed the resolver keeping the previous theme's colours on its yours and incoming columns after an appearance change.
  • Fixed the Git console resizing its chrome along with its output area.
  • Fixed the automatic fetch reading published state rather than the disk before deciding to run.
  • Fixed the commit inspector reloading when the selected commit had not changed.
  • Gave every icon-only control a 28 pt click target, the pointer minimum in the Apple Human Interface Guidelines. Several were the size of the glyph itself, around a dozen pixels.

Performance

  • Resolved diff ink once per document instead of at every leaf. Three accessors each re-read the selected theme from UserDefaults, and one row calls all three; with no cap on stacked lines, a 5 MB diff made roughly three hundred thousand lookups for a value that is constant for the whole preparation.
  • Moved preparation of the resolver's conflict columns off the main thread.

Nori 0.8.2

This release rebuilds the interface around the redesign recorded in docs/design/refonte-interface.md.

Added

  • Added a launcher home screen that lists recently opened repositories with their branch, opens one by keyboard, accepts a folder dropped anywhere in the window, relocates a repository that moved, and reports the Git version it found — including when that version is too old.
  • Added a context bar and a status bar: the current branch, its divergence and the number of changed files at the top, and the repository path, remote, last fetch and Git console at the bottom.
  • Added a light appearance derived from the same hues as the dark one, with every colour resolved from a single source.
  • Added the repository tabs to the window titlebar, on the traffic-light line, returning a full bar to the content. Full screen keeps them in their own row since the titlebar retracts there.
  • Added a modification dot to a repository tab, so an unsaved repository says so without being selected.
  • Added a commit inspector that answers what changed before what the commit is called, with per-file deltas, a proportional diffstat, named merge parents and navigation to parent commits.
  • Added a change ruler at the right edge of a diff, marking every change of the file, plus expandable context one widening at a time.
  • Added whitespace visibility, a gutter and a result pane to diffs and the conflict resolver, and named each conflict side by its origin.
  • Added VoiceOver and full keyboard reach to the commit graph, and a complete keyboard map for commits, changes, tabs and view toggles.
  • Added motion that shows the shape of what is loading and lets the selection travel between rows, silenced under Reduce Motion.
  • Added a kelp forest behind the home screen, animated only while that screen is frontmost.
  • Added Shift-Command-T support for reopening repository tabs in last-closed, first-reopened order.
  • Added Command-W support for closing the active repository tab.
  • Added an immediate fetch when a repository tab becomes active, followed by automatic fetches every three minutes while the app scene remains active, keeping remote refs and visible history current.

Changed

  • Moved the commit graph to the left edge and put each reference on its own commit as a badge, so the message column stops occupying an empty half of the window.
  • Put uncommitted work at the top of the graph, as its own row.
  • Opened the branch list in the sidebar, marked which branch HEAD is on, and dropped the branch card and the per-branch age that duplicated it.
  • Made every surface opaque, so contrast is a property of the theme rather than of the desktop picture behind the window.
  • Let the Git console float over repository content instead of displacing it.
  • Reported what a failed command left untouched, and why it cannot be retried.
  • Vectorised the logo and added a dark Dock icon.
  • Folded the conflict resolver's three stacked bars into one and stated what blocks Continue.
  • Moved the conflict abort action to the working tree, where its effect is.
  • Reworked the commit body to collapse at five lines without laying out the whole message to do it.

Fixed

  • Restored Control-Tab navigation between repository tabs.
  • Made reordering repository tabs by drag and drop work: the transfer type the drag carries is now declared, so a drop destination can accept it.
  • Refreshed the reference badges after a checkout, which kept showing the branch just left as HEAD.
  • Stopped the commit summary running under its character ring.
  • Wrote the unit on relative times, so "2m" stops meaning two months.
  • Kept a conflict resolver pane at its full height when its viewport resizes, so a pane stops collapsing to one screenful and snapping the shared scroll position back to the top of the file.
  • Kept an activation refresh request that arrived during a fetch.
  • Built the workspace once instead of on every view initialisation.
  • Redrew the graph only when something about it changed.

Removed

  • Removed Apple Intelligence commit message generation while keeping the user-written 72-character summary and optional description workflow.

Nori 0.7.0

Added

  • Added conflict-to-conflict navigation that opens each file on its first conflict and shows the current position alongside previous/next controls.
  • Added Apple Intelligence commit message proposals with a 72-character subject and optional body, based on bounded staged file and patch input.
  • Added an integrated, syntax-highlighted Git console for live command output with responsive animated transitions.
  • Added accessible motion feedback across repository interactions.
  • Added Codex task attribution for linked worktrees.

Changed

  • Kept routine successful staging and index-transfer events out of the Git console so its output remains focused on useful command feedback.

Fixed

  • Preserved the visible diff when unrelated repository state changes.
  • Kept conflict navigation focus and resolver position stable through layout updates, and retained the resolved conflict in focus.
  • Kept the current branch selected when creating a branch from the graph.

Nori 0.6.0

Added

  • Added persistent branch pinning from the sidebar and graph, with the pinned branch kept in the leftmost lane and remote HEAD used as the default when no manual pin exists.
  • Added Shift-Tab navigation through open repository tabs, including wraparound from the last tab to the first.
  • Added a persistent inline or side-by-side layout choice to working-tree, commit, and stash text diffs, with synchronized scrolling between versions.
  • Added worktree navigation and a guided finalization flow that can preserve a detached checkout on a branch, identify integrated work, and safely remove its directory while keeping the branch.
  • Added an explicit forced-removal confirmation for discarding dirty, detached, or submodule-bearing worktrees, with last-moment content revalidation and attached-branch preservation.
  • Added a confirmed action for pruning stale Git registrations after worktree directories disappear, while preserving attached branches and warning about detached HEAD reachability.
  • Distinguished linked-worktree tabs with the repository name, an explicit Worktree marker, and the agent worktree name.

Fixed

  • Made worktree removal discoverable with a persistent trash action and explicit guidance when a branch, integration, or repository switch is needed before safe removal.
  • Closed an open worktree tab after successful removal even when macOS path aliases no longer resolve once its directory has disappeared.

Nori 0.5.0

Added

  • Added native previews for image changes in working-tree and commit diffs.
  • Added detailed commit and stash inspectors with per-file diff navigation and direct navigation to parent commits.

Changed

  • Added an explicit Early stage launch mode that grants full local access without Trial or License enforcement while retaining the complete licensed flow behind a release toggle.
  • Early stage release artifacts no longer require or embed authorization trust configuration; licensed artifacts keep the existing strict validation.
  • Moved the Early Stage status and feedback action into a compact repository top bar item, with the explanatory copy available on hover.
  • Reworked large diff preparation and rendering to stay responsive and memory-efficient on substantial changes.
  • Refined repository surfaces and condensed the working-tree interface so more files and actions remain visible without sacrificing native macOS behavior.

Fixed

  • Kept branch checkout available when commercial authorization is unavailable.
  • Made multiline text selections remain visible and stable across native diff rendering and document refreshes.
  • Hardened repository refresh, mutation, and commercial access transitions against stale or overlapping asynchronous work.

Nori 0.4.0

Added

  • Added a guided upstream configuration dialog when pushing a branch that does not yet track a remote branch.

Changed

  • Sidebar and working-tree panes now keep their independently resized widths when collapsed and reopened, with stable native split-view behavior.
  • Refined the default working-tree width to give file changes more room while retaining the existing compact constraints.
  • The top-bar actions stay fully labelled in narrow windows.

Fixed

  • Removed viewport-size-driven pane visibility changes so collapse controls always remain available to the user.

Nori 0.3.0

Added

  • Added top-bar actions to stash all working-tree changes (including untracked files) and restore the most recent stash.
  • Working-tree file paths now stay on one line while preserving the filename; hovering a path shows its complete location immediately.

Changed

  • Moved Undo to the leading position in the top-bar action group and made unavailable actions consistently appear disabled.

Fixed

  • Untracked files inside directories are listed individually instead of being treated as an invalid directory diff.

Nori 0.2.4

Changed

  • Simplified the working-tree commit panel to commit staged files only. Undo is now a primary top-bar action, alongside fetch, push and pull.
  • Made sidebar and working-tree collapse controls permanent parts of their column headers. Compact edge rails reopen either pane at any time, including while resolving conflicts.

Nori 0.2.3

Added

  • Added immediate native syntax coloring to regular working-tree, hunk and commit diffs in signed production releases.

Nori 0.2.2

Fixed

  • Kept the resolver's native syntax colors after the optional HTML highlighter is unavailable in a signed macOS release. Its absence can no longer replace visible colors with plain text.

Nori 0.2.1

Fixed

  • Prevented a launch-time resolver crash in the signed macOS release when the third-party HTML highlighter attempted to load its SwiftPM resource bundle. The resolver safely keeps its native syntax colors in that configuration.
  • Release archives now include and verify all SwiftPM resource bundles under Contents/Resources before code signing.

Nori 0.2.0

Added

  • Full-file three-way conflict resolver with synchronized native scrolling, all conflicts visible at once, an editable result pane, and rebase abort.
  • Native syntax coloring for resolver first paint, followed by theme-accurate refinement without changing text geometry. Nine familiar editor themes are available, including VS Code Dark, GitHub Dark, Dracula, Nord and Tokyo Night.
  • Resolver controls for temporarily showing or hiding the sidebar and working tree, plus Mac notifications for background Git failures.
  • Development application launcher (scripts/run-development-app.sh) with a dedicated bundle identifier for safely running beside the installed app.

Improved

  • Resolver parsing, syntax work, rendering and scroll synchronization run off the interaction path; large conflict files remain responsive.
  • Repository tabs can be reordered by drag and drop. Staging a file closes its diff and opens the next file when applicable.
  • The working tree has a 420pt minimum width and resolver mode uses the available space more effectively.

Fixed

  • Native resolver scrolling works with both trackpad gestures and scroll bars, including synchronized vertical movement in the output pane.
  • Syntax themes no longer emit missing-style warnings, and switching from the immediate to full highlighter no longer causes text to zoom or jump.

Nori 0.1.0

Added

  • Native Sparkle 2.9.4 in-place updates with a signed EdDSA appcast. Once this version is installed, future releases update the existing application bundle and preserve its Dock entry.
  • A release pipeline that embeds Sparkle.framework, signs the archive and appcast, then publishes the feed alongside the public GitHub release.
  • First-launch macOS notification permission request for background Git errors.
  • Live hook output while Git hooks run, including failures from tools installed through Homebrew.

Improved

  • Branch graph badges now size themselves from the Branch column, expand on hover when truncated, preserve a consistent high-contrast hover treatment, and correctly layer above commit content.
  • Branch graph badges mask the content beneath their expanded form so long branch names remain readable.
  • Conflict resolution is substantially more responsive for large files: conflict previews render lazily, panes use their full available width, and scroll state remains stable after focused changes.
  • Dark theme action colours and changed-file headings are clearer and more stable while repository state refreshes.

Fixed

  • Restoring a conflicting stash now keeps the index intact and opens the resolver instead of failing the operation.
  • Conflict output highlights show only the selected conflict rather than stale selections from other conflicts.
  • Error handling no longer initializes UserNotifications from a SwiftPM executable, preventing the macOS crash observed outside a real .app bundle.

Removed

  • Temporary recovery-backup storage. Git operations now rely on Git's own transaction model and the resolver rather than creating parallel backups.

Nori 0.0.4

Nori 0.0.3

Public distribution archive for Nori 0.0.3.

Download for Mac — 14-day free trial