Commit Graph
19 Commits
Author SHA1 Message Date
LGUG2Z df4ab2d2a5 docs(repo): how it fits together, per platform, and why
The model (the host axis and the flavor axis, the master clock, the facade, the
rules and the layer that enforces each), the same questions answered for each
host, the decisions behind the design, and the checkpoints to run on a Windows
machine, including the installer.
2026-10-27 22:22:56 -07:00
LGUG2Z 28cfdaa463 feat(viewer): view a recording
`komorebi-recorder view <session>` opens a recording in a window: the video of
every display, a timeline with a lane for the bug regions, events, log errors,
the machine and the findings, and an inspector for the state at the playhead,
one event traced end to end, and komorebi's log. The window is untitled so
komorebi leaves it alone, and out of any recording being made. It is where a bug
is marked: the form takes the region from the selection or the playhead and asks
what went wrong and what was expected. It opens from the recorder window as
well.
2026-10-27 22:22:56 -07:00
LGUG2Z 52a45aa17b feat(winprobe): ask Windows what it thinks of a window
komorebi for Windows hides a window by cloaking it in place, so its state cannot
show whether a window is really hidden. `record --probe-windows` follows each
window event with a read of the window's real state from Windows and, now and
then, asks komorebi whether it manages the window. The analysis compares the
two: a window komorebi shows that Windows hides, one it hides that Windows
shows, and a visible window it does not manage. macOS refuses the flag with a
message.
2026-10-27 22:22:56 -07:00
LGUG2Z 069347060d feat(analysis): see what the screen did
When and where on each display the picture changed, found by decoding the video,
and a contact sheet of frames with the times, events and bug region marked. A
display with no video for part of a range has a gap there instead of an invented
frame.
2026-10-27 22:22:56 -07:00
LGUG2Z 26963391a3 feat(analysis): investigate from what you marked
The brief starts from what the user marked as the bug, in their words, and ranks
the events most worth tracing first; findings an agent concludes are saved with
the evidence they cite, which must exist. The commands arrive: `state`, `diff`,
`events`, `window`, `trace`, `code`, `brief`, `overview`, `search`, `annotate`,
`annotations`, `guide` and `schema`, all with `--json`, and a search is bounded
by a budget.
2026-10-27 22:22:56 -07:00
LGUG2Z 079f1ac6d0 feat(analysis): explain one event, follow one window
One event end to end: what its handler logged, what other threads logged
meanwhile, and every change with who made it and how sure that is. The state,
the diff and the events are answered as plain values, an overview ranks what
stands out in a recording, and invariants flag states that are wrong: a window
in two containers, a window parked off screen on the workspace that is showing
(a rule that holds only where komorebi hides windows by moving them, so it is
skipped on Windows).
2026-10-27 22:22:56 -07:00
LGUG2Z 72419d89a2 feat(analysis): what komorebi believed, and what changed
A komorebi `State` is read into monitors, workspaces and windows through each
flavor's rules, and what changed between two states is said in terms a person
would use. `at`, `range`, `summary` and `locate` ask what the recording holds
around a video time, and the other way round, with the text and JSON the later
commands share.
2026-10-27 22:22:56 -07:00
LGUG2Z e3a1f01fd7 feat(doctor): check what a recording leans on
`doctor` says what the machine can do for a recording: which komorebi runs and
how it logs, whether the screen can be captured and played back, the displays
and their scale, and the host clock. Probes measure one thing: the clock across
a sleep, a short capture, a decode, whether komorebi would tile a window of
ours.
2026-10-27 22:22:56 -07:00
LGUG2Z 3e30d81bc5 feat(av): decode the recorded video
Reading the video back: AVFoundation on macOS, the Media Foundation source
reader on Windows, a clear error elsewhere. A request for the frames between two
times is answered with the frame that was on screen at the start, even when the
decoder had to seek to an earlier key frame. `selftest` records a rendered
on-screen clock and compares the clock the video shows with the time the session
predicts.
2026-10-27 22:22:56 -07:00
LGUG2Z 5291a24fd4 feat(app): the recorder window
Run with no command, `komorebi-recorder` opens a small window with Record and
Stop. It is untitled and borderless because komorebi does not manage windows
without a title, so opening it does not move the layout under investigation, and
it keeps itself out of the video (by process name on macOS, with
`WDA_EXCLUDEFROMCAPTURE` on Windows). `komorebi-recorder-gui` is the same
program built for the GUI subsystem on Windows, so that a shortcut opens no
console; both are in the zips and the installer.
2026-10-27 22:22:56 -07:00
LGUG2Z 05d87908c5 feat(recorder): orchestrate a recording
`komorebi-recorder record` starts every source in the order that makes the
non-video sources a superset of the video, stops them in reverse, and
checkpoints the manifest as it goes, so that a recorder that is killed leaves a
session `reindex` can recover. `--no-video` records everything but the screen,
and Ctrl-C or `--duration` stops and finalizes a recording. The format of
`annotations.jsonl`, the append-only file that bug regions, notes and findings
are written to, is defined here too. The command table arrives with it, with
`displays` and `reindex`, and with the text-and-JSON conventions the later
commands share.
2026-10-27 22:22:56 -07:00
LGUG2Z 1006ec2570 feat(timeline): index a session
`timeline.jsonl` is a merged, time-sorted index that points into the raw files
by byte range, so the raw files are never rewritten and the index can be rebuilt
at any time. It places komorebi's log, events, the OS trace and the recorder's
own incidents on one timeline, and answers what was around a video time and
where in the video a log line or event is. `frames` extracts PNG frames from the
recorded video with ffmpeg, which is never used to capture.
2026-10-27 22:22:56 -07:00
LGUG2Z 383cc3c3db feat(power): ride out sleep, lock and display changes
Docking, sleep and lock are where komorebi bugs show up, so the recording
carries on through them. On Windows a hidden window hears suspend, resume, the
lid, the displays and session lock as Windows delivers them; on a Mac a sleep is
found because the host clock pauses while the wall clock does not, and the lock
is polled on both hosts. A tracker turns these into reactions: a display that is
gone has its video finalized at once, one that returns starts a new segment, and
every stream is started afresh after a wake instead of trusting the old one.
2026-10-27 22:22:56 -07:00
LGUG2Z fb11cb2db9 feat(capture): record the screen
Screen capture behind a `CaptureBackend`: ScreenCaptureKit and AVFoundation on
macOS (HEVC by default), Windows Graphics Capture and a Media Foundation writer
on Windows (H.264). Each display is written as fragmented mp4 in segments with
every frame's master-clock timestamp, and a manager decides, from what the
backend reports, when a segment ends and another begins. The segment logic is
shared by both backends and tested without a screen.
2026-10-27 22:22:56 -07:00
LGUG2Z 9d35869f88 feat(sources): the OS trace
What the OS says while komorebi acts: the unified log (`log stream`) on macOS,
one file per managed application, komorebi's process and the system; on Windows
the WinEvents komorebi hears, folded when repeated, and the Event Log's warnings
and its display, power and GPU providers. Both end up as `oslog/*.ndjson` on the
master clock, and a host with no OS trace says so instead of failing.
2026-10-27 22:22:56 -07:00
LGUG2Z 4724d831ba feat(session): the session directory
A session is a directory and its manifest, `session.json`: the host, the
komorebi flavor, the clock anchors, the log segments and the applications seen,
written atomically. komorebi's own log is recorded as the exact byte range
written while recording (`%TEMP%` on Windows, its data directory on a Mac),
together with the version of the komorebi that wrote it. A generated README in
each session says what every file is, quoting paths the way the host's shell
reads them.
2026-10-27 22:22:56 -07:00
LGUG2Z c748237741 feat(komorebi_link): record what komorebi says
The recorder subscribes to komorebi over its socket (a unix socket on macOS,
`uds_windows` on Windows) and writes every notification with the state it came
with, stamped on the master clock. Its accept loop only hands off to a writer
thread, since komorebi notifies subscribers while holding its locks. What
happens to the recording itself (a komorebi that exits, a stream that dies) is
written as incidents, and a lock file says whether a recorder is still running
in a session.
2026-10-27 22:22:56 -07:00
LGUG2Z 0de0f82840 feat(flavor): read komorebi for Mac and for Windows
Which komorebi produced a session is a separate axis from the host the recorder
ran on. `Flavor` names the two and `Rules` holds what each knows: what its
events look like on the wire, which of them move a window, and which are
komorebi making things up. komorebi for Mac and komorebi for Windows each
implement it, and a missing method is a compile error. The Windows rules were
written from komorebi's source and say so until a recording confirms them.

Events are classified through the rules, and the names of things in a session
(`event:12`, `log:7`) are parsed here too, with the envelope and exit codes
every command will answer in.
2026-10-27 22:22:56 -07:00
LGUG2Z d5eacecef8 feat(clock): the master clock
Every record in a session is stamped on one monotonic clock:
`mach_absolute_time` on macOS and `QueryPerformanceCounter` on Windows, behind a
`platform` facade with a third `unsupported` host that builds anywhere. Anchors
pair that clock with the wall clock, a map interpolates between them, and a jump
detector notices sleep and clock steps by comparing how far each moved. Video
timecodes are parsed and printed here too.

`Host` and `ClockKind` say what a session was recorded on.
2026-10-27 22:22:56 -07:00