Module header
A module is a TypeScript file with one export default defineAutomation({...}). Everything except run is the header: it must be literals only (strings, numbers, booleans, arrays and objects) because heliana reads it without running the code.
import { defineAutomation } from '@heliana/automation'Header fields
Section titled “Header fields”| Field | Meaning |
|---|---|
counters |
Named event counters. Each entry counts events of one kind inside a sliding window, per actor. |
game |
The game this module is written for. It must match the game of the organization. |
inputs |
Fields the operator fills in before a button runs. The shape of ctx.input is derived from this record. |
limits |
Per-minute ceilings on the bans and kicks of this module. They only narrow the platform ceiling, never raise it. |
name |
The display name of the automation. It is what the list and the run history show. |
pause |
Cooldown after a run. While it lasts the module does not start again for the same player, or at all when the scope is the automation. |
trigger |
What starts the module: an event, a button or a schedule. |
Trigger kinds
Section titled “Trigger kinds”| Kind | Meaning |
|---|---|
button |
A manual run from the player card or the server page. “on” says which subject the button acts on, “label” is the text on it. |
event |
Runs when the named event arrives from a connected server. The event key comes from the game vocabulary. |
schedule |
Runs on a timer: “every” takes a duration such as 15m, “cron” takes a five-field cron expression. “for” picks whether the run is per online player or per server. |
Durations use one grammar everywhere: a number and a unit s, m, h or d, for example 90s or 2h.
The same declarations ship in automation.d.ts.
export type Duration = `${number}${"d" | "h" | "m" | "s"}`
export interface NumberInput { readonly kind: 'number' readonly required?: boolean }
export interface TextInput { readonly kind: 'text' readonly required?: boolean }
export interface OptionInput { readonly kind: 'option' readonly options: readonly string[] readonly required?: boolean }
export type InputSpec = NumberInput | OptionInput | TextInput
export type Subject = "player" | "server"
export interface EventTrigger { readonly event: string readonly kind: "event" }
export interface ButtonTrigger { readonly kind: "button" readonly label: string readonly on: Subject }
export interface IntervalTrigger { readonly every: Duration readonly for: Subject readonly kind: "schedule" }
export interface CronTrigger { readonly cron: string readonly for: Subject readonly kind: "schedule" }
export type AutomationTrigger = ButtonTrigger | CronTrigger | EventTrigger | IntervalTrigger
export interface CounterSpec { readonly event: string readonly per: "actor" readonly window: Duration }
export interface PauseSpec { readonly for: Duration readonly per: "player" | "automation" }
export interface AutomationLimits { readonly bansPerMinute?: number readonly kicksPerMinute?: number }
export interface AutomationHeader { readonly counters?: Readonly<Record<string, CounterSpec>> readonly game: string readonly inputs?: Readonly<Record<string, InputSpec>> readonly limits?: AutomationLimits readonly name: string readonly pause?: PauseSpec readonly trigger: AutomationTrigger }