Paint by Numbers Deploy Guide · 5 Agents · 4 Tiers · Human-in-the-Loop
48-HOUR ACTIVATION PLAN INSIDEeizwhjpclwpcbhwrztwm)folio-saas repo)/opt/forge//opt/forge/.env.system has: SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, ANTHROPIC_API_KEY, NP_API_KEYfeat/agentic-outreach merged to main (or deploy from branch)Supabase URL + keys: In your .env.local file in folio-saas root
Anthropic API key: Same .env.local → ANTHROPIC_API_KEY
NP_API_KEY: Already in /opt/forge/.env.system (the Forge VPS key, id d20a2e4d)
Supabase SQL Editor: Open SQL Editor
This creates 8 tables in Supabase. You need to run 2 SQL files in order.
supabase/migrations/20260222_outreach_tables.sqlYou'll get errors like "relation already exists". Safe to ignore — or add IF NOT EXISTS to each CREATE TABLE statement.
supabase/migrations/20260222_outreach_seed.sql-- Run this in SQL Editor to verify: SELECT agent_name, is_enabled, loop_interval_seconds, max_daily_cost_usd FROM agent_config; -- Should show 5 rows: scout, warmer, signal, writer, iterator (all is_enabled=false) SELECT variant_name, price, is_active FROM offer_variants; -- Should show 1 row: "Mastery Monetization Lab - Base" at 150000 ($1,500)
| Table | Purpose | Key Fields |
|---|---|---|
prospects | Every prospect across platforms | full_name, icp_score, stage, tier, source |
signals | Pain expressions / buying signals | platform, relevance_score, suggested_response |
conversations | Outreach conversations | prospect_id, messages, sentiment, objection_type |
agent_runs | Audit log for every run | agent_name, status, duration_ms, estimated_cost_usd |
outreach_queue | Human approval queue | draft_message, priority, status (pending→approved→sent) |
offer_variants | Offer variations | price, headline, value_prop, conversion_rate |
content_queue | Content for review | platform, body, hashtags, status (draft→approved→posted) |
agent_config | Runtime config per agent | is_enabled, loop_interval, max_daily_cost, config JSON |
The dashboard and API routes are part of the Next.js app. Just push to Vercel.
# From folio-saas directory: git add app/api/outreach/ app/outreach/ lib/agent/tools.ts git commit -m "Agentic outreach: dashboard + API routes + agent tools" git push origin feat/agentic-outreach # Then merge to main (or deploy from branch): git checkout main && git pull origin main git merge feat/agentic-outreach git push origin main
https://www.nowpage.io/outreach (or your app URL + /outreach)| Path | What it does |
|---|---|
/outreach | Dashboard UI — 5 tabs: Agents, Pipeline, Signals, Content, Metrics |
/api/outreach/agents | List/start/stop agents |
/api/outreach/prospects | CRUD prospects, filter by stage/tier/score |
/api/outreach/signals | Signal feed + bulk actions |
/api/outreach/outreach | Approval queue for outgoing messages |
/api/outreach/content | Content draft queue |
/api/outreach/offers | Offer variant management |
/api/outreach/metrics | Funnel, costs, objections, variants |
# From your local machine (folio-saas root): scp -r agents/ forge@YOUR_VPS_IP:/opt/forge/agents/ # OR if using Syncthing, just wait for sync # OR git pull on the VPS: ssh forge@YOUR_VPS_IP cd /opt/forge/folio-saas git pull origin main cp -r agents/ /opt/forge/agents/
cd /opt/forge/agents npm install
# Check /opt/forge/.env.system contains: cat /opt/forge/.env.system | grep -E "SUPABASE|ANTHROPIC|NP_API" # Required vars (add any missing): NEXT_PUBLIC_SUPABASE_URL=https://eizwhjpclwpcbhwrztwm.supabase.co SUPABASE_SERVICE_ROLE_KEY=eyJ... # from .env.local ANTHROPIC_API_KEY=sk-ant-... # from .env.local NP_API_KEY=np_live_... # already there # Optional (for Twitter): TWITTER_BEARER_TOKEN=AAA... # only if you have Twitter API access
# Test signal agent (will exit after 1 loop if disabled): cd /opt/forge/agents node signal/index.js # You should see: # [signal] Starting agent loop... # [signal] Disabled, sleeping 60s... # (Ctrl+C to stop — this is correct, agent is disabled by default)
cd /opt/forge/agents/systemd
sudo bash install.sh
# DON'T enable all yet — we'll do it in the 48h plan below
Don't turn everything on at once. Phase agents in over 48 hours so you can verify each one works before adding the next. Total human time: ~1 hour/day.
The listener. Monitors Reddit for pain signals. Lowest risk — it only reads, never posts.
# On Forge VPS: sudo systemctl enable --now outreach-signal # OR from dashboard: Agents tab → Signal → Start
Verify after 30 min: Check dashboard → Signals tab. Should see signals appearing with relevance scores. If nothing, check journalctl -u outreach-signal -f
Your action: Review 5-10 signals. Click "Done" on good ones, "Skip" on noise. This trains your eye for what's useful.
The hunter. Finds ICP-matching users on Reddit. Creates prospects with ICP scores.
sudo systemctl enable --now outreach-scout
Verify after 4 hours: Dashboard → Pipeline tab. Should see prospects with ICP scores 0-100. Check the funnel numbers.
Your action: Review the top 10 prospects. Anyone obvious wrong? Override their ICP score or disqualify. Add 3-5 warm contacts manually via "Add Prospect".
The content engine. Generates LinkedIn posts, Reddit comments, Twitter threads from your core insights.
sudo systemctl enable --now outreach-writer
Verify after 12 hours: Dashboard → Content Queue tab. Should see 3+ content drafts across platforms.
Your action: Review each draft. Approve good ones (edit if needed). Post LinkedIn/Twitter manually. Reddit can auto-post if you set up PRAW later.
The relationship builder. Engages with prospects' content to build name recognition before outreach.
sudo systemctl enable --now outreach-warmer
Verify after 6 hours: Dashboard → Content Queue. Should see comment drafts for specific prospects.
Your action: Approve engagement comments. For Reddit, they can auto-post. For LinkedIn, copy the suggested comment and post it yourself.
Watch for: Prospects moving from "discovered" → "warming" → "ready" in the Pipeline.
The optimizer. Analyzes what's working, what's not, generates new offer variants.
sudo systemctl enable --now outreach-iterator
Verify after 24 hours: Dashboard → Metrics tab. Should see cost breakdown, funnel stats. Check ideas.asapai.net/outreach-reports/ for published iteration reports.
Your action: Review any new offer variants. Activate ones you like. The Iterator won't produce much until you have real conversations logged.
All 5 agents active. Time for your first system-level check.
Tune if needed: Adjust subreddit lists, pain keywords, ICP scoring thresholds in agent configs via the dashboard.
Once all agents are running, your daily routine is ~1 hour split across 3 sessions:
/outreach dashboardTier 1 (Warm): Your existing contacts → Writer drafts DMs → you send
Tier 2 (AI-Warmed): Scout finds → Warmer engages 3x → Writer drafts DM → you send
Tier 3 (Signal): Signal catches pain post → you respond helpfully → natural follow-up
Tier 4 (Content): Writer generates → you post → inbound inquiries → Tier 2/3
Job: Monitor Reddit + Twitter 24/7 for pain signals matching ICP
Loop: Every 30 min · LLM: Haiku (classify) + Sonnet (draft response) · Cost: ~$0.05/day
File: agents/signal/index.js
Config key fields: subreddits, reddit_keywords, twitter_keywords, min_relevance
Job: Find ICP-matching prospects on Reddit/Twitter. Generate LinkedIn search queries.
Loop: Every 4 hours · LLM: Haiku (filter) + Sonnet (ICP score) · Cost: ~$0.10/day
File: agents/scout/index.js
Config key fields: platforms, max_prospects_per_run, min_icp_score, subreddits
Job: Take 1 insight → generate 5 platform-native content pieces
Loop: Every 12 hours · LLM: Sonnet · Cost: ~$0.15/day
File: agents/writer/index.js
Config key fields: platforms, posts_per_day, core_insights (you provide these!)
Job: Engage with prospects' content 2-3x over 5-7 days to build recognition
Loop: Every 6 hours · LLM: Haiku (pick post) + Sonnet (draft comment) · Cost: ~$0.06/day
File: agents/warmer/index.js
Config key fields: max_touches_per_day, min_hours_between_touches, max_touches_before_ready
Job: Analyze rejections/objections → generate revised offer variants + weekly reports
Loop: Every 24 hours · LLM: Sonnet · Cost: ~$0.10/day
File: agents/iterator/index.js
Config key fields: min_rejections_before_variant, max_active_variants, analysis_window_hours
folio-saas/)app/outreach/page.tsx ← Dashboard UI (React client component) app/api/outreach/ agents/route.ts ← List/start/stop agents agents/[name]/route.ts ← Get/update single agent config prospects/route.ts ← List + add prospects prospects/[id]/route.ts ← Prospect detail/update/disqualify signals/route.ts ← Signal feed + bulk actions signals/[id]/route.ts ← Single signal detail/update outreach/route.ts ← Outreach approval queue content/route.ts ← Content draft queue offers/route.ts ← Offer variant management metrics/route.ts ← Funnel + cost metrics lib/agent/tools.ts ← 3 new tools: query_prospects, query_signals, get_sprint_metrics supabase/migrations/ 20260222_outreach_tables.sql ← 8 tables + indexes + RLS 20260222_outreach_seed.sql ← Agent configs + base offer
/opt/forge/agents/)shared/ supabase.js ← DB client (reads .env.system) llm.js ← Haiku/Sonnet/local LLM abstraction cost-tracker.js ← Daily budget tracking health.js ← Ralph loop + run lifecycle publish.js ← NowPage Publish API helper webhooks.js ← Webhook firing from agents signal/ index.js ← Main loop classifier.js ← Haiku classify + Sonnet draft monitors/reddit.js ← Reddit API poller monitors/twitter.js ← Twitter API poller scout/ index.js ← Main loop reddit.js ← Reddit user profiling twitter.js ← Twitter search icp-scorer.js ← Sonnet ICP scoring writer/ index.js ← Main loop multiplier.js ← Content generation per platform warmer/ index.js ← Main loop engagement.js ← Comment drafting + post selection iterator/ index.js ← Main loop analyzer.js ← Objection pattern analysis variant-gen.js ← Offer variant generation systemd/ outreach-signal.service ← systemd units (5 files) outreach-scout.service outreach-warmer.service outreach-writer.service outreach-iterator.service install.sh ← sudo bash install.sh package.json ← npm install (just @supabase/supabase-js)
journalctl -u outreach-signal -n 50 --no-pager
Common causes: missing env vars, wrong Supabase URL, no agent_config rows (run seed SQL).
The seed SQL hasn't been run. Go to Step 1b above.
Reddit's free API allows ~60 req/min. The agents respect this with 1s delays between requests, but if you hit limits, increase loop_interval_seconds for signal/scout.
Check if budget is exhausted: SELECT daily_cost_accumulated, max_daily_cost_usd FROM agent_config WHERE agent_name = 'signal'. Reset by setting daily_cost_accumulated = 0.
All config is in the agent_config table's config JSONB column. Edit via dashboard (Agents tab → click agent → update) or directly in Supabase. Changes take effect on the next loop iteration.
Dashboard → Agents tab → Writer → Edit Config → Update the core_insights array. Or via SQL:
UPDATE agent_config SET config = jsonb_set(config, '{core_insights}', '["Your new insight here"]') WHERE agent_name = 'writer'
| Agent | LLM Model | Calls/Day | Daily Cost |
|---|---|---|---|
| Signal | Haiku + Sonnet | ~100 + ~3 | $0.02-0.05 |
| Scout | Haiku + Sonnet | ~50 + ~5 | $0.05-0.15 |
| Writer | Sonnet | ~5 | $0.05-0.25 |
| Warmer | Haiku + Sonnet | ~6 + ~3 | $0.03-0.08 |
| Iterator | Sonnet | ~3 | $0.05-0.15 |
| TOTAL | $0.20-0.68/day |
14-day sprint total: $2.80-$9.52 in LLM costs.
Break-even: One $1,500 sale pays for 6+ months of agent operation.
Each agent has max_daily_cost_usd in its config. When accumulated cost hits the limit, the agent sleeps until midnight UTC. You can adjust these per-agent via the dashboard or SQL.