DevFlow is an all-in-one Jira → AI codegen → review → Git → CI/CD automation platform. It ships as an Electron desktop app (runs pipelines on your machine with the Cursor SDK) plus an optional cloud backend for public Jira webhooks and multi-worker job queues.
Full user manual: MANUAL.md
DevFlow Agent closes the loop from ticket to merged code:
- Detects Jira tickets (poll, webhook, or cloud queue)
- Generates implementation using the Cursor SDK
- Reviews changes with a second AI pass (auto-fix loop)
- Commits & pushes to GitHub, GitLab, or Bitbucket
- Updates Jira with review summaries and status transitions
- Deploys CI workflows that run AI review on every PR/MR
The desktop app is the worker — it holds your repo, secrets, and Cursor API key. The cloud server only queues jobs and receives webhooks; it never runs your code.
Jira Ticket → Detect → AI Code Gen → AI Review → Git Commit/Push → Jira Update → CI/CD
git clone https://github.com/thensanity/DevFlow.git
cd DevFlow
npm install
npm run dev| Feature | Description |
|---|---|
| Jira Detection | Polls Jira via JQL for tickets tagged devflow-agent |
| Self-Writing Tickets | Paste a spec; AI drafts and creates a structured Jira ticket |
| AI Code Generation | Uses Cursor SDK to implement tickets in your repo |
| AI Review Bot | Second agent pass reviews changes; auto-fixes critical findings |
| Git Integration | Creates feature branches, commits, and pushes to remote |
| Multi-Provider CI/CD | GitHub Actions, GitLab CI, or Bitbucket Pipelines |
| Secret Wiring | Auto-pushes CURSOR_API_KEY to repo CI secrets/variables |
| System Tray | Background polling continues when the window is closed |
cd devflow-agent
npm install
npm run devConfigure in Settings:
- Cursor API Key — Cursor Dashboard → Integrations
- Jira — Base URL, email, API token, project key
- Git — Local repo path, provider (auto-detect or manual)
- CI tokens — GitHub PAT, GitLab token, or Bitbucket app password (for secret wiring)
Enable Minimize to system tray in Settings:
- Closing the window keeps the app running in the tray
- Background polling continues on your configured interval
- Tray menu: Show Window, Run Next Ticket, Quit
- Desktop notifications when pipelines start (optional)
DevFlow auto-detects your git remote or you can pick a provider manually.
| Provider | Workflow file | Secret location |
|---|---|---|
| GitHub | .github/workflows/devflow-agent.yml |
Actions secret CURSOR_API_KEY |
| GitLab | .gitlab-ci.yml |
CI/CD variable CURSOR_API_KEY |
| Bitbucket | bitbucket-pipelines.yml |
Pipeline variable CURSOR_API_KEY |
- Install Workflow — writes CI config +
scripts/devflow-ci-review.mjslocally - Deploy + Wire Secrets + Push — installs workflow, wires
CURSOR_API_KEYvia provider API, commits, and pushes - Wire CURSOR_API_KEY Only — updates the remote secret without changing workflow files
- GitHub PAT:
repo,workflow(Actions secrets write) - GitLab token:
apiscope, Maintainer+ on project - Bitbucket app password: Repository write + Pipelines admin
All providers run scripts/devflow-ci-review.mjs on pull/merge requests. The script uses @cursor/sdk with CURSOR_API_KEY and fails the pipeline if the review returns CHANGES_REQUESTED or critical findings.
- Detect — Fetch ticket from Jira, transition to In Progress
- Generate — Cursor agent implements the ticket on a feature branch
- Review — AI review bot checks correctness, security, style, tests
- Commit — Stage and commit all changes
- Push — Push branch to configured remote
- Update Jira — Post review summary as comment; transition to Done if approved
npm run distOutput in release/ (NSIS on Windows, DMG on macOS, AppImage on Linux).
src/main/services/
├── jira.service.ts
├── git.service.ts # Remote parsing, multi-provider paths
├── agent.service.ts # Cursor SDK
├── review.service.ts
├── cicd.service.ts # Provider-specific CI templates
├── orchestrator.service.ts
├── tray.service.ts # System tray + background mode
└── providers/
├── github.provider.ts # Actions secrets (libsodium encrypt)
├── gitlab.provider.ts # CI/CD variables
└── bitbucket.provider.ts # Pipeline variables
Deploy the backend so Jira Cloud can reach you via a public URL. The desktop app registers as a worker and runs pipelines locally (where your repo and Cursor SDK live).
Jira Cloud ──webhook──▶ Backend Server ──job queue──▶ Desktop Worker ──▶ Git + Cursor AI
| Component | Role |
|---|---|
| Server | Receives webhooks, queues jobs, tracks progress |
| Desktop app | Polls for jobs, runs pipeline on your machine |
cd devflow-agent
npm run server:install
cp server/.env.example server/.env
# Edit server/.env — set API_KEY and WEBHOOK_SECRET
npm run server:devServer runs at http://localhost:8787 by default.
Settings → Cloud Backend:
- Enable Connect to cloud backend
- Set URL and API key (matches
API_KEYin server.env) - Enable Run as worker
In Jira → Settings → Webhooks:
- URL:
https://your-server.com/webhooks/jira - Header:
Authorization: Bearer YOUR_WEBHOOK_SECRET
When a ticket event fires, the server queues a job; your desktop worker picks it up and runs the pipeline.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /health |
None | Health + stats + config warnings |
| GET | /api/events/stream |
API_KEY | SSE live job events |
| POST | /webhooks/jira |
WEBHOOK_SECRET | Queue job (deduplicated) |
| POST | /api/jobs/trigger |
API_KEY | Manual job (high priority) |
| POST | /api/jobs/:id/retry |
API_KEY | Re-queue failed job |
| POST | /api/admin/release-stuck |
API_KEY | Release timed-out jobs |
| GET | /api/admin/audit |
API_KEY | Audit log |
| GET | /api/worker/jobs/next |
API_KEY | Worker claims next job |
| Feature | Description |
|---|---|
| Worker affinity | Jobs can set preferredWorkerId and affinityTags; workers register tags + repo path |
| Integration tests | Fastify inject tests for auth, RBAC, webhooks, affinity claiming |
| Desktop auto-update | electron-updater with Settings UI (packaged builds) |
Worker register payload:
{ "machineId": "...", "tags": ["frontend", "gpu"], "repoPath": "C:/repos/app" }Job trigger payload:
{ "issueKey": "PROJ-1", "preferredWorkerId": "machine-a", "affinityTags": ["gpu"] }| Feature | Description |
|---|---|
| PostgreSQL | Set STORAGE_DRIVER=postgres + DATABASE_URL for multi-instance deploys |
| Redis | Set REDIS_URL for distributed locks, dedup, and cross-instance SSE |
| JWT auth | POST /api/auth/token — exchange API key for JWT; desktop can enable in Settings |
| Multi-tenant | MULTI_TENANT=true, TENANTS=default,acme, per-tenant API/webhook keys |
| HMAC webhooks | X-DevFlow-Signature: sha256=<hex> of raw body; set WEBHOOK_HMAC_REQUIRED=true |
| Prometheus | GET /metrics — job/worker/webhook counters (optional METRICS_API_KEY) |
| Desktop SSE | Live job events in Cloud Backend panel |
| Admin UI | Retry, cancel, release stuck, cleanup, audit log from desktop |
- Stuck job recovery — auto-releases jobs past lease timeout
- Auto-retry — failed jobs re-queue up to
MAX_JOB_RETRIES - Priority queue — high / normal / low ordering
- Webhook dedup — ignores duplicate Jira events
- Rate limiting — protects webhooks and API
- Audit log — all webhook, job, and admin actions
- SSE stream — real-time job events at
/api/events/stream - Server notifications — optional Slack/Discord on job complete/fail
- Graceful shutdown — clean exit on SIGTERM
- Concurrent-safe storage — serialized JSON writes
Deploy server/ to Railway, Render, Fly.io, or a VPS:
cd server
npm run build
npm startSet PORT, API_KEY, WEBHOOK_SECRET, and optionally DATABASE_URL, REDIS_URL, JWT_SECRET as environment variables.
In Settings → App Updates, set your generic release feed URL (must host latest.yml from electron-builder). Enable auto-check or use Check now / Download update / Restart & install.
Packaged builds check every 4 hours; dev mode skips update checks.
| Feature | What it does |
|---|---|
| Setup Wizard | First-run onboarding for Cursor, Jira, and Git |
| System Health | Live checks for Config, Jira, Git, Cursor API, Git provider |
| Pre-flight Checks | Validates connections before every pipeline run |
| Smart Ticket Sort | Readiness scores (description, criteria, priority) — best ticket first |
| Smart Pick | One-click run on the highest-readiness ticket |
| Jira Comment Enrichment | Pulls recent comments into agent context |
| API Retry | Exponential backoff on Jira/Git failures |
| Auto-stash | Stashes dirty working tree before branching |
| Rollback on Failure | Deletes failed feature branch, returns to base |
| Pipeline Progress Bar | Visual stage tracker with percentage |
| Test All Connections | One button in Settings validates everything |
Open the Advanced tab for power-user controls:
| Feature | Description |
|---|---|
| Dry Run | Generate + review without commit/push |
| Approval Gate | Manual approve/reject with diff preview before push |
| Auto PR/MR | Creates pull/merge request on GitHub, GitLab, or Bitbucket |
| Custom Prompts | Override codegen and review agent prompts |
| Branch Templates | e.g. feature/{key}-{slug} |
| Issue Filters | Exclude issue types, minimum priority |
| Batch Queue | Run all pending tickets sequentially |
| Jira Webhook | Local HTTP server triggers pipelines instantly |
| Cron Scheduler | Schedule pipeline runs (e.g. 0 9,17 * * 1-5) |
| Slack/Discord | Webhook notifications on success/failure |
| Pipeline History | Persistent run log with analytics |
| Config Export/Import | Backup and restore settings |
- Enable in Advanced → set port (default
3847) - Point Jira webhook to
http://localhost:3847/webhook/jira - Optional: set
Authorization: Bearer <secret>header
| Document | Contents |
|---|---|
| README.md | Overview, features, API reference, deployment |
| MANUAL.md | Step-by-step user manual, settings, troubleshooting |
| server/.env.example | Backend environment variables |
MIT — see LICENSE.