[{"data":1,"prerenderedAt":216},["ShallowReactive",2],{"\u002Fdocs\u002Fcaf-orchestrator":3},{"id":4,"title":5,"body":6,"description":208,"extension":209,"meta":210,"navigation":211,"path":212,"seo":213,"stem":214,"__hash__":215},"docs\u002Fdocs\u002Fcaf-orchestrator.md","CAF Orchestrator",{"type":7,"value":8,"toc":202},"minimark",[9,13,18,26,55,62,126,129,142,146,149,165,168,188,191,195,198],[10,11,12],"p",{},"CAF Orchestrator is a small service that runs on your own VPS. It receives webhooks\nfrom your tracker, queues jobs per phase, then spawns headless Claude Code agents to\nrun Plan, Implement, Verify, and eventually open a PR.",[14,15,17],"h2",{"id":16},"setup","Setup",[10,19,20,21,25],{},"The Orchestrator ships as a Docker image — the fastest way to run it is with\n",[22,23,24],"code",{},"docker compose",":",[27,28,33],"pre",{"className":29,"code":30,"language":31,"meta":32,"style":32},"language-bash shiki shiki-themes github-light github-dark","docker compose up -d\n","bash","",[22,34,35],{"__ignoreMap":32},[36,37,40,44,48,51],"span",{"class":38,"line":39},"line",1,[36,41,43],{"class":42},"sScJk","docker",[36,45,47],{"class":46},"sZZnC"," compose",[36,49,50],{"class":46}," up",[36,52,54],{"class":53},"sj4cs"," -d\n",[10,56,57,58,61],{},"Before that, prepare an ",[22,59,60],{},".env"," file with the following variables:",[63,64,65,78],"table",{},[66,67,68],"thead",{},[69,70,71,75],"tr",{},[72,73,74],"th",{},"Variable",[72,76,77],{},"Description",[79,80,81,92,102,112],"tbody",{},[69,82,83,89],{},[84,85,86],"td",{},[22,87,88],{},"REDIS_URL",[84,90,91],{},"Connection to the Redis instance used for the BullMQ queue",[69,93,94,99],{},[84,95,96],{},[22,97,98],{},"CLAUDE_CODE_TOKEN",[84,100,101],{},"Credential used to run Claude Code headlessly",[69,103,104,109],{},[84,105,106],{},[22,107,108],{},"WEBHOOK_SECRET",[84,110,111],{},"Secret used to verify incoming webhook payloads",[69,113,114,123],{},[84,115,116,119,120],{},[22,117,118],{},"LINEAR_API_KEY"," \u002F ",[22,121,122],{},"JIRA_API_TOKEN",[84,124,125],{},"Tracker credentials, whichever you use",[10,127,128],{},"Once the container is running, check its health endpoint:",[27,130,132],{"className":29,"code":131,"language":31,"meta":32,"style":32},"curl http:\u002F\u002Flocalhost:PORT\u002Fhealthz\n",[22,133,134],{"__ignoreMap":32},[36,135,136,139],{"class":38,"line":39},[36,137,138],{"class":42},"curl",[36,140,141],{"class":46}," http:\u002F\u002Flocalhost:PORT\u002Fhealthz\n",[14,143,145],{"id":144},"webhook-configuration-linear-jira","Webhook configuration (Linear \u002F Jira)",[10,147,148],{},"The Orchestrator triggers automatically from ticket status changes. Register a\nwebhook in your tracker pointing to the Orchestrator's endpoint:",[150,151,152,159],"ul",{},[153,154,155,156],"li",{},"Linear: ",[22,157,158],{},"https:\u002F\u002F\u003Cyour-vps-host>\u002Fwebhooks\u002Flinear",[153,160,161,162],{},"Jira: ",[22,163,164],{},"https:\u002F\u002F\u003Cyour-vps-host>\u002Fwebhooks\u002Fjira",[10,166,167],{},"The flow:",[169,170,171,174,177,182,185],"ol",{},[153,172,173],{},"A ticket's status changes (e.g. to \"Ready for Plan\") in Linear\u002FJira",[153,175,176],{},"The tracker sends a webhook to the Orchestrator",[153,178,179,180],{},"The Orchestrator verifies the payload signature using ",[22,181,108],{},[153,183,184],{},"A job for the matching phase is queued in BullMQ",[153,186,187],{},"The Orchestrator spawns a headless Claude Code agent for that phase",[10,189,190],{},"Every phase still stops at the human-review checkpoint — the Orchestrator never\nadvances to the next phase without explicit approval.",[14,192,194],{"id":193},"multi-repo","Multi-repo",[10,196,197],{},"Running a single Orchestrator instance across multiple repos at once is still on the\nroadmap and isn't available in v1.0.0. For now, run one Orchestrator instance per\nrepo. This page will be updated once multi-repo support ships.",[199,200,201],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":32,"searchDepth":203,"depth":203,"links":204},2,[205,206,207],{"id":16,"depth":203,"text":17},{"id":144,"depth":203,"text":145},{"id":193,"depth":203,"text":194},"A self-hosted webhook receiver (Fastify + BullMQ + Redis) that runs agents per phase.","md",{},true,"\u002Fdocs\u002Fcaf-orchestrator",{"title":5,"description":208},"docs\u002Fcaf-orchestrator","07nKU4hmvXc65YsRQb59z_zbvuSMd6KKFVoYay8r7LU",1787621083854]