Skip to content

Instantly share code, notes, and snippets.

@intellectronica
Created September 26, 2026 10:10
Show Gist options
  • Select an option

  • Save intellectronica/859cd8ae9ed0fb991dd8239de0e7ef92 to your computer and use it in GitHub Desktop.

Select an option

Save intellectronica/859cd8ae9ed0fb991dd8239de0e7ef92 to your computer and use it in GitHub Desktop.
Silent Paseo scheduled tasks: suppressing finish notifications (unofficial hack)

Silent Paseo scheduled tasks (an unofficial hack)

Paseo schedules start a fresh agent on each run. When that agent finishes, Paseo notifies you: an in-app notice if you are active in the app, or a push notification if you are away. As of Paseo 0.9.2 there is no per-schedule setting to turn this off.

This matters for:

  • Silent jobs that should run without telling you anything.
  • Conditional alerts, where you want to hear about something only when a specific condition is met, and silence otherwise.

This note describes a workaround. It relies on internal behaviour, so treat it as a hack that a future Paseo release may break.

How it works

The Paseo daemon decides whether to send the "agent needs attention" notification when an agent finishes, errors or asks for permission. Before sending it, the daemon checks whether the agent is a delegated agent (subagent), meaning it has a paseo.parent-agent-id label. Subagents never notify you directly, because their parent agent is meant to handle the result.

Scheduled agents have no parent, so they always notify. However:

  • Every agent Paseo launches has PASEO_AGENT_ID (its own ID) and PASEO_CLI (the path to the Paseo CLI) in its environment.
  • paseo agent update <id> --label key=value can set any label on a running agent, including paseo.parent-agent-id.

So the scheduled agent can label itself as a subagent of a made-up parent at the start of its run. When it finishes, the daemon treats it as a subagent and sends no notification.

Relevant source, in getpaseo/paseo:

  • packages/server/src/server/agent/agent-manager.ts: broadcastAgentAttention() returns early when isDelegatedAgent(agent) is true.
  • packages/protocol/src/agent-labels.ts: isDelegatedAgent() checks for a non-empty paseo.parent-agent-id label.

Setup

1. Make the job silent

Put this at the very top of the schedule's prompt:

Before doing anything else, run this shell command exactly once:

"$PASEO_CLI" agent update "$PASEO_AGENT_ID" --label paseo.parent-agent-id=silent-schedule

This suppresses Paseo's finish notification for this run. If the command fails, carry on with the task anyway; do not report or retry it.

The value silent-schedule is arbitrary. Use any non-empty string that is not a real agent ID. Don't use the agent's own ID: archiving an agent also archives its children, and that could cause odd self-referential behaviour.

When creating a new schedule from the CLI:

paseo schedule create \
  --name "My silent job" \
  --cron "0 * * * *" \
  --timezone Europe/London \
  --provider claude \
  --cwd /path/to/repo \
  "$(cat prompt.md)"

For an existing schedule, keep a backup of the current prompt first, then prepend the instruction:

ID=<schedule-id>
paseo schedule inspect "$ID" --json | jq -r .prompt > prompt.backup.md
{ cat silent-preamble.md; echo; cat prompt.backup.md; } > prompt.new.md
paseo schedule update "$ID" --prompt "$(cat prompt.new.md)"

The agent needs to be allowed to run shell commands without asking for permission. A permission prompt would stall the run and also notify you.

2. Notify only when something happens

Once Paseo is silent, the prompt decides when you hear from the job. Tell the agent to send a message through a channel you choose, and to do so only when the condition is met. For example:

If <condition>, send a notification with <tool/command> containing <details>.
Otherwise, do nothing and stop without sending anything.

Suitable channels include:

  • ntfy: curl -d "message" ntfy.sh/<topic>.
  • A Slack or Discord webhook.
  • An email CLI.
  • osascript -e 'display notification "…"' on macOS.
  • Your own notification inbox API.

For recurring checks, ask the agent to use a stable ID per event where the channel supports one, so repeated runs don't send duplicate messages.

Verify it

  1. Create a throwaway schedule that runs once immediately:

    paseo schedule create --every 1h --run-now --max-runs 1 \
      --name "Silent label test" --provider <provider> --cwd /tmp \
      'Run this shell command exactly, before doing anything else:
    
    "$PASEO_CLI" agent update "$PASEO_AGENT_ID" --label paseo.parent-agent-id=silent-schedule
    
    Then reply with the single word: done'
  2. When the run has finished, check that the label was applied:

    paseo schedule inspect <schedule-id> --json | jq '.runs[] | {status, agentId, output}'
    paseo inspect <agent-id> --json | jq .ParentAgentId   # expect "silent-schedule"
  3. Confirm that no Paseo notification arrived, then delete the test schedule:

    paseo schedule delete <schedule-id>

If you run the test from inside a Paseo agent session, prefix the command with env -u PASEO_AGENT_ID. Otherwise the CLI may create the schedule as a child of your current agent, which makes the test meaningless.

Side effects and caveats

  • Errors are silenced too. A run that fails shows only in paseo schedule inspect <id> and the run history.
  • There is a short window at the start. The label is applied a moment after the agent starts. If the run crashes before the command runs, you still get a notification.
  • Runs disappear from workspace views. Paseo can't find the made-up parent, so the agent drops out of the workspace's agent list and status indicators. The schedule's run history and output are unaffected.
  • Subagents stay silent. If the scheduled agent starts its own subagents, they report back to the scheduled agent as normal, and you don't hear from them either.
  • It depends on the model following instructions. A model that skips or reorders steps won't apply the label. Keep the instruction short, first and explicit.
  • It isn't supported. It depends on undocumented internals, last checked against Paseo 0.9.2. If notifications come back after an update, check whether broadcastAgentAttention() still skips delegated agents.

Undo

Restore the original prompt:

paseo schedule update <schedule-id> --prompt "$(cat prompt.backup.md)"

A cleaner long-term fix would be a per-schedule notification setting in Paseo itself, such as always, on-error or never.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment