deckhand looks at a Mac and writes down what it finds — processes, ports, disks, startup items — as one plain JSON file. A small web page shows the result, and a local model can answer questions about it.
- Runs a handful of read-only collectors — hardware, memory, processes, network, installed software, autostart items, disk — and writes what they find to a single snapshot file.
- Never deletes, kills, or changes anything. Cleanup ideas come back as a command to run yourself, not an action it takes.
- Serves a small web page that renders the snapshot as a set of cards, plus a box for asking it questions.
- Works from the command line too — scan, print a summary, or ask a question without opening the page at all.
- The snapshot is just a file. The web page and the CLI are only two of the things that can read it — anything else is free to as well.
node deckhand.mjs scan # snapshot the machine -> data/snapshot.json
node deckhand.mjs show # human summary of the last snapshot
node deckhand.mjs serve # web UI on :7789 (DECKHAND_PORT to change it)
node deckhand.mjs ask "what's eating my disk?"No install, no dependencies, no build step — Node 22+, macOS.
Asking it things needs Ollama running locally with a
model pulled. The default is qwen3.5:9b; set DECKHAND_MODEL to use a
different one.
A scan writes to data/snapshot.json (left out of the repo — it describes one
particular machine). The shape is always the same: a schema version, when it
was captured, which host it's from, per-collector timing, and then one
top-level key per collector — hardware, memory, processes, network,
installed, autostart, disk.
Any other program can consume it the same way the web UI does: read the file, parse the JSON, use whatever section it needs. Nothing about the collectors assumes the web page or a model is the only thing reading their output.
Type a question into the box, or run ask from the terminal, and a local
model answers using only the facts in the last snapshot — nothing is sent
anywhere. Every answer is checked before it's shown: a figure that doesn't
appear in, or follow from, the snapshot gets flagged under the answer rather
than trusted quietly.
examples/demo-snapshot/ holds a made-up snapshot — an invented machine
(studio-mac), invented processes and ports, one disk — so the page can be
seen without scanning anything real. Point serve at it with an env var and a
throwaway port:
DECKHAND_SNAPSHOT=examples/demo-snapshot/snapshot.json DECKHAND_PORT=8080 \
node deckhand.mjs serveThe screenshots above and below were both taken from that demo snapshot.

