Skip to main content

durable-agents-setup

First-time setup for the Durable Agents stack (Mastra + Trigger.dev). Run once before using the main skill.

Jump to install

Source facts

Repository
modbender/skill-library-mcp
Last source activity
March 30, 2026 at 17:14
Detected SKILL.md language
English
Stars
12
Forks
3

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
durable-agents-setup
description
First-time setup for the Durable Agents stack (Mastra + Trigger.dev). Run once before using the main skill.
# Setup Guide Runs once. After setup is verified, remove the setup reference block from `SKILL.md`. --- ## Execution Rules These apply for the entire setup without exception. 1. **Run every step in sequence.** No skipping, no asking the user whether to continue. 2. **Never stop for user input.** Every known failure has a recovery path in this file. Go there, fix it, resume. 3. **If a fix is not in this file, find the solution independently.** Read logs, inspect the DB, check config files. Do not ask the user. 4. **Never change package versions or swap libraries to fix an error.** All versions in `package.json` are pinned intentionally. If a version mismatch appears to be the problem, the fix is in the configuration — not in bumping or changing a dependency. 5. **After any recovery, re-run only the step that failed** — not the full `./setup.sh` — unless the recovery section says otherwise. 6. **Confirm expected output before moving to the next step.** Each step specifies what success looks like. Match it before continuing. 7. **Report only at completion or on a genuinely unrecoverable failure.** Unrecoverable means: not covered in this file, and independent investigation finds no path forward. --- ## Prerequisites - Node.js 18+ - Docker with Docker Compose - Docker daemon running - An AI provider API key (any OpenAI-compatible endpoint) --- ## Setup Steps ### Step 0: Check if already running Before doing anything, verify the stack is not already up. ```bash curl -s http://localhost:3000/health ``` If this returns `{"status":"ok",...}`, the stack is already running. Skip to the Post-Setup Checklist and confirm all checks pass. If they do, setup is complete — do not re-run anything. If the API is not up, check whether the containers exist but are stopped: ```bash cd trigger-infra && docker compose -p trigger ps ``` If containers exist but are stopped, bring them back up: ```bash docker compose -p trigger up -d cd .. npm run dev ``` Then re-run the health check. Only proceed to Step 1 if no prior setup exists. ### Step 1: Clone and enter the repo ```bash git clone https://github.com/ainakwalamonk/durableclaw.git cd mastra-triggers-openclaw ``` ### Step 2: Run the setup script ```bash ./setup.sh ``` Handles: deps, Docker infra, Trigger.dev bootstrap (user, org, project, secret key, project ref, CLI token), database creation, migrations, AI provider config, smoke tests. If it fails at any stage, go to the matching recovery section below. Fix it, then resume manually from that step. ### Step 3: Verify infrastructure Start the worker first (separate terminal), then run the test: ```bash npm run trigger:dev # keep running npm run trigger:test # in another terminal ``` `trigger:test` fires `dummy-task` via the Trigger.dev API and polls for completion. Pass = full Trigger.dev pipeline is working. ### Step 4: Start the full system ```bash npm run dev ``` ### Step 5: Health check ```bash curl http://localhost:3000/health ``` Expected: `{"status":"ok","timestamp":"..."}` ### Step 6: Configure LLM from the openclaw gateway Do not hardcode or guess LLM credentials. Read them from the openclaw project on this machine. Check in this order until you find the values: 1. Look for a gateway environment file or gateway service config in the openclaw project directory (e.g. `gateway/.env`, `gateway/config.json`, `docker-compose.yml` service named `gateway`, or any `.env` at the project root that contains `AI_BASE_URL`, `AI_API_KEY`, or `MODEL_ID`). 2. Look for an openclaw config JSON (e.g. `openclaw.config.json`, `config/openclaw.json`, or any JSON referencing model/provider settings). 3. If neither exists, check running Docker containers for an AI gateway service: ```bash docker ps --format '{{.Names}}\t{{.Ports}}' | grep -i gateway ``` Then inspect its environment: ```bash docker inspect <container_name> --format '{{json .Config.Env}}' ``` Once you have `AI_BASE_URL`, `AI_API_KEY`, and `MODEL_ID`, write them to `.env` in this project: ```bash sed -i '' "s|^AI_BASE_URL=.*|AI_BASE_URL=<value>|" .env sed -i '' "s|^AI_API_KEY=.*|AI_API_KEY=<value>|" .env sed -i '' "s|^MODEL_ID=.*|MODEL_ID=<value>|" .env ``` ### Step 7: Smoke test Run the infrastructure smoke test: ```bash npm run trigger:test ``` Expected: `dummy-task` completes with status `COMPLETED`. This test makes no LLM call — a pass here means the full Trigger.dev pipeline is operational. If Step 6 failed to find real LLM credentials and `.env` is missing `AI_BASE_URL`, `AI_API_KEY`, or `MODEL_ID`, fill them with placeholders only for this test so the worker starts: ```bash grep -q "^AI_API_KEY=" .env || echo "AI_API_KEY=placeholder" >> .env grep -q "^AI_BASE_URL=" .env || echo "AI_BASE_URL=http://placeholder.local/v1" >> .env grep -q "^MODEL_ID=" .env || echo "MODEL_ID=placeholder-model" >> .env ``` Then re-run `npm run trigger:test`. Placeholders are only acceptable here — Step 8 requires real credentials. If you used placeholders, resolve the LLM config from the openclaw gateway before continuing. If the smoke test fails, the problem is in the infrastructure — go to the Recovery section. Do not debug LLM credentials until this passes. ### Step 8: Test the AI pipeline Once real LLM credentials are in `.env` from Step 6: ```bash curl -X POST http://localhost:3000/pipeline \ -H "Content-Type: application/json" \ -d '{"prompt": "Build a URL shortener service"}' ``` Expected: JSON with `plan`, `review`, and run IDs. ### Step 9: Verify Trigger.dev dashboard Open `http://localhost:3040` and confirm the run appears. --- ## Recovery ### Docker not installed or not running ```bash docker info ``` macOS: ```bash brew install --cask docker # Open Docker Desktop and wait for it to start ``` Linux: ```bash sudo apt-get update && sudo apt-get install -y docker.io docker-compose-plugin sudo systemctl start docker sudo usermod -aG docker $USER && newgrp docker ``` Re-run `./setup.sh` after Docker is running. ### Docker containers fail to start ```bash cd trigger-infra && docker compose -p trigger ps docker logs trigger-webapp-1 docker logs trigger-postgres-1 ``` If containers are unhealthy: ```bash cd trigger-infra && docker compose -p trigger down -v cd .. && ./setup.sh ``` ### Postgres not ready / connection refused ```bash until pg_isready -h localhost -p 5433 -U postgres 2>/dev/null; do sleep 2; done echo "Postgres ready" ``` ### Trigger.dev bootstrap fails (no secret key) ```bash bash trigger-infra/init-trigger.sh ``` If it fails to find the magic link: ```bash docker logs trigger-webapp-1 2>&1 | grep magic ``` If that returns nothing, pull the key directly from the DB: ```bash docker exec trigger-postgres-1 psql -U postgres -d postgres -t -A \ -c "SELECT \"apiKey\" FROM \"RuntimeEnvironment\" WHERE type = 'DEVELOPMENT' LIMIT 1" ``` Write the result to `.env`: ``` TRIGGER_SECRET_KEY=<value> ``` ### Project ref missing (CLI says "Project not found") The CLI requires the `externalRef` — not the project name or slug. ```bash docker exec trigger-postgres-1 psql -U postgres -d postgres -t -A \ -c "SELECT \"externalRef\" FROM \"Project\" LIMIT 1" ``` Write the result to two places: 1. `.env` → `TRIGGER_PROJECT_REF=<value>` 2. `trigger.config.ts` → replace the `project:` field ### CLI auth fails / "not logged in" The CLI (v3.3.17) reads `~/Library/Preferences/trigger/default.json` on macOS. ```bash cat ~/Library/Preferences/trigger/default.json 2>/dev/null cat ~/Library/Preferences/trigger/config.json 2>/dev/null ``` If the `self-hosted` profile is missing or has a placeholder token: ```bash PAT=$(grep TRIGGER_ACCESS_TOKEN .env | cut -d= -f2) node -e " const fs = require('fs'); const p = process.env.HOME + '/Library/Preferences/trigger/default.json'; let cfg = {}; try { cfg = JSON.parse(fs.readFileSync(p, 'utf8')); } catch {} cfg['self-hosted'] = { accessToken: '$PAT', apiUrl: 'http://localhost:3040' }; fs.writeFileSync(p, JSON.stringify(cfg, null, 2)); console.log('Updated.'); " ``` Verify: ```bash npx trigger.dev@3.3.17 whoami --profile self-hosted ``` Expected: ``` ◇ Account details [self-hosted] │ Email: admin@trigger.local │ URL: http://localhost:3040 ``` Fallback — authenticate interactively: ```bash npx trigger.dev@3.3.17 login -a http://localhost:3040 ``` Or override via env var for CLI commands: ```bash export TRIGGER_ACCESS_TOKEN="<your-pat>" ``` ### CLI PAT returns 401 even though token looks correct The PAT in the database was inserted with bad encryption — a known bug in `init-trigger.sh`. Regenerate it: ```bash # Generate and encrypt a new PAT node -e " const crypto = require('node:crypto'); const ENCRYPTION_KEY = '400852556fef3f19b9d0dfb558eb10f5'; const token = 'tr_pat_' + crypto.randomBytes(20).toString('hex'); const nonce = crypto.randomBytes(12); const cipher = crypto.createCipheriv('aes-256-gcm', ENCRYPTION_KEY, nonce); let enc = cipher.update(token, 'utf8', 'hex') + cipher.final('hex'); const tag = cipher.getAuthTag().toString('hex'); const hash = crypto.createHash('sha256').update(token).digest('hex'); console.log(JSON.stringify({ token, nonce: nonce.toString('hex'), ciphertext: enc, tag, hash })); " > /tmp/new_pat.json && cat /tmp/new_pat.json ``` ```bash # Insert into DB TOKEN=$(node -e "console.log(require('/tmp/new_pat.json').token)") NONCE=$(node -e "console.log(require('/tmp/new_pat.json').nonce)") CIPHER=$(node -e "console.log(require('/tmp/new_pat.json').ciphertext)") TAG=$(node -e "console.log(require('/tmp/new_pat.json').tag)") HASH=$(node -e "console.log(require('/tmp/new_pat.json').hash)") USER_ID=$(docker exec trigger-postgres-1 psql -U postgres -d postgres -t -A -c "SELECT id FROM \"User\" LIMIT 1") docker exec trigger-postgres-1 psql -U postgres -d postgres -c " DELETE FROM \"PersonalAccessToken\" WHERE name = 'cli-auto'; INSERT INTO \"PersonalAccessToken\" (id, name, \"userId\", \"obfuscatedToken\", \"encryptedToken\", \"hashedToken\", \"createdAt\", \"updatedAt\") VALUES ('pat_$(openssl rand -hex 12)', 'cli-auto', '$USER_ID', 'tr_pat_****...', '{\"nonce\": \"$NONCE\", \"ciphertext\": \"$CIPHER\", \"tag\": \"$TAG\"}'::jsonb, '$HASH', NOW(), NOW()); " ``` ```bash # Update CLI config node -e " const fs = require('fs'); const p = process.env.HOME + '/Library/Preferences/trigger/default.json'; let cfg = {}; try { cfg = JSON.parse(fs.readFileSync(p, 'utf8')); } catch {} cfg['self-hosted'] = { accessToken: '$TOKEN', apiUrl: 'http://localhost:3040' }; fs.writeFileSync(p, JSON.stringify(cfg, null, 2)); console.log('Done'); " ``` ```bash # Write to .env sed -i '' "s|^TRIGGER_ACCESS_TOKEN=.*|TRIGGER_ACCESS_TOKEN=$TOKEN|" .env ``` ### Version mismatch (404 on /engine/v1/) The SDK and CLI are pinned to `3.3.17` to match the self-hosted v3 platform. Do not change the versions. Fix the config instead. Verify the CLI version: ```bash npx trigger.dev@3.3.17 --version ``` If `package.json` has `^3.3.17` (with caret), remove the caret so it reads exactly: ```json
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub