/SKILL.md
# Voilà Outreach Automation Pipeline Deterministic outreach automation for Voilà — "Automation that fits." ## Architecture ``` IMPORTED → ENRICHING → READY_TO_DRAFT → DRAFTED → PENDING_SEND → SENT → [REPLIED|BOUNCED|NO_REPLY] ↓ ↓ ↓ ↓ [FAILED] [SKIPPED] [REVIEW] [SIMULATED*] Terminal states: CONVERTED, LOST, UNSUBSCRIBED, PAUSED ``` ## Safety First - **Emails NEVER send automatically** until explicitly enabled - `confi
npx skillsauth add alrightgpt/voila-crm voila-crmInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Deterministic outreach automation for Voilà — "Automation that fits."
IMPORTED → ENRICHING → READY_TO_DRAFT → DRAFTED → PENDING_SEND → SENT → [REPLIED|BOUNCED|NO_REPLY]
↓ ↓ ↓ ↓
[FAILED] [SKIPPED] [REVIEW] [SIMULATED*]
Terminal states: CONVERTED, LOST, UNSUBSCRIBED, PAUSED
config.send_enabled defaults to falsemode="send_if_enabled" + config.send_enabled=trueImport leads from CSV or manual entry.
# CSV import
./commands/intake.js --csv /path/to/leads.csv
# Manual entry
./commands/intake.js --manual '{"name":"John Doe","email":"[email protected]","company":"Acme Realty","role":"independent"}'
Output:
{
"lead_id": "uuid",
"state": "IMPORTED",
"imported_at": "ISO8601",
"validation_errors": []
}
Generate personalized email drafts.
# Draft all ready leads
./commands/draft.js --all [--template independent|brokerage]
# Draft specific lead
./commands/draft.js --lead <lead_id>
Output:
{
"lead_id": "uuid",
"state": "DRAFTED",
"draft": {
"subject": "string",
"body_text": "string",
"personalization_used": [],
"confidence_score": 0.8
},
"drafted_at": "ISO8601"
}
Send emails or simulate.
# Simulate all ready leads (default, safe)
./commands/send.js --all
# Test what would send
./commands/send.js --all --mode send_if_enabled --dry-run
# Actually send (requires send_enabled=true)
./commands/send.js --all --mode send_if_enabled
Output:
{
"lead_id": "uuid",
"state": "SENT|SIMULATED|FAILED|BLOCKED",
"sent_at": "ISO8601?",
"message_id": "string?",
"simulation_note": "string?",
"error": "string?"
}
Validate SMTP transport.
./commands/test_smtp.js <to> <subject> [body_text]
Output:
{
"status": "sent|failed",
"message_id": "string?",
"error": "string?"
}
Required for SMTP:
export VOILA_SMTP_HOST="smtp.gmail.com"
export VOILA_SMTP_PORT="587"
export VOILA_SMTP_USER="[email protected]"
export VOILA_SMTP_PASS="your-app-password"
export VOILA_FROM_NAME="Austin"
export VOILA_FROM_EMAIL="[email protected]"
Never commit these to git.
Pure functions in lib/state-machine.js:
canTransition(fromState, toState) - Check if transition is validtransition(lead, toState, metadata) - Execute transition, return new leadisTerminal(state) - Check if state is terminalrequiresManualReview(state) - Check if state needs approvalgetNextStates(state) - Get valid next statesStored in state/pipeline.json:
{
"version": "1.0.0",
"last_updated": "ISO8601",
"leads": [
{
"id": "uuid",
"state": "DRAFTED",
"imported_at": "ISO8601",
"updated_at": "ISO8601",
"raw_data": { /* normalized lead data */ },
"enriched_data": null,
"draft": { /* generated email */ },
"send_status": null,
"history": [ /* transition log */ ]
}
]
}
./commands/test_smtp.js [email protected] "Test"config.json, set "send_enabled": true--mode send_if_enabledTemplates in lib/templates/:
independent.md - For independent agentsbrokerage.md - For brokerages and teamsUse {{variable}} syntax for personalization:
{{first_name}}{{company}}{{company_name}}All commands input/output strict JSON. See command headers for schemas.
config.json:
{
"send_enabled": false,
"simulation_mode": true
}
Expected headers:
name,email,phone,company,role,notes
Role values: independent, brokerage, kw, or unknown
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.