CLI Reference

worker generators

add event, add listener, add job and add worker: scaffold background work for the cmd/worker binary.

Four generators scaffold the worker side: events, listeners and scheduled jobs. new project already includes the cmd/worker binary; add worker adds the worker layer to a project that doesn't have one yet.

add event

go tool gpsystem add event <module> <name>

Creates internal/modules/<module>/events/<name>.go (an event struct + EventName()) and, on the module's first event, wires an outbox events.Dispatcher into its Dependencies and constructs it in both cmd/<module>/main.go and cmd/worker/main.go. Idempotent: a second event reuses the dispatcher. Records the event in gpsystem.yaml.

go tool gpsystem add event orders orderPlaced

Then add fields to the generated struct and dispatch it from a service inside Transactor.WithinTransaction (see events).

add listener

go tool gpsystem add listener <module> <event> <name> [--queue <queue>]

Creates a listener stub in <module> and registers it in listeners/register.go. <event> is name for an event the module owns, or producer.name to subscribe to another module's event.

FlagMeaning
--queueasynq queue the listener runs on (default: the default queue)
go tool gpsystem add listener orders orderPlaced sendConfirmationEmail --queue emails
go tool gpsystem add listener shipping orders.orderPlaced reserveStock   # cross-module

The event must already exist (add event first). Each listener is an independent, retried task: implement the body idempotently.

add job

go tool gpsystem add job <module> <name> --cron "0 3 * * *"

Creates a job handler stub and schedules it in jobs/register.go. --cron accepts 5-field cron specs and asynq descriptors (@every 30m, @daily).

go tool gpsystem add job orders expireStaleCarts --cron "0 * * * *"

add worker

go tool gpsystem add worker

Adds the worker layer (binary, queue wiring, listener/job scaffolding) to a project that doesn't have one yet: the cmd/worker binary, each module's listeners/ and jobs/ subpackages, the outbox migration, and the Valkey/worker config. new project and new module already wire this in for you, so add worker is what you reach for when a project was assembled without it. For a compose.yml / .env.example that lack the anchors, it prints the block to paste rather than failing (those files are not compiled).

What gets wired

GeneratorCreatesWires (at // gpsystem:* anchors)
add eventevents/<name>.goDispatcher field in register.go; its construction in cmd/<module> and cmd/worker
add listenerlisteners/<name>.goevents.Listen(...) in listeners/register.go
add jobjobs/<name>.gosched.Job(...) in jobs/register.go
add workercmd/worker, listeners//jobs/ subpackage per module, outbox migrationworker/valkey config; each module into the worker main
There is a fifth module-level generator, documented separately because it wires a shared framework resource rather than the worker: add mail scaffolds a mail notifier (internal/modules/<module>/mail/) and, on a project's first notifier, wires mail.Mailer into every entry point. A mail notifier is typically called from a listener generated here; see the contact-email worked example.
Copyright © 2026