Skip to main content
Cue supports eleven event types. Each type watches for a different kind of activity and produces a payload that can be injected into prompts via template variables.

app.startup

Fires exactly once when the Maestro application launches. Ideal for workspace setup, dependency installation, health checks, or any initialization that should happen once per session. Required fields: None beyond the universal name, event, and either prompt or prompt_file. Behavior:
  • Fires once per application launch
  • Does NOT re-fire when toggling Cue on/off in Settings
  • Does not re-fire on YAML hot-reload (deduplication by subscription name)
  • Resets on session removal (so re-adding the session fires again on next app launch)
  • Not affected by sleep/wake reconciliation
  • Works with fan_out, filter, output_prompt, and prompt_file
Example:
Payload fields:

time.heartbeat

Fires on a periodic timer. The subscription triggers immediately when the engine starts, then repeats at the configured interval. Required fields: Behavior:
  • Fires immediately on engine start (or when the subscription is first loaded)
  • Reconciles missed intervals after system sleep - if your machine sleeps through one or more intervals, Cue fires a catch-up event on wake
  • The interval resets after each trigger, not after each run completes
Example:
Payload fields: None specific to this event type. Use common variables like {{CUE_TRIGGER_NAME}} and {{CUE_EVENT_TIMESTAMP}}.

time.scheduled

Fires at specific times and days of the week - a cron-like trigger for precise scheduling. Required fields: Optional fields: Behavior:
  • Checks every 60 seconds if the current time matches any schedule_times entry
  • If schedule_days is set, the current day must also match
  • Does not fire immediately on engine start (unlike time.heartbeat)
  • Multiple times per day are supported - add multiple entries to schedule_times
Example - weekday standup:
Example - multiple times daily:
Payload fields:

time.once

Fires exactly once at a specific wall-clock moment, then deletes itself from cue.yaml. This is the subsystem to reach for when a user says “in 20 minutes do X”, “tomorrow at 9am email me a summary”, “remind me at 4pm to push the rc branch”, or “schedule a 1h check-in” - anything that maps to a single action tied to a clock. Required fields: Optional fields: Behavior:
  • Poll-based at roughly 30-second granularity
  • Fires once when the wall clock crosses fire_at
  • Self-destructs from cue.yaml after a successful run (status completed)
  • On failed or timeout, also self-destructs unless self_destruct_on_failure: false
  • Supports all standard action values: prompt (default, runs the configured agent with the rendered prompt), notify (surfaces a toast through the owning agent - clicking it jumps there), and command (shell or CLI invocation)
  • The CLI command maestro-cli cue schedule is the supported way to create time.once subs - it handles ISO formatting, timezone offsets, target_node_key generation, and writes directly to the owning agent’s .maestro/cue.yaml. Do not hand-author time.once subscriptions.
Example - notify reminder:
Example - prompt run:
Payload fields: The standard {{CUE_TRIGGER_NAME}}, {{CUE_EVENT_TYPE}}, {{CUE_EVENT_TIMESTAMP}}, and {{CUE_PIPELINE_NAME}} variables are also available. Creating, listing, and cancelling:

file.changed

Fires when files matching a glob pattern are created, modified, or deleted. Required fields: Behavior:
  • Monitors for add, change, and unlink (delete) events
  • Debounces by 5 seconds per file - rapid saves to the same file produce a single event
  • The glob is evaluated relative to the project root
  • Standard glob syntax: * matches within a directory, ** matches across directories
Example:
Payload fields: The changeType field is also available in filters.

agent.completed

Fires when another Maestro agent finishes a task. This is the foundation for agent chaining - building multi-step pipelines where one agent’s completion triggers the next. Required fields: Behavior:
  • Single source (string): Fires immediately when the named agent completes
  • Multiple sources (list): Waits for all named agents to complete before firing (fan-in). See Fan-In
  • The source agent’s output is captured and available via {{CUE_SOURCE_OUTPUT}} (truncated to 5,000 characters)
  • Matches agent names as shown in the Left Bar
Example - single source:
Example - fan-in (multiple sources):
Payload fields: These fields are also available in filters. The triggeredBy field is particularly useful when a source agent has multiple Cue subscriptions but you only want to chain from a specific one. See Selective Chaining for a complete example.

task.pending

Watches markdown files for unchecked task items (- [ ]) and fires when pending tasks are found. Required fields: Optional fields: Behavior:
  • Scans files matching the glob pattern at the configured interval
  • Fires when unchecked tasks (- [ ]) are found
  • Only fires when the task list changes (new tasks appear or existing ones are modified)
  • The full task list is formatted and available via {{CUE_TASK_LIST}}
  • File content (truncated to 10K characters) is available via {{CUE_TASK_CONTENT}}
Example:
Payload fields:

github.pull_request

Polls GitHub for new pull requests using the GitHub CLI (gh). Optional fields: Behavior:
  • Requires the GitHub CLI (gh) to be installed and authenticated
  • On first run, seeds the “seen” list with existing PRs - only new PRs trigger events
  • Tracks seen PRs in a local database with 30-day retention
  • Auto-detects the repository from the git remote if repo is not specified
Example:
Payload fields:

github.issue

Polls GitHub for new issues using the GitHub CLI (gh). Behaves identically to github.pull_request but for issues. Optional fields: Behavior: Same as github.pull_request - requires GitHub CLI, seeds on first run, tracks seen issues. Example:
Payload fields: Same as github.pull_request, except: The branch-specific variables ({{CUE_GH_BRANCH}}, {{CUE_GH_BASE_BRANCH}}) are not available for issues.

cli.trigger

Fires only when explicitly triggered from the command line via maestro-cli cue trigger <name>. Unlike other event types, cli.trigger has no background watcher or poller - it waits for a manual invocation. No additional fields required - just name, event, prompt, and optionally enabled. Behavior:
  • Does nothing on its own - only fires when you run maestro-cli cue trigger <subscription-name>
  • Supports an optional --prompt flag to override or supply the prompt at invocation time
  • The override text is available in the prompt template as {{CUE_CLI_PROMPT}}
  • Ideal for deployment scripts, CI/CD integration, on-demand reviews, or ad-hoc automation
Example:
Triggering from the command line:
Discovering available subscriptions:
Payload fields:

webhook.received

Fires when an external service POSTs to Maestro’s local webhook listener. This is the generic escape hatch: anything that can send an HTTP request - GitHub, GitLab, Slack, a CI system, a cron box, your own script - can drive a Cue pipeline, and the filter decides which payloads matter. Required fields: webhook sub-fields: A secret is mandatory. A webhook path with no authentication is a remote trigger for an AI agent running with your credentials, so a subscription without secret or secret_env fails config validation rather than quietly starting to listen. The listener:
  • One listener serves every webhook subscription across every agent. It starts when the first one loads and stops when the last one unloads.
  • Binds to 127.0.0.1:17997 by default. Override with MAESTRO_CUE_WEBHOOK_PORT and MAESTRO_CUE_WEBHOOK_HOST.
  • To take deliveries from the public internet, point a tunnel (ngrok, cloudflared) or a reverse proxy at the loopback port. Binding the listener itself to 0.0.0.0 is possible but puts an agent trigger directly on your network.
  • Only POST is accepted. Bodies over 1 MB are rejected with 413.
  • Multiple subscriptions may share a path. Each authenticates independently, and every one that passes receives the delivery.
Authenticating a delivery: Without signature_header, the sender presents the secret:
Authorization: Bearer <secret> works too. With signature_header, the sender signs the raw body with HMAC-SHA256 and sends the digest in that header. Both bare hex and the sha256=<hex> form GitHub and GitLab use are accepted - so pointing a GitHub webhook at Maestro with signature_header: X-Hub-Signature-256 and the same secret works with no glue code. Example:
Filtering: Filters read the event payload with dot-notation, so one endpoint can fan different payloads to different pipelines:
Payload fields: Template variables: Secrets never reach the payload: the Authorization, Cookie, X-Maestro-Cue-Secret, and configured signature headers are stripped before the event is built, so they cannot leak into a prompt, the activity log, or the Cue database.