Turn GitHub issues into supervised runs of your shell scripts and AI agents – declaratively, observably, on your own machine.Aus GitHub-Issues werden überwachte Runs deiner Shell-Skripte und KI-Agenten – deklarativ, nachvollziehbar, auf deinem eigenen Rechner.
Node.js ≥ 22.13 · Linux & macOS · SQLite built in (no native add-on)Node.js ≥ 22.13 · Linux & macOS · SQLite eingebaut (kein natives Addon)
Why adispatchd?Warum adispatchd?
Running coding or review agents against an issue tracker usually ends up as a pile of cron jobs and glue scripts: who picks which issue, what happens when an agent crashes, who resets the labels, where are the logs? adispatchd moves those decisions into a few YAML files – GitHub stays the source of truth, workers stay plain programs, and technical failures are kept apart from business results.
Wer Coding- oder Review-Agenten auf einen Issue-Tracker loslässt, landet meist bei einem Haufen Cronjobs und Klebeskripten: Wer nimmt welches Issue, was passiert bei einem Absturz, wer setzt die Labels zurück, wo liegen die Logs? adispatchd verlegt diese Entscheidungen in wenige YAML-Dateien – GitHub bleibt Source of Truth, Worker bleiben normale Programme, und technische Fehler sind von fachlichen Ergebnissen getrennt.
FeaturesFunktionen
GitHub as task sourceGitHub als Aufgabenquelle
Issues and pull requests, including GitHub Projects fields (status, priority, custom fields), native dependencies and the issue's work branch and PR.
Issues und Pull Requests inklusive GitHub-Projects-Feldern (Status, Priorität, eigene Felder), nativen Abhängigkeiten sowie Arbeits-Branch und PR des Issues.
Declarative filtersDeklarative Filter
all/any/not trees and named filters reused across workflows and views. Missing access yields unknown – never a wrong start.
all/any/not-Bäume und benannte Filter für Workflows und Views. Fehlender Zugriff ergibt unknown – nie einen falschen Start.
Priorities & limitsPrioritäten & Limits
Workflow priority first, then item priority rules. Global, per-workflow and per-source concurrency limits, a lock per item and retry blocks.
Erst Workflow-Priorität, dann Item-Prioritätsregeln. Globale, workflow- und sourcebezogene Limits, ein Lock je Item und Retry-Blocks.
Visible conditions & info tilesSichtbare Bedingungen & Info-Kacheln
Named start conditions with their last result in the UI, and dashboard tiles from dashboard.yaml – small scripts run in the background (text, number or percent with thresholds).
Benannte Startbedingungen mit ihrem letzten Ergebnis in der UI und Dashboard-Kacheln aus dashboard.yaml – kleine Skripte, im Hintergrund ausgeführt (Text, Zahl oder Prozent mit Schwellwerten).
Your dashboard, your layoutDein Dashboard, dein Layout
Arrange the dashboard in dashboard.yaml: rows, columns and widths, views as widgets with chosen sections and row limits, and tabs – inactive tabs load nothing, the selected tab is part of the URL.
Das Dashboard in dashboard.yaml anordnen: Reihen, Spalten und Breiten, Views als Widgets mit gewählten Abschnitten und Zeilenlimit, dazu Reiter – inaktive Reiter laden nichts, der gewählte Reiter steht in der URL.
Poll GitHub, run on a cron schedule with time zone, or start manually from the UI/API with typed parameters – pick a branch, tag or a value from your own script in the start form. One workflow can serve several repositories.
GitHub abfragen, per Cron mit Zeitzone laufen oder manuell aus UI/API mit typisierten Parametern starten – im Startformular einen Branch, Tag oder Wert aus einem eigenen Skript wählen. Ein Workflow kann mehrere Repositories bedienen.
Lifecycle hooksLifecycle-Hooks
on_start, on_success, on_failure, crash/timeout/cancel hooks, on_result.<outcome> for named results, a catch-all on_error and on_retry_block/on_retry_unblock when a retry block is created or removed.
on_start, on_success, on_failure, Hooks für Absturz/Timeout/Abbruch, on_result.<outcome> für benannte Ergebnisse, der Sammel-Hook on_error sowie on_retry_block/on_retry_unblock, wenn ein Retry-Block entsteht oder aufgehoben wird.
Move items across your board as runs start and end. Idempotent (read before write), journaled and retried; items are added to the project if needed.
Items wandern beim Start und Ende eines Runs über das Board. Idempotent (erst lesen, dann schreiben), mit Journal und Retries; Items werden bei Bedarf dem Projekt hinzugefügt.
ArtifactsArtefakte
Workflows produce files or folders (execute.artifacts); they get an Artifacts page with file tree, download and delete, and are the items of their own source – so the next workflow processes each artifact exactly once (consumed_by), with a read-only copy in its workspace. No pipeline engine.
Workflows erzeugen Dateien oder Ordner (execute.artifacts); sie erscheinen auf einer Artifacts-Seite mit Dateibaum, Download und Löschen und sind die Items einer eigenen Source – der nächste Workflow verarbeitet jedes Artefakt genau einmal (consumed_by), mit einer schreibgeschützten Kopie im Workspace. Ohne Pipeline-Engine.
Item historyItem-Verlauf
One page per issue or PR: its current state, the path of all runs with their results and a timeline of hooks with what each action changed (labels, project field old → new, comments), retry blocks and UI actions – optionally merged with the GitHub timeline.
Eine Seite je Issue oder PR: aktueller Stand, der Pfad aller Runs mit Ergebnis und eine Zeitleiste der Hooks mit der Wirkung jeder Action (Labels, Projektfeld alt → neu, Kommentare), Retry-Blocks und UI-Aktionen – optional zusammen mit der GitHub-Timeline.
Act as your GitHub AppAls GitHub App handeln
Admins reply to an issue, change labels or set project fields from the web UI as a configured app identity – opt-in per identity, login required, confirmation before sending and an audit log (kept 365 days by default).
Admins antworten auf ein Issue, ändern Labels oder setzen Projektfelder aus der Web-UI als konfigurierte App-Identity – je Identity freizuschalten, nur mit Anmeldung, mit Bestätigung vor dem Senden und Audit-Log (Default 365 Tage aufbewahrt).
Shell or container workersShell- oder Container-Worker
Commands run without a shell in their own process group – or in a throw-away Docker/Podman container with fixed mounts, resource limits and --cap-drop ALL.
Kommandos laufen ohne Shell in eigener Prozessgruppe – oder in einem Wegwerf-Container (Docker/Podman) mit festen Mounts, Ressourcenlimits und --cap-drop ALL.
Token files for long runsToken-Dateien für lange Runs
Short-lived GitHub App tokens as an environment variable or a file (<NAME>_FILE) that the daemon renews atomically and deletes after the run.
Kurzlebige GitHub-App-Tokens als Umgebungsvariable oder als Datei (<NAME>_FILE), die der Daemon atomar erneuert und nach dem Run löscht.
Keep filesDateien sichern
execute.keep saves transcripts and logs (glob patterns) before the workspace is cleaned up – size-limited, never following symlinks, downloadable in the UI.
execute.keep sichert Mitschnitte und Logs (Glob-Muster) vor dem Workspace-Cleanup – mit Größenlimit, ohne Symlinks zu folgen, Download in der UI.
Live web UI & APILive-Weboberfläche & API
Workflows, runs with live output, events, kept files and read-only views across repositories (custom value order, several sort keys, sections with headings), streamed via Server-Sent Events – plus a JSON HTTP API. Optional toolbar links to other local tools such as claude-inspect, in a new tab or embedded.
Workflows, Runs mit Live-Output, Events, gesicherte Dateien und read-only Views über mehrere Repositories (eigene Wertereihenfolge, mehrere Sortierschlüssel, Abschnitte mit Überschriften), live per Server-Sent Events – dazu eine JSON-HTTP-API. Optional Links zu weiteren lokalen Tools wie claude-inspect in der Toolbar, im neuen Tab oder eingebettet.
Server resourcesServer-Ressourcen
A compact strip on the dashboard shows CPU, memory, disk and the busiest processes at a glance; the Resources tab charts CPU over time stacked by the daemon, each run, hooks and the busiest other processes – plus memory and disk. Command names only, never arguments.
Eine kompakte Leiste im Dashboard zeigt CPU, RAM, Platte und die größten Prozesse auf einen Blick; der Reiter „Resources“ zeigt die CPU über die Zeit, gestapelt nach Daemon, jedem Run, Hooks und den größten fremden Prozessen – dazu RAM und Platte. Nur Befehlsnamen, nie Argumente.
One hub for several projectsEin Hub für mehrere Projekte
Run several independent workspaces – each a complete instance with its own config, database and port – under one shared limit. One overview shows every workspace (state, runs, blocked items, slots, server resources); each workspace UI lives at /w/<id>/ on the same port, with one login and roles. A crashed workspace restarts on its own; one systemd unit (service install --hub) covers everything, and an existing instance moves in without copying data.
Mehrere unabhängige Workspaces – je eine vollständige Instanz mit eigener Konfiguration, Datenbank und eigenem Port – laufen unter einem gemeinsamen Limit. Eine Übersicht zeigt jeden Workspace (Zustand, Runs, blockierte Items, Slots, Serverressourcen); die Workspace-UIs liegen unter /w/<id>/ auf demselben Port, mit einer Anmeldung und Rollen. Ein abgestürzter Workspace startet selbst neu; eine systemd-Unit (service install --hub) deckt alles ab, und eine bestehende Instanz zieht ohne Kopieren von Daten ein.
Dry-run & validationDry-Run & Validierung
config validate reports errors with file and line; workflow dry-run explains for every item why it would or would not start – without starting anything.
config validate meldet Fehler mit Datei und Zeile; workflow dry-run erklärt je Item, warum es starten würde oder nicht – ohne etwas zu starten.
Built for operationsFür den Betrieb gebaut
systemd service installer (single instance or hub), drain and cancel-all, crash recovery, atomic config reload and automatic migrations with backup.
systemd-Installer (Einzelinstanz oder Hub), Drain und Cancel-All, Crash-Recovery, atomarer Config-Reload und automatische Migrationen mit Backup.
How it worksSo funktioniert es
On every planning step the daemon polls each source, evaluates the workflow filter and sorts candidates by priority.
Start conditions – shell checks, limits, locks and retry blocks – decide whether a run may start.
The worker gets a workspace, a JSON context file and, if declared, a token. Its exit code and optional result file decide which hook runs.
Hooks update labels, project fields and comments on the item – so the next workflow (for example a reviewer) can pick it up.
In jedem Planungsschritt fragt der Daemon die Sources ab, wertet den Workflow-Filter aus und sortiert die Kandidaten nach Priorität.
Startbedingungen – Shell-Prüfungen, Limits, Locks und Retry-Blocks – entscheiden, ob ein Run starten darf.
Der Worker bekommt einen Workspace, eine JSON-Kontextdatei und – falls deklariert – ein Token. Exit-Code und optionale Ergebnisdatei bestimmen den Hook.
Hooks ändern Labels, Projektfelder und Kommentare am Item – der nächste Workflow (z. B. ein Reviewer) übernimmt.
One YAML file per workflowEine YAML-Datei pro Workflow
This coder takes issues labelled ready-for-coding whose project status is Todo or Ready, moves them across the board while it works and puts them back in the queue on any technical error.
Dieser Coder nimmt Issues mit Label ready-for-coding, deren Projektstatus Todo oder Ready ist, schiebt sie während der Arbeit über das Board und stellt sie bei jedem technischen Fehler zurück in die Warteschlange.
The worker contractDer Worker-Vertrag
Input: a minimal environment plus declared secrets and ADISPATCH_RUN_ID, ADISPATCH_WORKSPACE, ADISPATCH_CONTEXT_FILE, ADISPATCH_RESULT_FILE, …
Exit code = technical status: 0 is ok, anything else is crashed.
Result file for the business result: {"schema_version":1,"result":"failure","message":"…"}, optionally with an "outcome" for on_result.
Events:@@ADISPATCH_EVENT {"type":"status","message":"…"} lines show up live in the UI.
Input: Minimalumgebung plus deklarierte Secrets und ADISPATCH_RUN_ID, ADISPATCH_WORKSPACE, ADISPATCH_CONTEXT_FILE, ADISPATCH_RESULT_FILE, …
Exit-Code = technischer Status: 0 ist ok, alles andere crashed.
Ergebnisdatei für das fachliche Ergebnis: {"schema_version":1,"result":"failure","message":"…"}, optional mit "outcome" für on_result.
Events: Zeilen @@ADISPATCH_EVENT {"type":"status","message":"…"} erscheinen live in der UI.
Create a GitHub App per role, put its IDs into identities.yaml and the repository into sources.yaml, export the private key, set enabled: true in workflows/coder.yaml and run adispatch config reload --config-dir ./config.
GitHub App je Rolle anlegen, IDs in identities.yaml und das Repository in sources.yaml eintragen, Private Key exportieren, in workflows/coder.yamlenabled: true setzen und adispatch config reload --config-dir ./config ausführen.
Security in briefSicherheit in Kürze
Optional login.auth.mode: password (built-in users, scrypt hashes) or trusted_header (Tailscale Serve, oauth2-proxy) with the roles viewer, operator and admin; without it the API binds to 127.0.0.1 by default – for remote access use an authenticating reverse proxy, VPN or Tailscale and set server.allowed_hosts.
Scripts and YAML are trusted code running with the service's permissions – there is no sandbox.
No isolation between runs of the same service user. Separate high- and low-privilege workflows into separate instances, users or containers.
Workers only receive explicitly declared secrets; private keys come from environment variables, never from YAML.
Anmeldung optional.auth.mode: password (eingebaute Benutzer, scrypt-Hashes) oder trusted_header (Tailscale Serve, oauth2-proxy) mit den Rollen viewer, operator und admin; ohne Anmeldung bindet die API standardmäßig an 127.0.0.1 – Fernzugriff dann nur über einen authentifizierenden Reverse Proxy, VPN oder Tailscale mit server.allowed_hosts.
Skripte und YAML sind vertrauenswürdiger Code mit den Rechten des Dienstes – keine Sandbox.
Keine Isolation zwischen Runs desselben Dienstbenutzers. Hoch- und niedrig-privilegierte Workflows in getrennten Instanzen, Benutzern oder Containern betreiben.
Worker erhalten nur ausdrücklich deklarierte Secrets; Private Keys kommen aus Umgebungsvariablen, nie aus YAML.
DocumentationDokumentation
The detailed documentation is in German. The README is available in English and German.
Die ausführliche Dokumentation ist auf Deutsch. Das README gibt es auf Englisch und Deutsch.