It's not highlighted much in the writeup, but most of the interaction takes place in the terminal. The original assignments just use text mode. The graphics mode got started when I tried to implement ANSI escape codes in the terminal, but some of the effects weren't possible in text mode. I changed the bootloader to switch the system into a known graphics mode, then implemented a terminal emulator on top of that. From there it was just a small matter of mouse drivers and windowing commands.
JOS is a unix-inspired exokernel. It has virtual memory with thread isolation, a pre-emptive scheduler (round-robin, I think), and IPC. Everything else lives in user-land. As alluded to, the disk drivers even run in a user-land process which has been given access to the disk IO port. My windowing system is also a user-land process, which leases out buffers of memory as windows and has been given access to the memory-mapped screen buffer.