Local Setup
Alakai is a Yarn-workspaces monorepo with three runnable components plus shared packages. This guide covers running each one locally.
| Component | Directory | Type | Role |
|---|---|---|---|
| Core | core/ | Long-running Fastify server | Receives Slack/GitHub/ClickUp requests, generates prompts, enqueues background tasks to SQS |
| Orchestrator | orchestrator/ | Long-running Fastify server | Consumes SQS, launches workers (ECS in prod), collects their results |
| Workers | workers/ | One-shot processes | Execute heavy tasks — implementation, bug-hunter, digest — and POST results back to the orchestrator |
See Background Tasks for the full architecture. You don't need every component running for every change — core alone is enough for prompt-generation work; add the orchestrator and a worker when testing the implement/digest/bug-hunter flows end to end.
Requirements
- Node.js 20+
- Yarn
- Docker (for local Redis and LocalStack SQS)
1. Install dependencies
From the repo root — this installs every workspace at once:
yarn install
2. Start local infrastructure
The background-task flow needs Redis (task state) and an SQS queue (core → orchestrator). For local dev, run Redis in Docker and SQS via LocalStack.
Redis
docker run -d -p 6379:6379 redis:latest
SQS (LocalStack)
A ready-to-use LocalStack setup lives in .local-aws/:
cd .local-aws
make up # start LocalStack (SQS + DynamoDB) on :4566
make infra # create the `alakai-queue` SQS queue
This creates a queue reachable at:
http://localhost:4566/000000000000/alakai-queue
Other helpers: make read-sqs (peek at messages), make reset (purge the queue), make down (stop LocalStack).
Workers don't read from SQS directly, so for worker-only testing you can skip LocalStack and use Redis alone (see Workers).
3. Core
Core is a stateless Fastify server, default port 3000.
Configure
cd core
cp .env.sample .env
Minimum required
OPENAI_API_KEY— OpenAI API keySLACK_SIGNING_SECRET— verifies/slack/*requestsTASK_TRACKING_REDIS_URL/TASK_TRACKING_REDIS_KEY_PREFIX— Redis for task trackingIMPLEMENTATION_SQS_QUEUE_URL— the LocalStack queue URL above (only needed for background-task flows)
Commonly needed
| Variable | Description |
|---|---|
GITHUB_APP_ID | GitHub App ID (recommended auth for repo=owner/repo) |
GITHUB_APP_PRIVATE_KEY | GitHub App private key PEM (use \n escaped newlines in .env) |
GITHUB_TOKEN | Personal Access Token. Fallback when App is not installed yet. |
GITHUB_WEBHOOK_SECRET | Verifies POST /github/webhook signatures (x-hub-signature-256) |
SLACK_BOT_TOKEN | Required for threaded Slack responses and ClickUp flows |
OPENAI_MODEL | Defaults to gpt-4.1-mini |
OPENAI_SUPPORTED_MODELS | Comma-separated allowlist for model=... overrides |
IMPLEMENTATION_AGENT_PROVIDER | Defaults to openai |
CODEX_API_KEY | Used for /init and openai implementation runs |
CURSOR_API_KEY | Required when IMPLEMENTATION_AGENT_PROVIDER=cursor |
Workflow config
| Variable | Description |
|---|---|
REPO_WORKFLOW_CONFIG_SOURCE | s3 (default) or file — use file locally |
REPO_WORKFLOW_CONFIG_FILE_PATH | Local path to config file (defaults to <cwd>/config.json) |
REPO_WORKFLOW_CONFIG_S3_BUCKET | Required when REPO_WORKFLOW_CONFIG_SOURCE=s3 |
REPO_WORKFLOW_CONFIG_S3_KEY | Required when REPO_WORKFLOW_CONFIG_SOURCE=s3 |
core/.env.sample is the source of truth for the full list (ClickUp, dashboard, analytics, etc.).
Run
cd core
yarn dev # watch mode (tsx)
# or
yarn build && yarn start
Smoke tests
curl -s http://localhost:3000/healthz | cat
curl -s http://localhost:3000/available-models | cat
Core also ships a Makefile for firing test payloads (Slack commands, GitHub/ClickUp webhooks):
cd core && make help
4. Orchestrator
The orchestrator polls SQS and, in production, launches worker ECS tasks. Its default port is also 3000, so when running it alongside core, give it a different port.
Configure
cd orchestrator
cp .env.sample .env
| Variable | Required | Description |
|---|---|---|
PORT | — | Defaults to 3000; set to e.g. 8787 to avoid clashing with core |
ORCHESTRATOR_URL | Yes | Public base URL workers POST results back to (e.g. http://localhost:8787) |
SQS_QUEUE_URL | Yes | Same queue core enqueues to — http://localhost:4566/000000000000/alakai-queue |
REDIS_URL | Yes | Redis instance (redis://localhost:6379) |
REDIS_KEY_PREFIX | Yes | Redis namespace (default alakai-orchestrator) |
AWS_REGION | — | Defaults to us-east-1 |
MAX_CONCURRENT_WORKERS | — | Defaults to 5 |
SLACK_BOT_TOKEN | — | Needed to deliver digest results to Slack |
ECS_CLUSTER, WORKER_TASK_DEFINITION, WORKER_CONTAINER_NAME, WORKER_SUBNETS, WORKER_SECURITY_GROUP | Prod only | ECS launch config. Not needed locally — workers are run by hand (see below). |
When using LocalStack, also export dummy AWS credentials so the SQS client authenticates:
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_REGION=us-east-1
Run
cd orchestrator
yarn dev # or: yarn build && yarn start
Locally the orchestrator will consume queued messages but won't launch ECS tasks. To exercise a worker, run it directly (next section) — the worker reads its task from Redis and reports back to ORCHESTRATOR_URL.
5. Workers
All workers live under workers/ and share a single dispatch entry point, workers/src/main.ts, which selects the worker by the WORKER_TYPE env var (implementation, digest, or bug-hunter). Each is a one-shot process: it reads a task payload from Redis keyed by TASK_ID, does its job, POSTs the result to ORCHESTRATOR_URL, and exits.
Each worker has its own .env.sample and a Makefile of local helpers. The general loop is: seed a task into Redis → run a mock orchestrator to catch the callback → run the worker once.
Common worker env vars (per .env.sample):
| Variable | Description |
|---|---|
TASK_ID | Redis key suffix the worker reads its payload from |
REDIS_URL | redis://localhost:6379 |
REDIS_KEY_PREFIX | Namespace (e.g. alakai-sandbox) — must match what seeded the task |
ORCHESTRATOR_URL | Where to POST the result; the mock orchestrator listens on http://localhost:8787 |
GITHUB_APP_ID / GITHUB_APP_PRIVATE_KEY | GitHub auth (or GITHUB_TOKEN fallback) |
Implementation worker
workers/implementation/ — generates code and opens a PR. Provider-specific keys: OPENAI_API_KEY/CODEX_API_KEY (default openai) or CURSOR_API_KEY (IMPLEMENTATION_AGENT_PROVIDER=cursor).
cd workers/implementation
make env-init # create .env from template
# edit .env: REDIS_URL, ORCHESTRATOR_URL, API keys, GitHub creds
make orchestrator # terminal 1: mock orchestrator on :8787
make seed repo=my-org/my-repo prompt='Add retry logic' baseRef=main # terminal 2: write task to Redis
make run-once # terminal 2: run the worker once (or `make dev` for watch)
Other helpers: make read (inspect the seeded task), make clear (delete it), plus several seed-* variants for specific flows (make help lists them).
Bug-hunter worker
workers/bug-hunter/ — reviews an existing PR diff and posts findings. Uses BUG_HUNTER_OPENAI_API_KEY.
cd workers/bug-hunter
cp .env.sample .env # then fill in keys
make mock # terminal 1: mock orchestrator on :8787
make seed repo=my-org/my-repo pr='42' # terminal 2
make run-once # terminal 2 (or `make dev`)
Digest worker
workers/digest/ — builds a team activity digest. Uses DIGEST_OPENAI_API_KEY.
cd workers/digest
cp .env.sample .env # then fill in keys
make seed repo=my-org/my-repo date=2026-04-29
make run-once # or `make dev`
The digest worker has no
mocktarget of its own; run a mock orchestrator fromworkers/implementation(make orchestrator) if you want to catch its callback.
6. How the pieces connect locally
The full implement flow, end to end:
Slack/GitHub → Core → SQS (LocalStack) → Orchestrator → Worker → Orchestrator → Slack/GitHub
│ │
└──────────── Redis (task state) ──────────┘
For a quick worker-only iteration you can bypass core and the queue entirely: seed a task straight into Redis and run the worker against a mock orchestrator, as shown above.
7. Tests and typecheck
Run across all workspaces from the root:
yarn test
yarn typecheck
Or per component, e.g.:
cd core && yarn test # Jest
cd orchestrator && yarn test # node:test via tsx
Notes:
- Core's Jest suite does not require
OPENAI_API_KEY(it uses a fake LLM provider). - Route tests are skipped on Node < 20 (Fastify v5 requirement).
8. Dashboard app (optional, separate repo)
The dashboard UI lives in alakai-dashboard (git@github.com:Houlak/alakai-dashboard.git).
cd ~/houlak_projects/alakai-dashboard
yarn install
yarn dev
With core + dashboard both running locally:
- Core API:
http://localhost:3000 - Dashboard UI:
http://localhost:5173 - Next rewrite forwards
/api/task-dashboard/*to core/dashboard/*
Production configuration (AWS)
In production each component loads secrets from AWS Secrets Manager via AWS_SECRETS_MANAGER_SECRET_ID (+ AWS_REGION) instead of .env. The secret object holds the sensitive variables (OPENAI_API_KEY, SLACK_SIGNING_SECRET, GITHUB_*, Redis URL, etc.). The orchestrator additionally needs its ECS launch variables (ECS_CLUSTER, WORKER_TASK_DEFINITION, …) so it can start worker tasks. Locally, keep using .env — no AWS variables required beyond the LocalStack dummy credentials.