Releases: yanlingLabs/winter
Release list
Winter 0.112.0
Winter 0.112.0
Sign in to the Anthropic Console
Claude models no longer need an API key copied into Winter. The Anthropic section of the
Providers pane now offers three ways in: API key, Console login, and Claude
subscription (shown, but not available yet). Console login signs you in through Anthropic's
own Platform CLI, ant, which ships inside Winter.app. Usage is billed to your Console
organization at API rates, exactly like a key. From the terminal:
winter login --anthropic-console
winter logout --anthropic-console- Both of Winter's runtimes use it. Code sessions on Claude models run on the Console
profile, and sessions that run on Winter's own runtime use the Console token. runtimes.official.authpicks the method:auto(the default: Console when you're signed in,
otherwise your API key),api-key, orconsole. Changes apply without a restart.- Your API key and your Console login are stored separately in the Keychain. Signing in to or
out of the Console never touches a stored API key. - A running Claude session keeps the credential it started with. A new choice applies to the
next session, or the next time a session moves between runtimes. - Signing out checks that the profile is really gone, and says so if it isn't.
Claude subscriptions stay off
Signing in with a claude.ai subscription still isn't supported. The hidden
runtimes.official.subscriptionAuth setting no longer loosens any check on its own; it stays
inert until that door is approved.
Fixes
- Moving a session from the Claude runtime back to Winter's runtime no longer reports success
when the destination fails to start. The move is refused and the session stays where it was.
Winter 0.111.1
Winter 0.111.1 — patch
- Fixed: on installs signed in with Codex (OpenAI OAuth), Claude models could not be selected for a session —
session.createandsession.setModelrefused every Claude model as "unknown model" before the runtime decision, so the official Claude leg was unreachable even with an Anthropic API key stored. Catalog models and their aliases are now accepted alongside the internal provider's own list.
Winter 0.111.0
Winter 0.111.0
Norma is now Winter. Same app, same daemon, same everything you already trust it with — new
name, new icon, and a fresh start on GitHub, Homebrew, and the update feed. This is the first
release under the new identity.
Coming from Norma
If you already have Norma installed, its next update is the handoff release: it carries Winter.app
inside it, installs and registers Winter as your menu-bar app, and retires itself — you don't need
to download anything separately. The very first time Winter boots, it migrates your existing
~/.norma home into ~/.winter on its own: sessions, settings, memory, and Keychain items are
copied over (never deleted from the old home, and never overwritten in the new one if something is
already there). macOS may ask permission for Winter to read the credentials Norma saved — click
Always Allow. Nothing about your history or your logins needs redoing. Once Winter is running the way you expect, the old Norma.app can be deleted — nothing in ~/.norma is needed for Winter to work, and the directory can go too once you have verified the migration.
If you installed via Homebrew, norma is deprecated in favor of winter. The handoff release
already installed Winter.app into /Applications by hand — not through Homebrew — before Norma
retired itself, so hand the cask back to Homebrew rather than reinstalling from scratch:
brew uninstall --cask norma && brew install --cask winter --adoptClaude models need your own API key
Code mode can now also run on Claude models, but only with an Anthropic API key you provide
yourself (winter login --anthropic-key). Signing in with a claude.ai subscription isn't
supported in this release — that door stays shut by default (runtimes.official.subscriptionAuth)
until it's had more scrutiny. Every other provider (your ChatGPT account, an OpenAI API key, Codex
OAuth) is unaffected.
A new version scheme
Winter versions now read #.###.# instead of Norma's #.#.###. The first digit only moves on a
rebrand-scale event (this one); the middle three digits are feature releases; the last single digit
is fixes. This is version 0.111.0 — the first release of the new scheme, feature line 111.
Signed Sparkle appcast entry: releases/winter/appcast.xml.
Norma 0.2.015 — Norma is now Winter
Norma 0.2.015 — Norma is now Winter.
This is the LAST Norma release. On launch it installs the bundled Winter.app into /Applications, moves your login item and helper registrations over, stops Norma's own daemon, opens Winter, and quits. Winter migrates your Norma data on its own first start.
This release embeds Winter.app (1206.4 MB) and installs it into /Applications on launch, then hands off and quits.
Signed Sparkle appcast entry: releases/appcast.xml.
Norma 0.2.014
Norma can work with office documents now.
Spreadsheets, presentations and text documents open in the panel, you can edit
them by hand, and the agent can read and change them directly — no exporting,
no conversion step, no asking it to write a script. This is the whole of this
release; it took the version from rendering nothing to driving all three.
Open and read
.xlsx .docx .pptx .ods .odt .odp and friends render in a document tab
— real layout, zoom, sheet/slide/page navigation. Open them from the file tree,
from a transcript, or with Open With. Tabs follow the file on disk: an external
change reloads silently and keeps your place, and a deletion says so instead of
showing a stale page.
Edit by hand
Type into them. ⌘S saves. Dirty state is tracked per tab, closing a modified tab
asks first, and quitting sweeps everything open. Saving is action-triggered, the
way Xcode does it: before and after the agent touches a file, when a tab closes,
periodically in the background, and when the agent reads a document you have open.
Let Norma edit them
Three new tools — sheets, slides and docs — let the agent read and modify
documents through the same sandboxed engine and the same atomic save path you
use. If you already have the file open, it edits that tab, so you watch it
happen. Writing to a path that doesn't exist creates the document.
- ⌘Z takes back what Norma did. One tool call collapses to one undo step, and
your own edits and Norma's share a single stack. - You can stop it. Esc in the composer, or the stop button where send usually
sits. While Norma is working on a document you have open, the tab says so and
tapping it interrupts the turn.
Also
- Formatting verbs for documents and slides: bold/italic, alignment, styles.
- Typing no longer blanks the page as you type.
- Saving got faster — about 4× on the fixed cost every save pays, so small
documents feel close to instant and large ones gain proportionally less. - Backspace deletes backwards. It was sending the forward delete.
- Scrolling works in documents that grow past the window.
- Spreadsheet reads return computed values, not formula source.
Known limitations
- Norma can't insert images or tables into office documents yet; it will fall
back to a script for those. - It can't read back most formatting, so it can tell you what it set, not what was
already there. - Undo of agent edits is verified in documents and spreadsheets; presentations are
unverified. - ODF files Norma saves no longer carry an embedded preview thumbnail. Finder,
QuickLook and Spotlight are unaffected — dropping it is what removed most of
the fixed cost above.
Note on size
The app now embeds a sandboxed LibreOffice, so this download is substantially
larger than 0.2.013 and the Sparkle update will be too. The office engine itself
runs entirely on your machine — rendering, editing and saving never leave it. What
you ask Norma to read or change still goes to your configured model provider, the
same as any other file it works on.
Requires Apple silicon.
vendor-libreoffice-20260822-r4 (headless LibreOffice, macOS arm64, r4)
Prebuilt, privacy-scrubbed headless LibreOffice engine for macOS arm64 — vendored dependency for
the Norma app, not an app release itself (--latest=false; does not affect the app's release
lineage or its Sparkle appcast).
What this is
A native macOS arm64 build of LibreOffice/core @ 11482c8f71bc76ed6260bc03b1576a52a788ab4f
with --enable-headless (the svp/headless VCL backend — the same shape LibreOffice's own iOS
port uses). Same commit, same configure flags, same build as -r2/-r3 — this asset changes
exactly one thing. Zero source patches anywhere in this build.
Why -r4
One disclosed change on top of -r3, from the same already-built core/instdir/ (no rebuild):
product-set/Frameworks/libmswordlo.dylib is added (68th dylib).
-r3 fixed .xlsx export and left .docx export failing with
SfxBaseModel::impl_store ... failed: 0xc10(Error Area:Io Class:Write Code:16), honestly disclosed
there as "a different, still-open Writer/OOXML-export defect." It was neither Writer's nor a defect —
it was the same omission class as -r3's own, one library over:
registry/writer.xcdroutes theMS Word 2007 XMLfilter to
com.sun.star.comp.Writer.WriterFilter. On an export descriptor that implementation does
exactly one thing:createInstance("com.sun.star.comp.Writer.DocxExport")
(sw/source/writerfilter/filter/WriterFilter.cxx).services/services.rdbplacescom.sun.star.comp.Writer.DocxExport(and
com.sun.star.comp.Writer.RtfExport) in$LO_LIB_DIR/libmswordlo.dylib— absent from-r2/
-r3'sFrameworks/, because the UNO service managerdlopens it by name at export time.
It is not a link-time dependency of anything, so neither the closure recipe's
DYLD_PRINT_LIBRARIEStrace (an import + tile-paint workload) nor its one-levelotool -L
safety net could ever have seen it.0xc10was never evidence of a failed write:SfxBaseModel::impl_storesynthesises
ERRCODE_IO_CANTWRITEwhenever storing returns false having set no error of its own
(sfx2/source/doc/sfxbasemodel.cxx, "Storing has failed, no error is set!"), which is exactly
how a missing export service presents.
Verified before packaging (a standalone LOK harness against product-set + this one dylib, nothing
else changed): gate.docx → .docx and gate.odt → .docx both now save real, complete
WordprocessingML packages whose text survives the round trip (the two directions together rule out
a fixture-specific effect); gate.xlsx, gate.pptx and gate.ods are unaffected. Also verified
with the same harness that the legacy-binary import behaviour is unchanged — libmswordlo also
carries Writer's WW8 (.doc) importer, and it makes no difference here, because the four
FormatDetector service libraries remain intentionally out of this trim, so content detection never
selects a binary filter.
This file was NOT rebuilt: it is a verbatim cp -pP from the identical core/instdir/ every other
dylib already came from, re-scanned for privacy independently rather than assumed clean by
inheritance. Its install-name/link shape was verified rather than patched — the same fixed-width
@__…OOO/<name> LC_ID placeholder its siblings carry, @loader_path/-relative dependencies that
are all already inside the kept set, and the same adhoc, linker-signed / TeamIdentifier=not set
posture. No install_name_tool run was needed or performed.
Engine-wise, nothing else changed, and this was re-measured rather than inherited: all six format
fixtures were re-rendered against this asset's own product-set (raw SHA-256 of the paintTile
output at the pinned tile geometry) and every hash matches -r3/-r2/the original build exactly.
Adding one dylib changes zero pixels — a filter library only ever dlopen'd on the export path
cannot affect what paintTile draws.
Contents
product-set/— the runtime closure:Frameworks/(68 of 248 possible dylibs —-r3's set plus
this release's one added file) +Resources/(LibreOffice's config/UI-resource tree, shipped
whole, unchanged).LICENSES/— per-upstream-project license texts, plusMANIFEST.md(updated: 68 dylibs; the new
file is the same already-coveredlibreoffice-coremodule/license, no new upstream project).VERSION-PIN— the exact configure flags, commit, build facts an embedder needs, the R4 ADDENDUM
documenting the change above in full, and the six-fixture pixel-hash pins (values unchanged,
and re-verified against this asset before upload).
Using this
Ships adhoc/linker-signed, as LibreOffice's own build produces it — this tarball does not sign
or notarize anything. An embedding application is responsible for re-signing these dylibs with its
own Developer ID identity (and hardened runtime, if applicable) at its own build time — Norma's own
embed phase does this, counting Mach-Os dynamically rather than assuming a fixed number, so the 68th
dylib needs no build-script change.
See VERSION-PIN inside the archive for the dlopen entry point, the required _Exit(0) teardown
pattern, and the fontconfig caveat — all unchanged.
Privacy scan — exact command and full result
Reused this repo's own local-only identity guard (the same mechanism scripts/release.ts's §11b
publish gate uses for app releases) — ~/norma-private/git-hooks/name-guard.sh artifacts <path>,
patterns not reproduced here since this file ships inside a public release (the guard is deliberately
local-only, outside every repository, for exactly that reason).
Scanned separately, before compression:
- The added dylib alone (
libmswordlo.dylib): clean. product-set/Frameworks/whole (all 68 dylibs): clean.product-set/Resources/minus one already-known, byte-verified-unchanged file
(liblangtag/language-subtag-registry.xml— IANA's language-subtag registry, whose one match is a
real registered language name, a natural-language collision and not an identity leak; this exact
file is already a standing exclusion in this repo's ownrelease-lib.tsNAME_SCAN_EXCLUSIONS
for the identical reason): clean.LICENSES/: clean.VERSION-PIN: clean.- The final, uncompressed
.tar(owner-suppressed,tar --uid 0 --gid 0 --uname '' --gname '',
verified withtar tvf): exactly one hit, independently verified byte-for-byte to be the same
IANA registry collision above — not a new leak, not identity-bearing. - The
.tar.zstwas verified by decompression round-trip (SHA-256-identical to the already-scanned
.tar), not re-scanned directly — compression would hide any string from a byte scan the same way
it would for a.zip/.dmg, so the meaningful gate is the uncompressed archive.
Zero identity hits anywhere in this asset.
vendor-libreoffice-20260822 (headless LibreOffice, macOS arm64, r3)
Prebuilt, privacy-scrubbed headless LibreOffice engine for macOS arm64 — vendored dependency for
the Norma app, not an app release itself (--latest=false; does not affect the app's release
lineage or its Sparkle appcast).
What this is
A native macOS arm64 build of LibreOffice/core @ 11482c8f71bc76ed6260bc03b1576a52a788ab4f
with --enable-headless (the svp/headless VCL backend — the same shape LibreOffice's own iOS
port uses). Same commit, same configure flags, same build as -r2 — this asset changes only the
two items below. Zero source patches anywhere in this build.
Why -r3
Two disclosed changes on top of -r2, both from the same already-built core/instdir/ (no
rebuild):
-
The OOXML export fix.
-r2'ssaveAsto.xlsxcrashed the whole helper process —
libuno_sal.dylib.3's text-encoding subsystem lazilydlopenslibsal_textenclo.dylibby
name the first time a full charset lookup is needed (e.g. an Excel font record's Windows
charset ID), andabort()s when the load fails. That dylib is absent from-r2's 66-dylib
Frameworks/because it is reached only through a runtimedlopen, never a link-time
dependency —-r2's closure recipe (aDYLD_PRINT_LIBRARIEStrace of an import+paint-only
workload, plus a one-levelotool -Lsafety net) had no way to see it.-r3adds this one
file — a verbatimcp -pPfrom the identicalinstdirevery other dylib already came from,
re-scanned for privacy independently, not assumed clean by inheritance. Verified before
packaging (a standalone LOK harness,product-set+ this one dylib, nothing else changed):
gate.xlsxnow saves successfully (real output file, clean exit);gate.pptxis unaffected
(already worked, still works).gate.docxstill does not save — the missing-dylib abort is
gone (no crash, reproduced on two independent fresh profiles), but a different, still-open
Writer/OOXML-export defect surfaces instead: a clean, caughtSVSTREAM_WRITE_ERROR
(ERRCODE_IO_CANTWRITE) insideSfxBaseModel::impl_store. Unrelated to the charset-table gap
this asset fixes; disclosed, not chased further here. -
A tar-container privacy fix
-r2didn't have. Measured directly against the live,
currently-published-r2asset (cold-downloaded, SHA-256-matched to its pin): the tarball's own
per-entry headers record the packaging account's macOS username and primary group, via
bsdtar's default owner-name recording — independent of, and not caught by,-r2's own
file-content byte-scan (which read extracted file bytes, never the tar's own header bytes).
-r3's tar is built with explicit owner/group suppression (tar --uid 0 --gid 0 --uname '' --gname ''); see the Privacy scan section below for the verification. The live-r2asset was
not modified or re-uploaded — a GitHub release asset is maintainer-replaceable at the same
URL, and re-publishing scrubbed bytes under the same name is exactly the silent-swap hazard this
repo's ownfetch-libreoffice.tsheader warns against. Flagged here as an open item for whoever
owns this asset's lifecycle to consider once-r3is the pinned, fetched asset.
Engine-wise, nothing else changed: all six format fixtures render pixel-identical (raw SHA-256 of
the paintTile output) to -r2/the original build. Adding one dylib and fixing tar metadata
changes zero pixels.
Contents
product-set/— the runtime closure:Frameworks/(67 of 248 possible dylibs —-r2's trim
plus this release's one added file) +Resources/(LibreOffice's config/UI-resource tree,
shipped whole, unchanged from-r2).LICENSES/— per-upstream-project license texts, plusMANIFEST.md(updated: 67 dylibs, the
new file is the same already-coveredlibreoffice-coremodule/license, no new upstream
project).VERSION-PIN— the exact configure flags, commit, build facts an embedder needs, the R3
ADDENDUM documenting both changes above in full (including the verified install-name/link shape
of the added dylib — matches its siblings, no patching needed), and the six-fixture pixel-hash
pins (unchanged from-r2).
Using this
Ships adhoc/linker-signed, as LibreOffice's own build produces it — this tarball does not sign
or notarize anything. An embedding application is responsible for re-signing these dylibs with its
own Developer ID identity (and hardened runtime, if applicable) at its own build time — Norma's own
embed phase does this, counting Mach-Os dynamically rather than assuming a fixed number, so the
67th dylib needs no build-script change.
See VERSION-PIN inside the archive for the dlopen entry point, the required _Exit(0) teardown
pattern, and the fontconfig caveat — all unchanged from -r2.
Privacy scan — exact command and full result
Reused this repo's own local-only identity guard (the same mechanism scripts/release.ts's §11b
publish gate uses for app releases) — ~/norma-private/git-hooks/name-guard.sh artifacts <path>,
patterns not reproduced here since this file ships inside a public release (the guard is deliberately
local-only, outside every repository, for exactly that reason).
Scanned separately, before compression:
- The added dylib alone (
libsal_textenclo.dylib): clean. product-set/Frameworks/whole (all 67 dylibs): clean.product-set/Resources/minus one already-known, byte-verified-unchanged-from--r2file
(liblangtag/language-subtag-registry.xml, IANA's language-subtag registry — a natural-language
collision,<description>Como Karim</description>, a real registered language name (ISO 639-3
cfg), not an identity leak; this exact file is already a standing exclusion in this repo's own
release-lib.tsNAME_SCAN_EXCLUSIONSfor the identical reason): clean.LICENSES/: clean.VERSION-PIN: clean.- The final, uncompressed
.tar(owner-suppressed): exactly one hit, independently verified
byte-for-byte to be the same IANA registry collision above (single match, same description
string, same file) — not a new leak, not identity-bearing. - The
.tar.zstwas verified by decompression round-trip (SHA-256-identical to the already-scanned
.tar), not re-scanned directly — compression would hide any string from a byte scan the same
way it would for a.zip/.dmg, so the meaningful gate is the uncompressed archive.
Zero identity hits anywhere in this asset.
Norma 0.2.013
Norma 0.2.013
Signed Sparkle appcast entry: releases/appcast.xml.
vendor-libreoffice-20260819 (headless LibreOffice, macOS arm64, r2)
RETIRED — superseded by r3 (vendor-libreoffice-20260822).
The r2 asset has been removed from this release. Its tarball container metadata
recorded the packaging account's identity (the file contents were clean; the
container was the gap). r3 is a straight re-cut from the same pinned upstream
commit with that gap closed, plus one dylib restored so OOXML export works.
Nothing depends on this asset: the vendor fetch pins r3, and no shipped release
of the app ever embedded the office engine.
This release is kept as a provenance record only.
Norma 0.2.012
Norma 0.2.012
Signed Sparkle appcast entry: releases/appcast.xml.