zc-workstationDocumentation PDF GitHub

What zc-workstation is

Set up a developer workstation on macOS, Linux and Windows from one YAML file: packages, dotfiles and runtimes, planned before anything changes.

.md

One YAML file says what a workstation needs: the packages, the dotfiles, the language runtimes. zc-workstation reads what this machine has, prints the difference, and only if you ask, closes it. Every apply is checked by planning again.

$ zc-workstation plan
CREATE  brew      cask:ghostty           install with brew
CREATE  brew      mas:uBlock Origin Lite install with mas
UPDATE  dotfiles  .gitconfig             update; changed outside chezmoi, apply overwrites it
CREATE  runtimes  java@temurin-25        install with mise

What it manages

Provider Reads Changes with

packages

A Brewfile, an apt or dnf package list, or a winget import file

brew, mas, apt-get, dnf, winget

dotfiles

A chezmoi source directory

chezmoi apply, one path at a time

tools

A mise config file

mise install

desktop

A wallpaper and a screen saver page

osascript, WebViewScreenSaver

settings

macOS preferences

defaults

services

Homebrew services and launchd agents

brew services, launchctl

localdir

Files written inline in the config

Direct writes inside one directory

It does not reimplement these tools. chezmoi already handles templates, secrets and per-machine differences, and mise already resolves versions. zc-workstation adds one plan across all of them, a dashboard, and the same rules for every surface.

One config, three systems

A target can name the systems it is for. The same file then describes the Mac, the Linux laptop and the Windows desktop:

targets:
  - {name: brew,   provider: packages, os: [darwin],  file: packages/Brewfile}
  - {name: apt,    provider: packages, os: [linux],   file: packages/apt.txt}
  - {name: winget, provider: packages, os: [windows], file: packages/winget.json}
  - {name: dotfiles, provider: dotfiles, source: home}
  - {name: runtimes, provider: tools, file: mise.toml}

A target for another system is skipped, and shown as skipped.

The loop

  1. Plan asks each provider what is missing and lists actions: CREATE, UPDATE, DELETE and MANUAL. Planning writes nothing.

  2. Apply runs the actions in order, then plans again. A change that ran but did not take is reported as still outstanding, never as done.

  3. Saved plans pin what was reviewed. plan -out writes the plan, and apply FILE refuses when the machine changed since.

  4. MANUAL is what no tool should do for you, such as installing the package manager itself or trusting a mise config. The plan says what to run.

Five surfaces, one contract

The CLI is the contract. The dashboard, the menu bar app, the MCP server, the agent skills and scripts all go through the same plan and apply, with the same refusals.

On a Mac, the menu bar app also has ZC Care, a window that cleans junk and what AI tools leave behind, uninstalls apps with their leftovers and finds what fills the disk.

A new Mac

Keep the config in its own repo, and a new Mac needs one command. See A new Mac in one command.

Edit this page Last updated

Keyboard shortcuts

Ctrl/⌘ K or /
Search the docs
↑ ↓ Enter
Move through the search results
← →
Previous or next page
f
Filter the pages in the sidebar
g h
Home
t
Cycle the theme
?
This list
Esc
Close a menu or the search results