Schedule @devintern/code to drain your backlog continuously via systemd timers or cron

Automated Task Processing

Run @devintern/code on a schedule, without manual intervention. On modern Linux servers the recommended approach is systemd timers — you get structured logs via journalctl, restart-on-failure semantics, and no root crontab access required. Cron still works on any Unix-like system and is shown second as a fallback (macOS, BSD, Alpine, containers without an init system).

systemd timers

A systemd job is a pair of unit files: a one-shot .service that runs devintern, and a .timer that triggers it on a schedule.

Every 10 minutes — process Intern-labeled tasks

/etc/systemd/system/devintern-intern.service:

[Unit]
Description=Process Intern-labeled tasks with @devintern/code
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=devintern
WorkingDirectory=/path/to/your/project
ExecStart=/usr/local/bin/devintern \
  --jql 'statusCategory = "To Do" AND sprint in openSprints() AND labels IN (Intern) ORDER BY created DESC' \
  --max-turns 500 \
  --create-pr \
  --pr-target-branch master
StandardOutput=journal
StandardError=journal

/etc/systemd/system/devintern-intern.timer:

[Unit]
Description=Run @devintern/code every 10 minutes

[Timer]
OnBootSec=2min
OnUnitActiveSec=10min
Persistent=true

[Install]
WantedBy=timers.target

Enable, start, and inspect:

sudo systemctl daemon-reload
sudo systemctl enable --now devintern-intern.timer

# Show next scheduled run
systemctl list-timers devintern-intern.timer

# Tail recent runs
journalctl -u devintern-intern.service -f

Hourly — process AutoImpl-labeled tasks

Same .service shape, swap the ExecStart JQL:

ExecStart=/usr/local/bin/devintern \
  --jql 'status = "To Do" AND labels IN (AutoImpl)' \
  --create-pr

And use an hourly timer:

[Timer]
OnBootSec=5min
OnUnitActiveSec=1h
Persistent=true

[Install]
WantedBy=timers.target

Twice daily — high-priority bug sweep

For wall-clock schedules, use OnCalendar instead of OnUnitActiveSec. This timer fires at 09:00 and 17:00 every day:

[Timer]
OnCalendar=*-*-* 09,17:00:00
Persistent=true

[Install]
WantedBy=timers.target

Matching .service:

ExecStart=/usr/local/bin/devintern \
  --jql 'type = Bug AND priority = High AND status = "To Do" AND labels IN (Intern)' \
  --max-turns 300 \
  --create-pr

Cron

If you’re on a system without systemd, the same three jobs work as crontab entries:

# Process tasks labeled "Intern" in open sprints every 10 minutes
*/10 * * * * cd /path/to/your/project && devintern --jql 'statusCategory = "To Do" AND sprint in openSprints() AND labels IN (Intern) ORDER BY created DESC' --max-turns 500 --create-pr --pr-target-branch master >> /tmp/devintern-cron.log 2>&1

# Process AutoImpl-labeled tasks every hour
0 * * * * cd /path/to/your/project && devintern --jql 'status = "To Do" AND labels IN (AutoImpl)' --create-pr >> /tmp/devintern-cron.log 2>&1

# Process high-priority bugs twice daily
0 9,17 * * * cd /path/to/your/project && devintern --jql 'type = Bug AND priority = High AND status = "To Do" AND labels IN (Intern)' --max-turns 300 --create-pr >> /tmp/devintern-cron.log 2>&1

Important Notes

  • Set WorkingDirectory (systemd) or cd (cron) to your project directory so the correct .devintern-code/.env is loaded
  • Use absolute paths to the devintern and agent binaries, or pin PATH explicitly in the unit file
  • For systemd, journalctl -u <unit> gives you logs; for cron, redirect stdout/stderr to a log file
  • Use ORDER BY created DESC to process newest tasks first
  • Test your JQL query manually before scheduling