Local command scheduling

Keep the schedule with the code.

Define shell commands and schedules in YAML, commit them with your project, and run them through one local service backed by SQLite.

Task lifecycle
~/reporting $ runbinder add --enable reports.runbinder.yaml
[RUNBINDER] Registered task "reports.daily".
~ $ runbinder run reports.daily
[RUNBINDER] Task "reports.daily" completed successfully.
~ $ runbinder list
ID NAMESPACE ACTIVE YAML TZ DIRECTORY LAST RUN
1 reports.daily true OK America/New_York /srv/reporting 2026-09-03 06:00:04 (SUCC)
~ $ runbinder log -n 2 reports.daily
Fetched 142 records
Report written to reports/daily.pdf

What it handles

A scheduler with a deliberately small footprint.

RunBinder is for commands that belong to one machine and should remain visible beside the project they operate on.

01 / SCHEDULE

More than one clock.

Use cron, fixed times of day, or repeated intervals inside a daily window. Combine forms and evaluate each task in its own IANA time zone.

02 / CONTROL

Bounded execution.

Set a global concurrency limit, prevent scheduled runs from overlapping, and discard delayed occurrences beyond a configurable grace period.

03 / INSPECT

State you can see.

List registered tasks, spot definition drift, inspect the latest result, tail command output, and check the scheduler heartbeat from the CLI.

How it works

From a file in your project to a task you can manage anywhere.

Registration stores a validated snapshot. Source edits remain visible as drift but do not change a running schedule until you update it.

01 / DEFINE

Put the schedule beside the work.

Create one small YAML file in your project. It is readable in review, easy to commit, and travels with the code it runs.

~/reporting/reports.runbinder.yaml
namespace: reports.daily
command:
- ./scripts/build-report.sh
cron: "0 6 * * *"
working_dir: .
timezone: America/New_York
02 / REGISTER

Validate it once.

Register the file when you are ready. RunBinder validates it, resolves the working directory, and stores the snapshot under a namespace you can use from any directory.

~/reporting
~/reporting $ runbinder add --enable reports.runbinder.yaml
[RUNBINDER] Registered task "reports.daily".
Task is enabled and ready for the service.
03 / SCHEDULE

Start one background service.

RunBinder handles due schedules with bounded concurrency, run history, logs, and overlap protection. Run it detached on Linux or macOS, or in the foreground under a service manager.

~/reporting
~/reporting $ runbinder service --detach
[RUNBINDER] Service started in the background (PID 23287).
~/reporting $ runbinder status
Is Service Running: TRUE
04 / OPERATE

Use the namespace from anywhere.

Check the YAML state, run a task now, inspect its output, or pause it. The commands work from any directory once the task is registered.

~
~ $ runbinder list
ID NAMESPACE ACTIVE YAML TZ DIRECTORY LAST RUN
1 reports.daily true OK America/New_York /srv/reporting 2026-09-03 06:00:04 (SUCC)
~ $ runbinder run reports.daily # ad hoc one-off run
~ $ runbinder log reports.daily
Fetched 142 records
Report written to reports/daily.pdf
~ $ runbinder disable reports.daily

Right-sized orchestration

Built for jobs that belong to one machine, not distributed workflows. Definitions stay in Git; registrations, run history, and service health stay local. See the configuration reference for the full YAML contract.

Get started

One command. One binary.

Install with Go 1.24 or newer, ensure your Go binary directory is on PATH, then run runbinder init inside a project. Detached service operation is supported on Linux and macOS.

go install github.com/evanjhopkins/RunBinder/cmd/runbinder@latest