Client

Your side of Cronhoster is a single folder of plain JavaScript. On the reference machine it lives at ~/Developer/LIVE/Cron; in your own setup it is whatever you point contentRoot at. The client mirrors that whole tree to your server — files and sub-folders alike — so the folder on disk is the single source of truth. There is no per-domain partitioning as in sitehoster; it is one flat script directory.

The cron folder

Author entry points at the top level, and organise everything else however you like underneath.

~/Developer/LIVE/Cron/
  digest.every.30m.cron.js     entry point — a job
  backup.daily.0300.cron.js    entry point — a job
  report.hourly.00.cron.js     entry point — a job
  report.hourly.30.cron.js     entry point — same base name, twice an hour
  lib/                         supporting modules (imported, never run)
    format.js
    mailer.js
  _scratch.every.5s.cron.js    ignored — leading _
  _env.json                    ignored — secrets, stays on the server
  .DS_Store                    ignored — dotfile

What syncs, what stays local

Almost everything syncs. The exceptions are named so you can keep drafts and secrets in the same folder without them ever leaving your machine or running:

NameBehaviour
Top-level <name>.every|daily|hourly.…cron.jsAn entry point — synced and run on its schedule.
Any other file or sub-folderA supporting module — synced and importable, but never invoked on its own.
Starts with _Ignored entirely: never synced, never run. For drafts and for _env.json secrets.
Starts with . (dotfiles)Ignored entirely — editor and VCS cruft never leaves your machine.

Develop in place

Because the leading _ hides a file from the sync and the runner, the natural way to write a new job is to draft it behind an underscore, run it by hand while you iterate, and drop the underscore to go live:

_cleanup.daily.0400.cron.js   →  drafting: local only, not running
cleanup.daily.0400.cron.js    →  rename to go live: next sync runs it

You can execute a draft directly with Node while you work — a cron script is just a module, so node _cleanup.daily.0400.cron.js runs it once against your own machine.

The edit loop

Run the client resident with --watch and it re-syncs as you save, so the folder on the server tracks the folder on your disk without you thinking about it. See the Commands reference for every flag.

node client/sync.js --config config.json --watch

Pull run logs back down the same way when you want to see how a job behaved on the server:

node client/sync.js --config config.json --pull-logs

How a set of edits becomes live

A single save can touch several files — a new entry point plus the library it imports. The sync is designed so the runner never sees that change half-applied: it keeps running the last complete version of your folder until the whole new set has arrived and been verified, then switches over as a unit. In practice you just save and the right thing happens; the note below is the design behind it.

Watch your base names

The base name — the part before the schedule keyword — is a job's identity and its mutex key. Two files that share a base name are treated as the same job for the single-instance rule. That is exactly what you want for the twice-an-hour idiom (report.hourly.00 + report.hourly.30), but it can bite if it happens by accident.

See also