Skip to content

Cron & Dispatch

SWEny becomes most powerful when it runs on autopilot. Put it on a cron schedule and it continuously monitors your production systems, triages errors, and opens fix PRs — without anyone clicking a button.

Use GitHub Actions schedule trigger to run triage on a recurring basis. The cron syntax uses UTC time.

name: SWEny Triage
on:
schedule:
- cron: '0 9 * * 1-5'
workflow_dispatch:
permissions:
contents: write
issues: write
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
dd-api-key: ${{ secrets.DD_API_KEY }}
dd-app-key: ${{ secrets.DD_APP_KEY }}
time-range: 24h
on:
schedule:
- cron: '0 */6 * * *'
workflow_dispatch:

With time-range: 6h to match:

- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
dd-api-key: ${{ secrets.DD_API_KEY }}
dd-app-key: ${{ secrets.DD_APP_KEY }}
time-range: 6h

Twice a week (Monday and Thursday mornings)

Section titled “Twice a week (Monday and Thursday mornings)”
on:
schedule:
- cron: '0 6 * * 1,4'
workflow_dispatch:
PatternSchedule
0 9 * * 1-5Weekdays at 9:00 AM UTC
0 */6 * * *Every 6 hours
0 6 * * 1,4Monday and Thursday at 6:00 AM UTC
0 0 * * *Daily at midnight UTC
0 */2 * * *Every 2 hours
30 8 * * 1-5Weekdays at 8:30 AM UTC

The workflow_dispatch trigger lets you run triage on demand from the Actions tab. Add inputs to make it configurable:

name: SWEny Triage
on:
workflow_dispatch:
inputs:
time-range:
description: 'Time window to analyze'
required: false
default: '24h'
type: choice
options: ['1h', '6h', '24h', '7d']
dry-run:
description: 'Analyze only, do not create issues or PRs'
required: false
default: false
type: boolean
service-filter:
description: 'Service filter pattern'
required: false
default: '*'
permissions:
contents: write
issues: write
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
dd-api-key: ${{ secrets.DD_API_KEY }}
dd-app-key: ${{ secrets.DD_APP_KEY }}
time-range: ${{ inputs.time-range }}
dry-run: ${{ inputs.dry-run }}
service-filter: ${{ inputs.service-filter }}

This surfaces a form in the GitHub Actions UI where you can select the time range, toggle dry run, and filter services before running.

Trigger the implement workflow automatically when a specific label is added to an issue:

name: SWEny Implement
on:
issues:
types: [labeled]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
implement:
if: github.event.label.name == 'sweny-implement'
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
issue-override: '#${{ github.event.issue.number }}'

Label an issue sweny-implement and SWEny picks it up, writes a fix, and opens a PR.

Use repository_dispatch to trigger implementations from external systems (webhooks, chatbots, other workflows):

name: SWEny Implement
on:
repository_dispatch:
types: [sweny-implement]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
implement:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
issue-override: ${{ github.event.client_payload.issue }}
additional-instructions: ${{ github.event.client_payload.instructions }}

Dispatch it with:

Terminal window
curl -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/repos/OWNER/REPO/dispatches \
-d '{"event_type": "sweny-implement", "client_payload": {"issue": "ENG-123"}}'

The most common pattern: one workflow for automated triage on a schedule, and another for on-demand implementation.

.github/workflows/sweny-triage.yml
name: SWEny Triage
on:
schedule:
- cron: '0 9 * * 1-5'
workflow_dispatch:
permissions:
contents: write
issues: write
pull-requests: write
jobs:
triage:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
dd-api-key: ${{ secrets.DD_API_KEY }}
dd-app-key: ${{ secrets.DD_APP_KEY }}
time-range: 24h
.github/workflows/sweny-implement.yml
name: SWEny Implement
on:
issues:
types: [labeled]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
implement:
if: github.event.label.name == 'sweny-implement'
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: swenyai/triage@v1
with:
claude-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
issue-override: '#${{ github.event.issue.number }}'

This creates a clean handoff: triage runs daily, finds issues, and creates tickets. When you are ready to fix one, add the sweny-implement label and SWEny writes the PR.

  • Start with daily cron and dry-run: true. Review the results for a week before enabling issue creation and PRs.
  • Match time-range to your schedule to avoid duplicate investigations.
  • Always include workflow_dispatch alongside schedule so you can trigger manually for debugging.
  • Set timeout-minutes: 60 (or higher for thorough depth) to give the agent enough time to complete.
  • Use novelty-mode: true (the default) to skip issues that already have tickets, keeping your backlog clean.
  • Browse the Marketplace if you want a starting workflow for a different scheduling pattern — competitive scans, content pipelines, weekly digests.