Recurfile Format Reference

A recurfile is a YAML configuration file that declaratively defines triggers and their associated actions. Recurfiles are registered with the daemon via recur register and live anywhere on the filesystem. Multiple recurfiles can be registered simultaneously; their configurations are merged by the daemon.

Default recurfile names, searched in order when no path is given to recur register: recur.yaml, recur.yml, .recur.yaml, .recur.yml.

Top-level structure

A recurfile is a YAML map. Every key is either the reserved key aliases or a group name.

  aliases:
  fs: core.fileevents

My Triggers:
  on:
    - type: FileCreated
  do:
    - shell: "echo {{.FilePath}}"
  

At least one group must be defined.

aliases

Type: map of string to string. Optional.

Defines shorthand names for plugin namespaces. Aliases declared at the file level are available to all groups in the file. Group-level aliases override file-level aliases of the same name.

  aliases:
  fs: core.fileevents
  notify: com.example.notifications
  

Aliases can be used anywhere a plugin namespace is accepted: trigger type values, namespace-qualified option keys, and template variables.


Group definition

Each non-reserved top-level key defines a group. The key is the group name (a free-form string).

  My Triggers:
  aliases:
    fs: org.other.filesystem
  options:
    recursive: true
  on:
    - type: FileCreated
  do:
    - shell: "echo {{.FilePath}}"
  

aliases

Type: map of string to string. Optional.

Group-scoped plugin namespace aliases. Overrides file-level aliases when the same short name is used.

  My Triggers:
  aliases:
    fs: org.other.filesystem
  

options

Type: map. Optional.

Default trigger options inherited by all triggers in this group. The available keys and value types are defined by the trigger plugin’s manifest. Per-trigger options override these values.

  My Triggers:
  options:
    recursive: true
    filter:
      - "*.md"
  on:
    - type: FileCreated
    - type: FileModified
      options:
        recursive: false
  

In this example, both triggers inherit filter: ["*.md"]. FileCreated inherits recursive: true; FileModified overrides it to false.

When option names conflict across plugins, qualify them with the plugin namespace or alias:

  options:
  fs.recursive: true
  

Options not recognized by any trigger in the group emit a debug-level warning. Setting an option to null is a validation error.

on

Type: list of trigger definitions. Required.

The list of triggers in this group. Must contain at least one entry.

  on:
  - type: FileCreated
  - type: FileModified
    options:
      recursive: false
    do:
      - shell: "echo modified {{.FilePath}}"
  

do

Type: list of action definitions. Optional.

Default actions applied to every trigger in this group that does not define its own do. A trigger with no do at either level is allowed but produces warnings at registration and when the trigger fires.

  do:
  - shell: "echo {{.FilePath}}"
  

Trigger definition

Each item in an on list defines a single trigger.

  on:
  - type: FileCreated
    name: "Source watcher"
    options:
      recursive: false
    do:
      - shell: "echo {{.FilePath}}"
  

type

Type: string. Required.

The trigger type name from an installed plugin. May be unqualified (FileCreated), namespace-qualified (core.fileevents.FileCreated), or alias-qualified (fs.FileCreated). Matching is case-insensitive, though following the plugin’s declared casing is recommended.

If the referenced plugin is installed but not active, the CLI may prompt to enable it during registration. If the plugin is not installed, registration fails.

name

Type: string. Optional.

A user-defined label for identification and organization. When set, the name is used as the display name in CLI output and is searchable by recur inspect and other commands.

options

Type: map. Optional.

Trigger-specific options that override group-level options. The available keys and value types are defined by the trigger plugin’s manifest.

  on:
  - type: FileCreated
    options:
      recursive: true
      filter:
        - "*.go"
  

do

Type: list of action definitions. Optional.

Actions for this specific trigger. When present, overrides the group-level do entirely (no merging).

  on:
  - type: FileCreated
    do:
      - shell: "go build ./..."
      - notify: "Build complete"
  

Action definition

Actions appear in do lists at either the group level or the trigger level. Two forms are supported: shorthand and detailed.

Shorthand form

A single-key map where the key is the action plugin name (or alias or fully qualified namespace) and the value is mapped to the plugin’s shorthand option.

  do:
  - shell: "echo {{.FilePath}}"
  - notify: "Build complete"
  - com.example.slack: "#general Build done"
  

Plugin name matching is case-insensitive. The reserved keys type and options cannot be used as plugin names in shorthand form.

Detailed form

type

Type: string. Required (in detailed form).

The action plugin type, alias, or fully qualified namespace.

name

Type: string. Optional.

A user-defined label for identification and organization. When set, the name is used as the display name in CLI output and is searchable by recur inspect and other commands. Only available in the detailed form.

options

Type: map. Optional.

Action-specific options. The available keys and value types are defined by the action plugin’s manifest.

  do:
  - type: shell
    name: "Build step"
    options:
      shell: bash
      command: "cat {{.FilePath}}"
      params:
        - "--key=val"
        - "--flag"
  

Specifying both type and a shorthand plugin key in the same action entry is a validation error.


Template variables

Action option values support Go template syntax to reference trigger context values. Available variables are declared in the trigger plugin’s manifest context list.

  do:
  - shell: "echo {{.FilePath}} was created at {{.TriggeredOn}}"
  

Templates are validated at registration time against the trigger’s declared context variables. References to undeclared variables are a registration error. If a plugin fails to provide a declared variable at runtime, the action errors with a log message.

When an alias qualifies a trigger, the alias can also qualify template variables.

{{ .Test }}

A special boolean variable, always available regardless of the trigger plugin. Set to true when the trigger is fired via recur test. Useful for conditional behavior in actions.


Inheritance and resolution

All inheritance follows the pattern: more-specific overrides less-specific.

WhatResolution order (highest priority first)
Trigger optionsPer-trigger options > group options > plugin manifest defaults
Actions (do)Per-trigger do > group do
AliasesGroup aliases > file aliases

Setting an option value to null is a validation error. To exclude an inherited option, move the trigger to a separate group.


Cross-file merging

When multiple registered recurfiles define the same group name:

ElementBehavior
Triggers (on)Appended as separate registrations. A warning is emitted at registration.
Group-level actions (do)Merged into a combined action list. A warning is emitted.
Group-level optionsConflicting values are a validation error. Resolve by moving options to per-trigger level.
aliasesConflicts (same short name, different namespace) are a validation error.

The fully merged configuration is queryable via recur inspect group.


Context file fallback

For cases where templates are insufficient, the daemon writes trigger context as key-value pairs to a temporary file unique to each trigger event. These are loaded as environment variables scoped to the action’s process. The context file is cleaned up after the action completes.