pub struct Trigger {Show 20 fields
pub name: String,
pub schedule: Schedule,
pub prompt: String,
pub description: Option<String>,
pub timezone: Option<String>,
pub enabled: bool,
pub created_at: Option<DateTime<Utc>>,
pub provider: Option<String>,
pub model: Option<String>,
pub workspace: Option<PathBuf>,
pub permission_mode: PermissionMode,
pub tools: Vec<String>,
pub skills: Vec<String>,
pub no_mcp: bool,
pub max_turns: Option<u32>,
pub max_output_tokens: Option<u64>,
pub max_cost_usd: Option<f64>,
pub timeout: Option<String>,
pub catch_up: CatchUp,
pub notify: Option<String>,
}Expand description
One scheduled prompt.
Fields§
§name: StringThe file’s stem. Never read from the file itself — a name that can disagree with its filename is a class of bug with no upside.
schedule: ScheduleFive-field cron, in timezone.
prompt: StringWhat to ask. This is the whole action: a trigger runs an agent, not a command. (Scheduled commands are what cron is for, and giving one a place in this store would mean answering how it gets confined and which environment it sees — questions the MCP and sandbox work already answered the expensive way.)
description: Option<String>One line for mecha trigger list.
timezone: Option<String>IANA name. Written explicitly by mecha trigger add, resolved from
[agent] timezone at the time: “07:00” must not quietly mean something
different after a config edit.
enabled: bool§created_at: Option<DateTime<Utc>>The anchor for the first fire. Without it a trigger added at 08:00 would find 07:00 unfired and run immediately.
provider: Option<String>§model: Option<String>§workspace: Option<PathBuf>The path jail for this run. Defaults to the daemon’s working directory, which is usually not what you want — say it.
permission_mode: PermissionModeRead-only by default. See the module docs: an unattended run has nobody to ask, and outbox staging works at every level.
tools: Vec<String>Only these tools, if set. The narrowest useful control there is: a briefing that can read mail and nothing else cannot be talked into anything else.
skills: Vec<String>Skills this run may load. Empty means none, which is the opposite
of the tools field above and is deliberate.
A trigger is an unattended run with nobody to ask, so “what does this
run actually do” has to be answerable from the trigger file. If the
model could load any skill in the store, the effective instruction set
of a scheduled run would be larger than its file shows, and it would
grow every time the user wrote an unrelated skill — the same reason
trigger show prints the resolved workspace rather than leaving an
omitted line to be interpreted.
So this defaults closed and the schedule names what it needs. Note the
asymmetry with tools: an empty allowlist there means “the usual
surface”, because that surface is fixed and reviewable, where the skill
store is a directory the user adds to.
no_mcp: boolSkip MCP servers entirely for this run.
max_turns: Option<u32>§max_output_tokens: Option<u64>§max_cost_usd: Option<f64>Needs prices on the provider. A cap that cannot fire is refused at load
rather than ignored at 03:00 — see Trigger::validate.
timeout: Option<String>Wall-clock ceiling on one run. Cancels at the next safe point, keeping the partial answer, exactly as Ctrl-C does.
catch_up: CatchUp§notify: Option<String>A command run when the trigger produces an answer, with the answer on
stdin — notify-send, a mail invocation, an append to a file.
An observer, like post_tool: its failure is logged and never fails the
run. The answer is already in the session transcript, which is the
record; this is delivery.
Implementations§
Source§impl Trigger
impl Trigger
pub fn new( name: impl Into<String>, schedule: Schedule, prompt: impl Into<String>, ) -> Self
Sourcepub fn valid_name(name: &str) -> Result<()>
pub fn valid_name(name: &str) -> Result<()>
A trigger name is a filename, a log line, and a CLI argument. Keep it to what is unambiguous in all three.
Sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Everything that can be wrong with a trigger before it ever runs.
Called on load, so a typo surfaces on mecha trigger list at a
keyboard, not on the fire it was meant to control.
pub fn timeout_duration(&self) -> Duration
Sourcepub fn next_fire(
&self,
at: DateTime<Utc>,
fallback_tz: Option<Tz>,
) -> Option<DateTime<Utc>>
pub fn next_fire( &self, at: DateTime<Utc>, fallback_tz: Option<Tz>, ) -> Option<DateTime<Utc>>
When this trigger would next fire after at.
Sourcepub fn due(
&self,
last_slot: Option<DateTime<Utc>>,
now: DateTime<Utc>,
fallback_tz: Option<Tz>,
) -> Due
pub fn due( &self, last_slot: Option<DateTime<Utc>>, now: DateTime<Utc>, fallback_tz: Option<Tz>, ) -> Due
Is it due, and if not, when?
last_slot is the most recent slot that has already been accounted for
— fired, or deliberately skipped. None means nothing has, in which
case created_at is the anchor: a trigger must not fire for a slot that
predates its own existence.