crofty 0.17.0 — a local preview that can't linger
crofty preview wraps a blocking hugo server so you can see your site in a
browser. Press Control-C and it stops. But when an AI backgrounds it to keep
working, there’s no Control-C to press — so the server just keeps running.
0.17.0 gives preview a lifecycle anyone (or any agent) can drive from a separate process, without changing the foreground Control-C experience.
Before
A backgrounded preview had no off switch. Nothing recorded that it was running, so a second process couldn’t find it, couldn’t tell whether one was up, and couldn’t stop it. It lingered until the machine went down.
After
While it runs, preview records .crofty/preview.json (its own pid, hugo’s pid,
port, url, timeout) — machine state, gitignored, never content. Two subcommands
act on it:
$ crofty preview status
Preview is running at http://localhost:1313/ (pid 87265).
It auto-stops at 2026-07-07T13:02:58+09:00. Stop it now with 'crofty preview stop'.
$ crofty preview stop
Stopping preview (pid 87265, http://localhost:1313/)...
Stopped.
status --json gives an agent the same answer as a machine-readable object:
{
"running": true,
"url": "http://localhost:1313/",
"pid": 87265,
"port": 1313,
"startedAt": "2026-07-07T12:57:58+09:00",
"timeoutAt": "2026-07-07T13:02:58+09:00"
}
Two more guards make “forever” impossible:
--timeout(default 30m, 0 = off) auto-stops a preview, so a backgrounded one can’t linger past the backstop.- Singleton — starting a preview reaps one that’s already running, so at most one runs per project and re-running heals a forgotten one.
stop ends both the wrapper and hugo by pid, so hugo is never orphaned. crofty agent now teaches the stop/status/timeout lifecycle, and Windows is covered too
— process control is split by build tag so it compiles and works there.