Home
The desktop itself, on any empty Space: the date, Customize, Make something, one line of system health (a failed service opens its log), pinned apps and a search pill.
Features
One desktop, a set of tools and a lot of careful defaults, grouped by what you'd be doing when you need them. Screenshots are the real shell from its smoke test, framed on the part that matters; select one to see the whole screen. Where no screenshot exists yet, the text says what the code does.
Hyprland · Quickshell · Quiet Glass UI
Frosted chrome over a quiet wallpaper or a slowly drifting light, opaque graphite where the work happens, IBM Plex type and one sage accent. The whole shell is Quickshell on Hyprland: bar, dock, Home, search, Spaces and every dialog.
The desktop itself, on any empty Space: the date, Customize, Make something, one line of system health (a failed service opens its log), pinned apps and a search pill.
The focused window's app and title (a click opens its menu: minimize, maximize, full screen, float, close), your Spaces, genui widgets, the tray, Tailscale, network, volume, battery, notifications, search, the clock, which opens the month with today's events, and you: your picture or initials open Lock, Log out, Sleep, Restart and Shut down. It tightens on small screens.
Maximize and close sit on each window's own title bar, in Quiet Glass: GTK and libadwaita apps, the terminal, Firefox; the window's name in the top bar opens its menu, minimize included. Windows keep 12 px corners with their menus and toolbars clear of the curve. Settings > Appearance can put minimize, maximize and close in the top bar beside the window's name instead, or hide them.
SuperShiftF maximize SuperQ closeThe k-hole mark at the top left is Home, and it talks: the ring swings on hover, a moon orbits while something works, the ring fills with an install's progress and breathes with your voice, and 51 small animations answer charging, messages, Do Not Disturb, updates and more. Each one means something and then goes still. Settings, Appearance, Logo animations: all, only important, or off.



A slim bar of icons, yours to arrange: drag to reorder while the others slide aside, drop one app on another for a folder, pull a tile off to remove it, keep a running app by dragging it in, with Undo for the last change. Up to five pages, or one scrolling row. Bottom, left or right; names on hover or always; glass, solid or none; magnification, auto-hide or smart hide, minimized windows, recent apps and Downloads and Trash stacks when you want them. Right-click for the app's own actions, Quit and Move to Space; notification counts and progress on the icons; files dropped on an app open with it. Super+Alt+D arranges it from the keyboard.
Apps ranked by how often you open them, open windows, Settings pages, actions, your tasks and their drafts, your genui panels (type a panel's name to open or close it), a calculator and "Make …". Apps meant for other desktops stay out of the list.
SuperSpaceSpaces shows every space as a small screen with its windows where they are, and the chosen one's windows large below, titled. Drag a window onto another space to move it. Hold Super and tap Tab to step through Spaces, let go to land. Alt+Tab works the same way: a quick tap flips to the previous window without drawing anything; hold Alt for live pictures of every window, minimized ones included. Alt and the key under Esc step through one app's windows, typing finds a window by name, Alt+W closes and Alt+M minimizes the chosen one. Settings, Software, the Library, Notes, Servers and Calendar are windows, so Alt+Tab reaches them and they stay open beside your work.
SuperTab AltTabPush into the top-left corner for a quarter of a second and Spaces opens. A pointer that just lands or parks there opens nothing.
Volume and output, what's playing, brightness for every screen, keyboard light, Wi-Fi, Bluetooth, Do Not Disturb, microphone, airplane mode, power mode and the ad blocker.
SuperAWhatever is playing: every player (Spotify, mpv, VLC, each browser tab) and every app making sound (a call, a game), each with the output it plays on. Move one to your headphones, Bluetooth or the monitor's speakers without moving the rest; pause, skip and seek; jump to the player's window. The bar shows what's playing while it plays, and the media keys drive the player you used last.
The shell is the notification server: toasts under the bar, a history behind the bell, Do Not Disturb with a VIP list of apps or words. mako takes over if the shell isn't running.
SuperShiftNVolume in 5% steps (Shift+Volume up to 150%), mic mute, screen and keyboard brightness, external monitors over DDC/CI, display mode, airplane, touchpad, calculator, lock, sleep. They work while the shell is down too.
Three fingers sideways switch Spaces, three up open search, four up or a pinch show all Spaces, four down show the desktop.
Hyprland has no minimize; k-hole adds one. "N minimized" in the bar lists them, and each goes back to the Space it came from.
SuperM SuperShiftMPages behind Home: Desktop 1 is your Desktop folder, more pages are folders inside it, and an empty one goes away when you leave it. Icons open, rename, drag and go to the Trash like a file manager.
SuperCtrl←→ SuperCtrlDPlain or sand, sage, sky, rose or accent, with undo and a reminder bell. "Notes" in search lists them all.
SuperCtrlNDay, week, month and agenda. Drag an event to move it, or its edge to make it longer; repeating events ask whether you mean one or all. Local calendars are plain .ics files; subscribe to a published calendar, or add a Nextcloud, iCloud or Fastmail account (CalDAV, the password in the keyring). Reminders ring even when the app is closed. Type lunch with Ana fri 12:30 in search to add one.
Type timer 25m tea or alarm 7:30 in search, or ring the bell on a note. Reminders are re-armed at login, and missed ones show late.
What you copy outlives the app it came from, in every format. Super+V brings back text, images and files from the history (never a password manager's copies). Ctrl+Shift+C copies in every terminal. Text in the desktop itself can be selected and copied.
SuperV CtrlShiftCPrint opens a capture bar: the screen, a window or an area you can adjust, as a photo or a video, to the clipboard, a file or both, with a delay if you need one. Shift+Print, Alt+Print and Ctrl+Print take an area, the focused window or the screen at once. A card with the picture offers Edit (Satty), Copy, Save, Show in Files and Delete.
Print ShiftPrintLock, suspend, log out, restart or shut down, with a spoken countdown, focus on Cancel and a "30 s more" button.
SuperShiftEWhen the screen dims, turns off and locks, and when the computer sleeps, set separately for battery and mains. What the lid does (also with a display connected) and the power button, a power mode per state, a charge limit where the battery allows it, battery health, the almost-empty action and what may wake it. Hibernate appears only when it works.
Windows, apps, terminals, the session and every Fn key, in one overlay.
Super/Hold Super and, after a moment, a see-through map of every Super shortcut appears over your work, grouped by what each does, or drawn on a keyboard. Add Shift, Alt or Ctrl while holding to see those; let go and it's gone. It never takes the keyboard, so the shortcut you're looking at still works, and binds you add yourself show up too.
Super holdDefault, graphite, sage, ice, lilac, rose and amber, or Custom: any accent and background tint from a colour picker, kept readable by the same contrast checks the design system passes. With glow, glass tint and frosted or solid glass (frosted stays dark and readable over any window), they recolour Hyprland, the lock screen, GTK, Qt, Ghostty, fuzzel, mako, the default apps and the icon theme.
Veil, Orbit, Eclipse and Signature, made for k-hole around its mark, and each accent brings its own: Veil with sage, Orbit with rose and amber, Eclipse with graphite, ice and lilac. Pick one by hand, choose No picture for Home's drifting glow, or drop your own into ~/Pictures/Wallpapers. The picture is cropped around its subject on any screen shape, dimmed just enough for the glass and the words on Home to stay readable, and blurred behind the lock screen. It costs nothing at rest: a still picture draws no frames.
Appearance, displays, sound, network, Bluetooth, keyboard, power, AI models, voice, remote, privacy, software, developer storage, accessibility and about. Changing a monitor's scale keeps its mode and moves its neighbours with it.
SuperIExtend, mirror, external only or built-in only, from a picker, the display key or when a screen is plugged in. A change you haven't kept goes back by itself after 15 seconds, so a black screen never sticks; the choice is remembered only once you press Keep.
SuperShiftPAt the first login: accent and glass, Wi-Fi and Tailscale, a model (a key from OpenRouter, Groq, Gemini, Cerebras or Mistral, or local models with Ollama), then a tour with a Try it for each feature and three live AI demos that ask before they install or run anything. Closing it brings it back once.
Web browser, terminal, text editor, files, email, music, video, images, PDF, office, archives, calendar and the screenshot editor: Settings > Default apps shows the app doing each one by its own name and icon, with a quick picker of the apps you have and the well-liked ones you don't (Chromium, Zen, Brave, LibreWolf, kitty, Alacritty, VS Code, Helix, Nautilus, Dolphin, Thunderbird, VLC, LibreOffice and more), installed in one click. The dock, Home, Super+B/N/E/Return, $TERMINAL and Thunar follow your choice. Searching "terminal" or "files" still finds them.
The khole icon theme draws each default app's glyph on a Quiet Glass tile. Zed, btop, mpv, zathura, imv and Satty get colours from the same tokens.
The config is Lua. Your changes live in ~/.config/hypr/local.lua, loaded last and never overwritten; an older local.conf is moved over once, and Settings lists binds that collide with yours.
If the shell is down, Super+R still opens fuzzel and the Fn keys still work.
SuperRgenui
Describe a widget, panel, command or service. Your model writes it, k-hole checks it in a sandbox with the network off, and you approve what it may do before it runs.
A widget lives in the top bar and refreshes on a timer; a panel floats; a command is a search entry that answers in a notification; a service is a systemd user timer.
Anthropic, any OpenAI-compatible API, local Ollama, or the built-in router with no key of its own. Keys stay in the login keyring, unlocked when you log in.
The backend runs once with no network, no D-Bus and read-only paths, and the QML loads headlessly in its own bubblewrap sandbox, first empty, then with sample data.
Reads, writes, network, D-Bus, processes and a router snapshot each appear in a table. A change in what a plugin asks for turns it off until you approve again.
An empty home, read-only /usr, its own process namespace, network only through pasta in its own namespace, D-Bus through a filtering proxy, a time limit and a 64 KB output cap.
Credentials, keyrings, browser profiles, shell history, login dotfiles and /run. Paths are checked again at run time, so a symlink can't swap one in.
No network APIs, dynamic loading, URLs, template literals, escapes, unbounded loops or recursion in generated QML. For plugins without network, links in their output are broken before they reach the screen.
Ask for a change in words. A plugin that fails its checks goes back to your model with the errors, a few rounds at most. Every change is a git commit you can undo or roll back to.
Each version is deployed read-only and the last five are kept.
Spend ticker, Free-tier fuel, Pod meter, Route map, Forty dots, Data meter, USB log, Memory pill, Two clocks, Hotspot badge, Engagement clock and Quick notes. Checked and approved like your own.
Plugins load in the background, and one that takes over 4 seconds to build is unloaded.
genui new, enable, edit, history, undo, show --source and doctor.
khole-flow · the Library
Your workflows and loops are your own jobs, on a schedule: post the next video at each posting slot, look for jobs three times a weekday and write a cover letter for each good one, answer customer email every hour. Say it in words or start from a template. Before anything runs you see what it reads, what it thinks with and what it does, and nothing goes out without your yes unless you said it may.



Sample data: these three are the real Library and the real engine, run against stand-in mail servers, a stand-in job board and a stand-in model. The shop, the people and the jobs are made up.
Say what the job is and when, and a model drafts the task, saved turned off. Or start from Job search, Inbox replies, Video post queue, Price watch or Weekly report and fill in what it needs.
Any email account (Gmail, Outlook, iCloud, Fastmail, Proton through Bridge and the rest), company job boards on Greenhouse, Lever, Ashby, Workable and SmartRecruiters, job alert emails from LinkedIn, Indeed, Glassdoor and Wellfound, feeds, web pages (only when they changed, prices too) and folders.
A model through the router decides what to do with each item and writes the words: a reply, a cover letter, a caption. Its answer is checked against the shape the task expects before anything acts on it.
Replies to, sends, labels and moves mail; writes cover letters into ~/Documents/k-hole/<task>; uploads to YouTube, posts to TikTok, or hands you an Instagram post with the caption ready to paste; calls a webhook.
You choose for each action. Asking makes a draft you approve, edit or skip, with one notification per run: Review or Approve all. After ten approvals of one step without changes it suggests letting that step act alone; it never switches by itself.
A test run reads for real and asks the model for real, and everything it would send becomes a test draft. Nothing is sent, nothing is marked read, no tracker rows are kept.
Every job, email or video it handled, with its status: new, drafted, applied, interview, offer for a job search. Change a status, filter, open the link, export a CSV.
What your tasks want from you now, the ones worth a test run, what runs next, what ran (with its cost) and each tracker's counts, on one page.
Every hour, weekdays at 9, 13 and 18, once at a date, or posting slots such as Tuesday and Friday at 18:00. A loop can end after a number of runs or when a condition is met, and says so.
If the computer was off or asleep at the time, the run happens late (within a window you set), is skipped with a note, or asks you. Never more than one catch-up.
The next run sets the clock's wake alarm through polkit, and the laptop goes back to sleep afterwards if the lid is closed or nobody is using it. A computer that's off can't wake: run that task in the cloud.
On Modal or your own server over SSH, checked every minute. Only the accounts a cloud task names, and that you allowed, go there. Its drafts show in Today like any other and are sent exactly once, whichever side you approve on.
The browser view has a Drafts screen: approve, edit or skip from the phone. Each phone needs its own approve right, off until you give it (full control doesn't include it), and the computer tells you which phone approved.
Each task has a model budget per month. When it's spent the task pauses until next month and tells you once. Local models and answers on your plan cost nothing.
Account passwords and tokens are typed once into the keyring (or a private file), never on a command line, and never shown in drafts, logs or the Library.
khole-flow templates, new --from-template, draft-task "…", run --test, today, drafts approve and tracker … export --csv.
The System tab holds the automations k-hole ships: workflows that react to your machine, and loops that keep a model on a goal with limits you set.
Charger in or out, a metered or changed network, window focus, a Space change, a stream starting or ending, a file changing, a USB device, a dev server starting or stopping, login, a time of day, or your own events.
Ask a model, run, notify, Do Not Disturb, power, Hyprland, HTTP, genui, set, if, wait, speak, screenshot, clipboard, router and save terminals. Conditions use their own small language, never eval.
Installing shows what a workflow may do, with risky permissions marked. A change to its permissions or trigger needs your approval again, and if it changed while the sheet was open, it stays off and says so.
Every loop has a maximum number of runs and a spending cap, checked against the router's usage, and can stop on a condition. Local and free models cost nothing.
Grid-down mode, Grid back, Quiet hours, On-call switch, Metered mode, Milestone freeze, Captive portal catcher, Spend brake, Site uptime check, Describe this screen, Weekly debris sweep and more.
Drag steps, set the trigger, inputs and permissions, and let "Match the steps" fill the permissions in. Your copy replaces the Library's.
CtrlS CtrlZAn on/off switch, Run now with each step's result as it happens, Options for inputs, and the last run's time and outcome.
On-call switch, Metered mode and Milestone freeze pause system updates until you're ready or a date passes.
The background service starts a monitor only for events an enabled workflow uses.
A workflow can call allowed dispatchers and settings only, never an arbitrary command through Hyprland.
khole-router · Ollama · khole-cloud
One local, OpenAI-compatible endpoint for every tool on the machine. Add keys once, or use the subscriptions you already pay for; routes pick a model you can reach and move on when one is rate-limited or down.
127.0.0.1:4141, started on demand for each user. Any app that takes an OpenAI base URL can use it.
OpenRouter, Groq, Cerebras, Gemini, Mistral, NVIDIA NIM, GitHub Models, Hugging Face, SambaNova, Cohere, Chutes, xAI, Together, DeepSeek, OpenAI, Anthropic, Ollama and LM Studio.
khole/free, fast, smart, code and local, plus your own. A step can name a model exactly or pick the newest one that matches a pattern.
A refused key rests 30 minutes, a rate-limited one as long as the provider asks, a silent provider from 30 seconds up to 10 minutes. A request that was sent is never replayed.
Several keys per provider, entered on stdin into mode-600 files, sent only over https or to this machine. Every client needs the router's own token.
A request from a browser page gets a 403, so a website can't spend your keys.
khole-router connect genui, opencode, env or claude writes the endpoint and token where each tool reads them.
Claude through your own Claude Code, ChatGPT through Codex, Qwen Code, Gemini CLI, a GitHub Copilot sign-in, and the Alibaba, GLM, Kimi and MiniMax coding plans answer like any provider. Answers show as on your plan at $0 and count against its limits; a plan that reaches its limit rests until the time it names and the next step answers. Anthropic doesn't allow Claude subscription sign-ins in other tools, so k-hole never touches Claude Code's login: your Claude plan answers only through Claude Code itself, signed in as you. Settings > AI models shows each one with its limits, when it rests, Test and Sign in (or khole-router plan list).
A ChatGPT Pro and a Plus, two Claude or Copilot accounts, two coding-plan keys: each signs in once into its own folder and is used in your order, the smaller plan first unless you change it. When one reaches its limit, the next one takes over Add, rename and reorder them in Settings > AI models, or khole-router plan add codex --account plus.
"Add your first key" with Groq, Gemini or OpenRouter, the model each step resolves to, provider health, a Test button, drag to reorder and 10 seconds of undo.
khole/stt tries Groq's free Whisper first, then OpenAI or whisper.cpp on this machine; khole/tts speaks.
Ollama built for CUDA, ROCm, Vulkan or the CPU, its context sized for the GPU, and khole-models pulls the largest model per role that fits your VRAM.
khole-cloud deploys vLLM on Modal (one container, stops when idle, proxy-token protected), adds a RunPod endpoint or any OpenAI-compatible URL as a provider.
whisper · decision model · kokoro
Optional and off until you turn it on. Hold a key and say what you want: whisper writes it down while you talk, a decision model decides what you mean, and it's done. Your AI model only steps in for open questions and tasks of several steps.


Hold Super+H while you talk, or tap Super+Shift+H and it listens until you pause.
SuperH SuperShiftHwhisper.cpp on this machine (CPU, Vulkan or CUDA, the model kept loaded) transcribes each phrase as you finish it, so the words are on the card and done when you stop. Or the router's speech route, online.
A decision model isn't a chatbot: from your words and what's on the desktop it picks what you want, which app, window or button, and how sure it is. Sure enough, and it's done at once. Not sure, or an open question: your model takes over. TypeSafe's (its first model is Jev, early access) comes ready to use with its key; new decision models are added as data in Settings > AI models, no update needed, and any chat model can stand in (it asks you more often, since its percentages aren't calibrated).
Opens apps and links, switches windows, presses buttons and links through the app's accessibility tree (no screenshot), types, sets volume, brightness, Do Not Disturb, Wi-Fi and Bluetooth, and runs workflows and genui actions. Your model can also look at the screen when nothing else works.
Kokoro, Piper or espeak-ng here, or an online voice, sentence by sentence; common phrases play at once, and the action comes first. Talk over it and it stops to listen.
Typing into a terminal or editor, sending, deleting, buying, anything in a password field: it asks, and listens a few seconds without the key. "Yes", "go ahead", "evet" or "no, open the other one" are understood on the machine; silence is never a yes.
Each request shows its cost, split into speech, decisions, model and voice, with a daily budget. A command the decision model settles costs about 0.004¢ at TypeSafe's price; the $0.10 per request limit is only a safety stop.
Your voice, words and screen never leave the computer (quick decisions are off then); otherwise the card says "Screen goes to" the provider whenever a cloud model sees it.
Esc, the stop button or saying "stop" ends everything at once.
EscIt listens only while you hold or tap the key.
Every action, decision (with its probabilities) and cost goes to voice-actions.jsonl; models download with their size shown and their checksum verified.
zellij · nix · mise · khole-clean · khole-servers
What you set up on every new machine, already set up, plus a few things that save you from yourself.
Every Ghostty window is a saved zellij session: the directory, the layout and 2000 lines of scrollback survive closing, a crash and a reboot. After a crash, a login notification offers to restore them.
SuperShiftTzellij's own keys are off; Ctrl+Alt+G unlocks it for one action and shows what's there. Idle closed sessions end after 12 hours.
CtrlAltGTerminal windows are titled by their folder and what runs in them ("k-flow-os — nvim"), never a session id. Give one a name and one of seven calm colours, or any hue: the background takes a tint, the border and cursor the colour, and the top bar, Alt+Tab and Spaces show it as a dot. Reopened or restored, it keeps both. Pick "Name and colour…" in the window's menu (click its name in the top bar), or run khole-term name / color inside it.
Every dev server you're running, named after its project (package.json, pyproject, Cargo, go.mod, a container) and recognised by framework: Next.js, Vite, Django, FastAPI, Rails, Go, Rust, databases and more. Port, address, uptime, memory and branch at a glance, a LAN chip when it listens beyond this machine, and Open, Copy, Logs, Restart and Stop (children too, after a question). The bar counts them; other users' services are listed read-only.
khole-workspace new <name> puts a branch in its own folder with its own ports and data, so two branches of one app run side by side. Removing it refuses while uncommitted work or data is there; --force packs that into an archive first.
direnv and mise in every tier; the Nix package manager and devbox in full.
Finds node_modules, virtualenvs, __pycache__, .next, Cargo target and build folders, shows what removing them frees, and cleans what you pick or what's untouched for 30 days. Files tracked by git are never touched.
pnpm, Bun and uv link from one store per ecosystem. npm goes to pnpm only in projects that already use pnpm, and pip outside a virtualenv points you to uv.
Claude Code, Codex, Gemini CLI, OpenCode, Aider, llm and the Hugging Face CLI, installed from upstream.
Python with uv and ruff, Node with pnpm and Bun, Go, Rust through rustup, clang, mold, cmake and ninja.
zsh with starship, fzf, zoxide, atuin, ripgrep, fd, bat, eza, neovim, lazygit, delta, difftastic and the GitHub CLI.
Rootless podman, buildah and distrobox in standard; Docker, kubectl, k9s, helm, kind and minikube in full, with Docker ports bound to localhost.
Overlays, the Library, voice, notifications and the indicator all answer qs ipc -c khole call …, so a key or a script can drive them.
khole-pkg why <name> says whether a package is in k-hole's lists and what needs it.
khole-block · ufw · Tailscale
Ads and trackers stop at DNS for every app, and the defaults assume the network isn't friendly.
A local resolver (blocky) with HaGeZi's lists, Pro plus a malware list by default, from Light to Ultimate.
Everything not blocked goes over DNS-over-HTTPS to Quad9, then Cloudflare, then your network.
If the blocker stops answering, a watch restarts it and then hands DNS back to your network, and takes over again once it's healthy.
5, 30 or 60 minutes, or 10 minutes of the network's own DNS for a captive portal. The bar reminds you while it's paused.
What was just blocked, with one-click Allow, a tester for any domain, and your own allow and block lists.
uBlock Origin in Firefox, uBlock Origin Lite in Chromium and Chrome, and their own encrypted DNS off so they don't skip the filter.
Tailnet names keep resolving, and phones on your tailnet can use the blocker too.
ufw denies inbound traffic except on Tailscale.
Private kernel pointers and dmesg, no unprivileged eBPF, protected FIFOs and files, no ICMP redirects.
LUKS2 in the installer, with the boot menu inside the encrypted disk.
Installs, updates and snapshots from the desktop go through one polkit action with a short list of allowed verbs; core and GPU packages can't be removed there.
AUR build scripts are shown before they build, the CachyOS repo script is pinned to a reviewed commit, and the Claude Code installer is downloaded and hashed, never piped.
Remote access and voice control start off; remote services listen on Tailscale only.
Secure Boot, TPM unlock and a signed package repository.
btrfs · snapper · khole-update
Arch speed with a way back: updates take a snapshot first, and snapshots boot.
snapper takes one before and after each pacman transaction, plus hourly and daily ones.
Each snapshot carries its own kernel and appears in the GRUB menu (or Limine on plain Arch).
khole-rollback makes a snapshot the running system again and keeps the one you left.
Update now takes a snapshot, says how much it will download, updates the system with one password prompt, then Flatpaks, and counts AUR updates for a terminal. A hold stops it and says whose it is: Keep the hold, or Update anyway.
Snapshot, keyring, pacman -Syu, AUR, Flatpak and k-hole itself, in one command.
A hold stops updates until you lift it or until a date, and --ignore-holds overrides it.
restic, from Settings > Developer storage: back up now or on a timer you turn on, keeping 7 daily, 4 weekly and 6 monthly copies, with a check that restores a sample and compares it. Setting it up again asks first, and keeps the old password so older backups still open.
khole-doctor checks disk space, failed services, a pending kernel, .pacnew files, snapshots, the firewall, Tailscale, the shell, the GPU driver and genui, and says how to fix each.
Every package k-hole knows about, by category, nothing installed until you tick it. Repo apps install in the window; AUR apps open a terminal so you can review them. When an install would also have to update other packages, it asks first (update the system and install, or not now) instead of leaving a half-updated system.
SuperPA watchdog restarts a stuck desktop shell; if it keeps crashing it comes back in software rendering, then opens a terminal that shows why.
The tools, the desktop and /usr/share/khole come from one pacman package, so pacman -Qkk khole knows every file.
Dotfiles you changed are left alone; the new default lands next to them as .khole-new. Symlinked dotfiles stay symlinks.
Tailscale · RDP · Moonlight · the browser
Reach your running desktop from a phone or another computer, over your tailnet.


Your running desktop in Microsoft's Windows App on an iPhone, sized to the phone and portrait when you hold it upright, with touch, pointer and keyboard modes.
Nothing from an app store: scan a QR code, add it to the Home Screen, pair with a PIN. Multi-touch or trackpad modes, a keyboard with modifier and Fn keys, the clipboard both ways, and sound. With an approve right, a phone can also approve your tasks' drafts.
Game-grade streaming, with a control bar for right-click, drag lock, scroll, zoom, sticky modifiers and a keyboard.
Connect by ID and password, or with any VNC client that encrypts.
A virtual output sized to the phone, with touch mapped to it.
Services listen on your Tailscale address; "LAN too" opens one service to your local network after a warning.
Secrets, the PIN and paired phones live in mode-600 files, never on a command line; forget a phone in one command.
While a stream runs, the screen doesn't lock and the desktop switches to hard cuts with no blur.
The browser app is tested in headless Chromium as an iPhone, not yet on a real one. Moonlight or RDP are the fallback.
k-chain · k-moon firmware · ESP32-S3 AMOLED
A small device beside your keyboard that talks to k-hole: voice, approvals for your coding agents, gestures that run workflows. The firmware (k-moon, its own C on ESP-IDF with LVGL for drawing) lives in the k-chain-os repository; the desktop half is in k-hole.






Hold the BOOT key and speak; k-hole hears it, decides and answers on the screen and through the speaker. A wake word sits behind a setting, off for now.
Resting, listening, thinking, acting, speaking, needs your yes, done, a problem: a glass orb with a nebula inside, composited on the chip from rendered pieces (it has no GPU), easing between states.
When Claude Code or Codex wants to run something, the card says what: Deny, or hold to allow for 600 ms. Allowing is never a voice command, and a tap on BOOT denies.
Face down holds Do Not Disturb, a double tap pauses the music, a shake locks the computer. Each is a k-hole workflow you can change or replace.
Media, volume, Do Not Disturb, lock, Presenting and timers go to k-hole; the time, brightness, timers and power saver work on the device even with the computer away.
It pairs with the PIN k-hole shows, keeps its token in its own storage and pins the desktop's certificate; never an unverified connection.
At 12 % with nothing running it dims to an ember on its own; the charger or 15 % brings it back.
The firmware builds and runs in Espressif's emulator, where a scripted tour plays every screen. The first build on the Waveshare board is next.
Orca · espeakup · motion
A screen reader from the boot menu to the installed desktop, a keyboard path to everything, and motion you can turn down.
The screen-reader entry speaks from the start, and speech carries into the installed system: espeakup on the console and login screen, brltty for braille, Orca at every login, and a tune when the boot menu is up.
Super+Alt+S turns it on or off, and it stays that way across logins.
SuperAltSCtrl+Alt+Tab walks the bar (tray icons and widgets included), the dock, the desktop page and the tour. Menu or Shift+F10 opens a tray menu.
CtrlAltTabReaches GTK apps and the terminal too.
44 px hit areas, on, off or while streaming, with hover effects off and presses held visible a little longer.
Full, Reduced (short fades, nothing slides or zooms) or Off, reaching Hyprland and GTK apps. System follows the desktop's own setting, live.
Without GPU acceleration the shell starts in software rendering with no blur, shadows or motion, and says why.
The power dialog counts down aloud, focuses Cancel and offers 30 seconds more.
The smoke test fails if the shell draws more than 4 frames in 65 seconds at rest. The light on Home pauses under overlays, when you're away, on battery and in power saver.
Every control has an accessible name and focus you can see.
qs ipc -c khole call shell perf shows frames per second for every shell window. At rest every row reads 0.
Four sound themes
Four original sound themes to choose from, Quiet Glass, Air, Arc and Bloom: 37 short cues each, quiet by design.
Quiet Glass, Air, Arc and Bloom: the same events and rules, each in its own voice. Play a theme's startup chime before you pick it; GTK apps and the terminal bell follow your choice.
Notifications, errors, a finished install, the charger, low battery, USB devices, screenshots, locking, logging out, voice control and remote sessions.
Once per session when the desktop is ready: full, short or off. Never on wake, unlock or a shell restart.
Except critical alerts, battery critical, voice control, the power countdown and the timers, alarms and reminders you set.
Two sounds at most at once, no stacking, and a rate limit on each.
A switch, a volume, the sound theme, the startup choice, and optional sounds each with a switch and a play button.
Drop files under the theme's names into its folder in ~/.local/share/sounds (khole for Quiet Glass, khole-air for Air...) to replace any cue.
timer 25m tea, alarm 7:30 or a note's bell plays one cue and shows a notification.
archiso · khole-install · install.sh
A live ISO that is the real desktop, an installer that sets up everything above, and GPU detection that picks the right drivers.
The live session is the full desktop, with Install k-hole on Home.
Live, with screen reader, safe graphics, basic graphics for black screens, and a text installer. Boot with khole.debug for a report of the live session.
A disk, your account, time zone, keyboard, optional encryption and ad blocking; no internet needed, and it can't be dismissed by accident while it runs.
Subvolumes for the system, home, logs, the package cache, snapshots, models, containers and Nix, with /boot inside so snapshots carry kernels.
GPT with EFI and BIOS boot partitions, GRUB for both, a hidden menu (Shift or Esc) that shows for 5 seconds when another OS is on the disk.
32 GB minimum; old LVM, RAID or LUKS on the target is released first, other disks aren't touched, and Windows appears in the boot menu.
After the first login, Welcome offers GPU drivers, the CachyOS layer, AUR apps and AI tools, and asks again until it's done or you skip it.
install.sh adds k-hole to Arch or CachyOS as a pacman package. Safe to re-run, with --dry-run to see every command.
Lite, standard or full, each a set of package lists you can read.
NVIDIA Turing and newer get the open driver and CUDA; Maxwell to Volta the 580xx driver and Vulkan; AMD ROCm; Intel Vulkan; hybrid laptops both.
Every device with a plain status and one action: install a driver, add missing firmware, switch a module. A snapshot comes first, and if none can be taken it asks before going on. Switching NVIDIA driver branches downloads first and keeps the old packages, so a failure puts them back.
x86-64-v3/v4 packages, the BORE kernel, sched_ext and zram.
A Quiet Glass GRUB menu and Plymouth splash with the disk password prompt and update progress; --no-splash leaves your boot alone.
os-release with the build and commit, a fastfetch logo, and About shows the edition and build.
virt-manager and GNOME Boxes recognise the ISO once the host knows it; khole-vm creates a VM with UEFI, virtio and 3D.
A QEMU test boots the ISO, installs it unattended on UEFI/NVMe, BIOS/SATA and encrypted UEFI, boots the result, rolls back and boots that too.
Build against a date in the Arch Linux Archive; the exact package list lands next to the ISO.
Keys
Build the ISO on any Linux with Docker, or add k-hole to an Arch install you already have.