Commit Graph
35 Commits
Author SHA1 Message Date
LGUG2Z 98b3b4bc0c build(nix): the programs of the macOS e2e guest, and nix run .#e2e-macos
komorebi-e2e-macos builds the test window and the agent for macOS in a derivation of its own, on the
dependency artifacts of the macOS build, so that fullBuild (what users get) does not change. The
e2e-macos app, on aarch64-darwin, runs the scenarios of the shared core against the golden Tart image
with this checkout's daemon, as e2e-windows does for Windows: tart comes from nixpkgs, where its
licence makes it unfree, so only it is allowed, here. KOMOREBI_E2E_BINS runs another build, and
KOMOREBI_E2E_TART another tart.
2026-11-06 14:40:50 -08:00
LGUG2Z 77e43d1602 ci(e2e): run the unit tests of the macOS port with those of the Windows one
The check that runs the Python of the e2e guests that needs no guest (windows-e2e-tests, on
Linux) now also runs platforms/tart_macos/tests: the ignore rules, which windows count as hidden,
the paths a scenario may ask for, and that every scenario the macOS runner names exists in the core.
2026-11-06 14:40:50 -08:00
LGUG2Z f4715a3465 feat(e2e-agent): the macOS verbs on the shared protocol, in the one agent crate
Move the macOS agent into komorebi-e2e-agent as macos.rs, answering the protocol of protocol.rs
with its own verbs (os_windows, displays, activate, minimize, close, move; a window is found by
its title), and remove the separate komorebi-macos-e2e crate that had copied the protocol. There
is one binary name and one port on every platform, so the host has one client and one description
of the protocol.

AppKit is for the main thread, so the macOS agent serves one connection at a time on it, where
the Windows one serves each on a thread. A spawned program on macOS gets a standard input that
stays open, as the test window leaves when its input closes. The crate is built for macOS and
Windows now and stubbed on Linux, as komorebi-testwin is.
2026-11-06 14:40:49 -08:00
LGUG2Z 6ed535be38 feat(testwin): a window for macOS, on the same command line and commands
An AppKit window of a regular application, so that the daemon sees it as it sees any program: the
same options and standard input commands as the Win32 one (title, colour, size, minimum size,
fixed, late rename, fullscreen as a borderless window over its display, report with the frame in
points from the top left of the main display, close, exit). The main thread runs the event loop
in short turns and takes the lines the input thread queued; the program leaves when its window is
closed. A window class has no meaning on macOS, so --class is accepted and ignored.

The macOS source set now builds the crate; Linux still stubs it.
2026-11-06 14:40:49 -08:00
LGUG2Z 6b8ab7d959 feat(e2e): a guest agent for macOS that answers the host and describes windows
The Windows guest has komorebi-e2e-agent; this is its macOS counterpart, speaking the same
protocol (one JSON line per request, raw bytes after it for put_file and get_file) so that the
host client is the same. Beyond exec, spawn and file transfer it answers with the windows the
accessibility API gives (title, frame, focus, minimized) and the displays with their work areas,
and it can activate, minimize, close and move a window.

It has to be started by a program that holds the Accessibility and Screen Recording grants, so
that the daemon it spawns is attributed to that program.
2026-11-06 14:40:49 -08:00
LGUG2Z 82366f7134 fix(nix): evaluation no longer reads store paths that builtins.path makes
nix flake check --no-build failed in the nix-eval job on the runner with "path ...-Cargo.lock is not
valid": crane's vendorCargoDeps runs pathExists on the lock at evaluation time, and `repoFile` is a
store path that builtins.path makes during evaluation. Nix 2.35 with an empty store, as on a fresh
runner, does not have it yet under --no-build; Lix, and a store that had seen the file, do.

The parsed lock now comes from the flake source (cargoLockParsed in nix/lib.nix), and the Windows guest
reads tools/test-partition.json the same way. The derivations are unchanged (same drv paths), so no
cache key moves. Reproduced and fixed with upstream Nix and an empty store:
nix shell nixpkgs#nixVersions.latest -c nix flake check --no-build --all-systems --store <empty dir>
2026-11-05 16:48:10 -08:00
LGUG2Z 194fbd4281 build(nix): a hygiene dev shell with the pinned tools of the first CI stage
devShells.hygiene is the toolchain with the nightly rustfmt, cargo-deny, shellcheck, actionlint, jq,
ripgrep and git, without the Windows SDK, the VM tooling and the rest of the full shell, so that the
first stage sets up in seconds and a local `nix develop .#hygiene` runs what CI runs.
2026-11-05 16:31:20 -08:00
LGUG2Z e23bfcfb36 build(nix): the macOS options and nix-darwin module validations are checks on every system
They take a plain pkgs and evaluate against any nixpkgs, so a Linux runner can build them. They stay in the macos-options set.
2026-11-05 15:51:50 -08:00
LGUG2Z 56afe5b286 build(nix): the tests of komorebi-macos-core run in linux-nextest and macos-nextest 2026-11-05 15:51:50 -08:00
LGUG2Z 98295e0065 build(nix): windows-nextest runs the windows and os_sensitive packages of the partition, windows-nextest-full all of them 2026-11-05 15:51:50 -08:00
LGUG2Z 279ac0f759 style: format the files the path edits touched with rustfmt and nixfmt 2026-11-05 15:03:27 -08:00
LGUG2Z 259575a1b3 build: route the workspace to crates/
The workspace members, the path dependencies, the include_str! and test
fixture paths, the recorder's indexed source keys, and the Nix source
filter and path literals follow the new layout. Cargo.lock is unchanged.
2026-11-05 15:03:27 -08:00
LGUG2Z 112e624c5e build(nix): regenerate the Nix options from the schemas 2026-11-05 15:03:27 -08:00
LGUG2Z c6d29a9268 build(nix): schemars-nixgen is built and checked by the flake, and in the dev shell
nix/nixgen has the package and the clippy and nextest checks (in the default check sets), from a
"nixgen" platform of nix/workspace-src.nix that is the tool alone; it is a stub in every other
platform's source, so an edit of it rebuilds none of theirs.
2026-11-05 15:03:27 -08:00
LGUG2Z 3d33fac0cd merge: the history of schemars-nixgen 2026-11-05 15:03:27 -08:00
LGUG2Z 1db6d7d3fd build(nix): the recorder is built, checked and shipped by the flake
nix/recorder holds the native packages and checks of macOS and Linux (the recorder and the
sources it indexes are the "recorder" platform of nix/workspace-src.nix), the Windows
build has it as one of its members, and the dev shell gets ffmpeg, resvg and GStreamer. The
flake inputs komorebi-mac and komorebi-windows are gone: the sources are in the tree.
2026-11-05 15:03:27 -08:00
LGUG2Z 38a56fd544 merge: the history of komorebi-recorder 2026-11-05 15:03:27 -08:00
LGUG2Z 3e21ebd3a4 feat(e2e): windows-nextest runs the Windows unit tests in the guest
The Windows crates' unit tests could only run in the (future) hosted Windows
CI. They run in the existing Windows e2e guest: nix run .#windows-nextest
boots the golden image like a scenario (restoring a saved state when
KOMOREBI_E2E_STATE is set), uploads the test executables that the check
windows-nextest-build cross-compiled, runs every test in a process of its own
(nextest.exe is not needed: komorebi's tests share global state, so one
process per test is what nextest does too) and prints a line per executable
and the failures, with OUT/cargo-tests.json for every result.

The driver e2e/platforms/qemu_windows/cargo_tests.py already existed and was
wired to nothing; it now takes the check output (tests.tsv) as well as cargo
messages, creates the saved state itself, prints the panic message of a
failure, and uploads the data files the tests read. Those are found by the
CARGO_MANIFEST_DIR baked into the executables, a path of the Nix build, so
the check also keeps schemas/ and the tests' fixtures and the driver puts them
at that path under C:. Without them 20 tests failed for the missing files.

docs/dev/build-and-test.md and docs/dev/flake-checks.md describe the check,
the app and the neutral crates in linux-nextest.

Verified: nix run .#windows-nextest on the golden image g8 (scale 1.5, state
~/e2e-w0/state-nextest): 964 tests in 37 executables, 964 passed, 0 failed,
202 s with the state restored (first run 163 s more to save the state).
One run only; not soaked. No e2e scenario, the golden image or the existing
e2e-windows behaviour changed.
2026-11-05 15:03:27 -08:00
LGUG2Z d872c9ec43 build(nix): windows-nextest-build compiles the Windows tests
The tests of the Windows crates cannot run on a Linux builder, and the old
windows-nextest (crane cargoNextest with doCheck = false) ran none. This
check does the part a builder can do: cross-compile every test executable of
the Windows workspace (cargo test --workspace --release --no-run, target
x86_64-pc-windows-msvc through the xwin toolchain) and keep them with a
tests.tsv that lists them (48 executables), so that they are proved to
compile and link, and so that the next revision can run them in the guest.
The stub members of the Windows source (Linux and macOS packages) are
excluded: objc2 does not build for Windows. The check is in the set
windows-test.

Verified: nix build .#checks.x86_64-linux.windows-nextest-build; the output
holds tests/*.exe and tests.tsv. Not run: the executables (see the next
revision).
2026-11-05 15:03:27 -08:00
LGUG2Z 18e92e59d1 build(nix): the neutral crates' tests run in linux-nextest
linux-nextest ran only the tests of the Linux packages (-p komorebi -p
komorebi-linux ...). The tests of komorebi-layouts, komorebi-scrolling,
komorebi-themes and the shared crates/* (backend, collections, config, core,
protocol, settings, transport, komorebic-core) ran in no nix check. They are
platform neutral, so the check now names them too (explicit -p list: with
--workspace the feature unification of komorebi-daemon breaks windows-future
on Linux), and runs with --no-fail-fast so one run lists every failure.

Two of those tests read files that the Linux source did not have: the
schemas of every platform (komorebi-config schemas test) and the macOS CLI
pages (komorebic-core docs_cli), so nix/workspace-src.nix keeps schemas/ and
docs/macos/cli/ in the Linux source.

Verified: nix build .#checks.x86_64-linux.linux-nextest, 1532 tests run, 1532
passed (9.1 s of test time).
2026-11-05 15:03:27 -08:00
LGUG2Z dfef93fc61 build(nix): macos-nextest runs the tests (doCheck = true)
The macos-nextest check was built with doCheck = false like the Windows one, so crane printed
'doCheck is not set, nextest tests will not run' and the check ran no test. It now uses
doCheck = true, as linux-nextest does, so the macOS unit tests run in the nix sandbox of a
darwin machine (the owner asked: can nextest run on a Mac with nix-darwin; if so, keep it).

Verified on the Mac Mini (aarch64-darwin, nix, no komorebi daemon started):
nix build .#checks.aarch64-darwin.macos-nextest exits 0 in about 1 minute with the cached
dependencies; nextest reports 'Summary 383 tests run: 383 passed, 1 skipped'. This is the
komorebi-macos library's tests; the cargo test run of the other packages (753 tests in all) was
done outside nix earlier. Not run: the other macOS checks again after this change (it only
touches this one check's arguments).
2026-11-05 15:03:27 -08:00
LGUG2Z 77289f6b20 docs(dev): flake-checks.md and the nix commands of build-and-test.md
docs/dev/flake-checks.md records why the evaluation of the checks needed more than
the host has (about 0.55 GB per VM suite and 0.4 GB per NixOS system of the module
check, nothing shared), the sets and what is in each, how they are exposed
(checkSets, checkMembers, defaultCheckSets in nix/checks.nix), the alternatives
rejected, what was measured with the sets (nix flake check --no-build 4.54 GB / 33 s
on one system, 6.55 GB / 40 s --all-systems; each set alone from 0.2 GB for the cheap
ones to 11.6 GB for linux-nixos-eval), and why windows-nextest and macos-nextest ran
no test.

build-and-test.md gets the commands for one set, the default and one member and
loses windows-nextest; flake.md, docs/linux/CONTRIBUTING.md, docs/linux/dev/vm-tests.md,
the comment of nix/linux/tests/vm/default.nix and the CI step of CUTOVER-PLAN.md name
the new places (checkSets, checkMembers, legacyPackages.<system>.vm.NAME) instead of the
placeholder heavyChecks and checks.<system>.vm-NAME. Not run: the docs build.
2026-11-05 15:03:27 -08:00
LGUG2Z 5961368c7d perf(nix): the overlays share one nixpkgs and one crane build per system
overlays.linux and overlays.forVmTests (which applies the first as well) ran
mkPkgs, a new `import nixpkgs` with the rust overlay, and the whole crane
mkKomorebiPackages once for every NixOS system an evaluation instantiated: every
node of every VM suite and every module scenario, twice each. lib.mkPkgs now
hands out one instance per system and the linux module builds the packages of
each Linux system once (buildFor).

The derivations are the same (drvPath of linux-clippy, vm-kwin and linux-run-kde
equal to those before). Measured on a scratch copy of the same change: the
stand-alone expression of 4 suites 2.15 -> 1.50 GB, 8 real suites 5.18 -> 4.79 GB,
linux-nixos-module-eval 10.3 -> 8.5 GB, plasma guests 9.0 -> 8.7 GB. It does not
make the heavy sets cheap: see docs/dev/flake-checks.md.
2026-11-05 15:03:27 -08:00
LGUG2Z c0980f1f0b fix(nix): the check windows-nextest ran no test and is gone
The Windows crates are built with doCheck = false (individualCrateArgs of
nix/windows/build.nix) and the tests of a Windows program cannot run on a Linux
builder, so crane's cargoNextest derivation only ran `cargo nextest --version`:
a check named nextest that ran nothing. It is removed from the checks (22 names
left on x86_64-linux) and the windows-test set has the e2e Python tests only.
windows-clippy (--all-targets) still compiles the tests; the Windows CI runs
them (`cargo test`, .github/workflows/windows.yaml). The name is dropped from
docs/dev/flake.md and build-and-test.md, with a comment where it was.

macos-nextest has the same shape (doCheck = false in nix/macos/build.nix): it is
left as it is, since the Intel/Apple names stay stable until the Mac run decides.
2026-11-05 15:03:27 -08:00
LGUG2Z f3581bad91 build(nix): checks are composed from defaultCheckSets
checks.<system> is now the members of the sets named in one list,
defaultCheckSets in nix/checks.nix (fmt, deny, windows-lint, windows-test,
linux-lint, linux-test, linux-options, macos-lint, macos-test, macos-options),
instead of "every set but the heavy ones", so choosing what `nix flake check`
runs is a one-line edit. The heavy sets (linux-demo, linux-nixos-eval, vm-fast,
vm-slow) stay reachable as `nix build .#checkSets.<set>` and their members as
.#checkMembers.<set>.<name>. Two sets are added to checkSets: cheap (what
checks has, one derivation) and all (every check).

The members of checks are the same as before this revision on every system
(x86_64-linux: 23 names).
2026-11-05 15:03:27 -08:00
LGUG2Z 6038e53fc5 refactor(nix): the checks are separate sets
Every platform module now defines its checks as allChecks.<name> and the new
nix/checks.nix says which set each is in (fmt, deny, windows-lint, windows-test,
linux-lint, linux-test, linux-options, macos-lint, macos-test, macos-options,
linux-demo, linux-nixos-eval, vm-fast, vm-slow; the vm tiers come from the
suites). A check in no set, or in two, fails the evaluation. checks.<system>
holds the members of the sets that are not heavy, the same split flake-one made
(vm-*, the Plasma guests, the module scenarios and run-kde left out), and the
placeholder legacyPackages.<system>.heavyChecks is gone: every set is one
linkFarm derivation, legacyPackages.<system>.checkSets.<set>, and its members
are legacyPackages.<system>.checkMembers.<set>.<name>. legacyPackages.<system>.vm
is unchanged.

The linux module is mostly reindented (the split wrapper is gone); no check
changed. Verified: see the revision that composes the sets.

treefmt and pre-commit, which the treefmt-nix and git-hooks-nix modules add to checks themselves, are allChecks of nix/common.nix now (those modules' own entries are switched off, treefmt.flakeCheck and pre-commit.check.enable), so that they are members of the set fmt.
2026-11-05 15:03:27 -08:00
LGUG2Z ae9ee327f9 build(nix): one root flake for Windows, KDE Plasma and macOS
One flake.nix and one flake.lock replace the root flake that re-exported two nested flakes.
The inputs are one nixpkgs (the revision the KDE flake was locked to, f05535a0: the VM suites
run against its Plasma and KWin 6.8.2), one crane, rust-overlay (19ecdd08, rustc 1.99.1),
flake-parts, treefmt-nix and git-hooks-nix, all the KDE flake revisions, plus asc. A second
nixpkgs, nixpkgs-x86_64-darwin (16c7794d, the macOS flake pin), serves the x86_64-darwin
outputs only: evaluating that system with the unified pin throws (nixpkgs 26.11 dropped it).

Layout: nix/common.nix (systems, pkgs, treefmt, pre-commit, dev shells default and native,
default overlay), nix/lib.nix, nix/workspace-src.nix (one source per platform from the one Cargo
workspace: the platform members, its files of the shared crates told apart by name, the data
files, and stubs for the other members, which cargo needs), nix/{windows,linux,macos}/
{build,flake-module}.nix. The dependency derivations use a manifests-only dummy source, a plain
path, so crane reads nothing built at evaluation and the Darwin outputs evaluate on Linux.

Names: unprefixed outputs are the native build (Linux: KDE; Darwin: macOS); Windows cross
outputs are windows-*; checks are windows-*, linux-*, macos-* and vm-NAME; table in docs/dev/flake.md
(next revision). One deny.toml, one format-all and one version (workspace) are used by all.
PLACEHOLDER for the agent that owns the check sets: the checks that evaluate a NixOS system
or a VM (vm-*, linux-nixos-module-eval, linux-plasma-guests-eval, linux-run-kde*) are
legacyPackages.<system>.heavyChecks.<name>, not checks, because evaluating them needs more
memory than nix flake check --all-systems can use. The Plasma guests got a stub root file system
and boot loader (mkDefault, replaced by their vmVariant) so that nix flake check can evaluate
their toplevel.

Verified: nix flake check --no-build --all-systems passes (42 s, rc 0); nix flake check
--no-build passes. Not verified: any build (next revisions record them).
2026-11-05 15:03:27 -08:00
LGUG2Z 05698a34ba fix(nix): the nix files read the final directories
The pure moves put the KDE and macOS nix files under nix/linux and nix/macos but left the
relative paths they read: the JSON schema (now schemas/linux and schemas/macos), the example
configurations and key binding samples (docs/linux, docs/macos), the key binding fixtures
(komorebi-hotkeys at the top level), the wsl2 probe script (scripts/linux). Each path now
names the file in the final directory, one more directory up because the files are one level
deeper.

Not touched: flake.nix and the nested flakes (next revisions), which still name the old paths.

Verified: not verified (nothing evaluates until the flake is rewritten; the new flake checks
these paths).
2026-11-05 15:03:27 -08:00
LGUG2Z f01853ceca refactor(repo): move the KDE and macOS nix files under nix/ (pure move)
komorebi-for-kde/nix/ -> nix/linux/
komorebi-for-mac/nix/ -> nix/macos/

The nix expressions of the platforms (modules, option files, VM test suites, kwin effects,
the darwin module) sit next to the existing nix/workspace-src.nix. Renames only (252
files); the flakes that import them are replaced by one root flake later in this stack, so
nix does not evaluate at this revision.
2026-11-05 15:03:27 -08:00
LGUG2Z 080fef2a5a chore(layout): move the files of the repository to where they live in the komorebi monorepo 2026-11-05 13:05:34 -08:00
LGUG2Z df35d7b258 chore(layout): move the files of the repository to where they live in the komorebi monorepo 2026-11-05 11:48:44 -08:00
LGUG2Z 80a749b37e build(nix): build the KDE and macOS packages from the root workspace
The three flakes now build from the one root Cargo workspace (previous revision, which must land with
this one). nix/workspace-src.nix assembles each platform's source: the files it needs (its crates, the
root crates they depend on, the root Cargo.toml and Cargo.lock) plus a stub (the member's own
manifest, an empty lib.rs, a main that does nothing) for every other member, because cargo has to load
the whole workspace but must not depend on the other platforms' code. The KDE and macOS flakes pass
-p <their packages> (cargoExtraArgs), no longer cd into a subdirectory workspace, use the root
Cargo.lock/Cargo.toml (vendored from the filtered source, so crane does not read the stubbed one),
and run cargo deny with --workspace --exclude <the other platforms' packages> and their own
deny.toml; the root flake excludes the KDE and macOS packages from deny and builds default-members.
komorebic/applications.json is added to the macOS source filter (it is embedded by include_str!).
The KDE/macOS deny.toml clarify entries and root deny.toml follow the package renames (squashed into
the rename revisions).

Evaluation (nix eval drvPath, no build): Windows clippy, deny, fmt, nextest, toml-fmt; kfde clippy,
doc, deny, fmt, toml-fmt, nextest, schema-fresh; kfde-komorebi, kfde-komorebic, komorebic. Cache
isolation measured by evaluation: an edit of crates/komorebi-bar-core or komorebi/src changes the
Windows drvs and leaves the kfde clippy and nextest drvs unchanged; an edit of komorebi-for-kde changes
kfde and leaves Windows unchanged; an edit of komorebi-for-mac changes neither. tools/kde-closure-check
ok (rewritten for the merged workspace), root-crates.json unchanged.

KNOWN LIMITS: (1) the stubbed source is a derivation that crane reads at evaluation (readDir in
mkDummySrc), so evaluating or building another system's attributes needs a builder for that system:
`nix flake show --all-systems` and drvPath of aarch64-darwin attributes now fail on a Linux host (the
fast-check nix step evaluates the current system only). (2) cargo deny, fmt and taplo behaviour in the
merged workspace is unverified: not built. (3) the version placeholder warning of crane for the
virtual root manifest (cosmetic).

Needs from the coordinator (idle host, heavy gates): nix build -L .#checks.x86_64-linux.komorebi-workspace-clippy
(the root deps derivation is a new one because of the lock), .#checks.x86_64-linux.komorebi-workspace-deny,
-fmt, -nextest, -toml-fmt; the same for kfde-komorebi-workspace-{clippy,deny,fmt,nextest,toml-fmt,doc},
kfde-schema-fresh, .#packages.x86_64-linux.kfde-komorebic and kfde-komorebi; then one KDE VM fast run
(the KDE package derivation changed); on a Mac or a darwin builder: .#packages.aarch64-darwin.kfm-komorebic,
kfm-komorebi, kfm-komorebi-bar and the kfm checks. Not run by me: any of these.
2026-10-31 12:06:27 -07:00
LGUG2Z 1da13d257b fix(nix): alias the spellings headers include each other by in the Windows SDK 2026-10-29 07:08:50 -07:00
LGUG2Z dbbf738d42 fix(nix): build the Windows SDK the same on every host, and with a CA bundle 2026-10-29 00:01:15 -07:00
LGUG2Z 76bae0630e build(nix): build and check for macOS and Windows
A flake that builds the recorder for macOS and cross-compiles it for Windows
from a Mac (xwin for the SDK, LLVM for the toolchain), with a dev shell for
each, and `nix flake check` running clippy for both targets, rustfmt, taplo,
cargo-deny and the tests.

The sources of komorebi for Mac and komorebi for Windows are flake inputs,
pinned in `flake.lock`: the recorder indexes them so that a line of komorebi's
log can be traced to the statement that wrote it, and the dev shells and every
derivation export where they are.
2026-10-27 22:22:56 -07:00