fix-demos
Fix Flagged InboxMate Demos
Announce:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Fix Demos started. Finding demos that need fixes... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
STEP 0 — Check Environment
Read .env using the Read tool. Required tokens:
PSQUARED_CRM_TOKEN— CRM API bearer tokenNUXT_MCP_DEMO_TOKEN— InboxMate MCP server tokenOPENBRAND_API_KEY— OpenBrand color extraction API key
MCP connection:
- URL:
https://app.psquared.dev/api/mcp - Auth:
Authorization: Bearer <NUXT_MCP_DEMO_TOKEN> - Transport: JSON-RPC 2.0 over HTTP POST
Call tools/list on the MCP server to confirm connectivity and get available tools.
Once verified:
Environment OK. Connecting to MCP...
STEP 1 — Find Demos Needing Fixes
Query CRM for opportunities at SCREENING stage with demoStatus = NEEDS_FIX:
curl -s -X POST https://crm.psquared.dev/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $PSQUARED_CRM_TOKEN" \
-d '{"query":"{ opportunities(filter: { stage: { eq: SCREENING }, demoStatus: { eq: NEEDS_FIX } }, first: 50) { edges { node { id name stage demoStatus demoId demoReviewIssues demoUrl { primaryLinkUrl } company { id name domainName { primaryLinkUrl } } pointOfContact { id name { firstName lastName } emails { primaryEmail } } } } } }"}'
Announce:
Found [N] demos needing fixes: 1. [Company Name] — Issues: [demoReviewIssues summary] 2. [Company Name] — Issues: [demoReviewIssues summary] ...
If none found, announce "No demos need fixing" and stop.
STEP 2 — Fix Each Demo
For each opportunity with NEEDS_FIX, parse the demoReviewIssues field and apply the appropriate fixes.
2a — Parse Issues
The demoReviewIssues field contains a text description of what failed QA. Common issues and their fix actions:
| Issue keyword | Fix action |
|---|---|
| color / brand / Farbe | Re-extract brand color via OpenBrand, update widget via MCP update_widget_style |
| greeting / Begrüßung | Fetch company website, rewrite greeting, update via MCP update_widget_style |
| language / Sprache | Fix language mismatch — update uiLang, greeting, questions via MCP |
| questions / Fragen / cards | Rewrite quick questions based on actual company content, update via MCP update_quick_questions |
| knowledge / content / hallucination | Re-scrape the company website, update/add knowledge items via MCP add_to_bucket |
| wrong company | Critical — demo was built for wrong company. Skip and flag for manual rebuild |
| prompt / system prompt | Rewrite system prompt based on company website, update via MCP update_prompt |
| offer / countdown | Campaigns manage deadlines — do not set offerExpiresAt or offerText. Skip this issue and note it in the report. |
2b — Fetch Company Website
Use WebFetch on the company's domain (company.domainName.primaryLinkUrl) to get current content. This is needed for most fixes — always do it.
Check key pages:
- Homepage
/kontaktor/contact/impressumor/imprint/leistungenor/services
2c — Apply Fixes
For color issues:
curl "https://openbrand.sh/api/extract?url=https://[domain]" \
-H "Authorization: Bearer $OPENBRAND_API_KEY"
Use the primary color from the response. Never use pure black (#000000) or pure white (#ffffff) — if primary is black/white, use secondary. If too light or too dark, pick the next best color. Then update:
Note on
agentId: The CRM storesdemoId(=demo_pages.id). To get theagentId, callGET https://app.psquared.dev/api/demo/<demoId>and readagentIdfrom the response. Use that value for all MCP tool calls.
{
"method": "tools/call",
"params": {
"name": "update_widget_style",
"arguments": {
"agentId": "[agentId — see note above]",
"primaryColor": "[corrected hex]"
}
}
}
For greeting issues:
Write a new greeting that's specific to the company (not generic). Must reference the company name and product/service.
{
"method": "tools/call",
"params": {
"name": "update_widget_style",
"arguments": {
"agentId": "[demoId]",
"greetingMessage": "[new EN greeting or omit]",
"greetingMessageDe": "[new DE greeting or omit]"
}
}
}
For question issues:
Rewrite quick questions based on actual website content. Always use card format.
{
"method": "tools/call",
"params": {
"name": "update_quick_questions",
"arguments": {
"agentId": "[demoId]",
"style": "cards",
"questionsEn": [{ "text": "...", "title": "...", "description": "...", "icon": "..." }],
"questionsDe": [{ "text": "...", "title": "...", "description": "...", "icon": "..." }]
}
}
}
For knowledge/content/hallucination issues:
Re-scrape the relevant pages and update knowledge items. Use add_to_bucket with the existing bucket. Each item MUST have a sourceUrl.
{
"method": "tools/call",
"params": {
"name": "add_to_bucket",
"arguments": {
"bucketId": "[existing bucketId]",
"title": "[corrected title]",
"content": "[corrected content from actual website]",
"sourceUrl": "https://[domain]/[page]"
}
}
}
For prompt issues:
Rewrite the system prompt to be specific to this company. Follow the template from the inboxmate-demo skill (Phase 2c).
{
"method": "tools/call",
"params": {
"name": "update_prompt",
"arguments": {
"agentId": "[demoId]",
"prompt": "[rewritten system prompt]"
}
}
}
For offer/countdown issues:
Skip entirely. Campaigns manage deadlines — do not set
offerExpiresAtorofferText. Note in the final report that this issue was skipped.
2d — Republish Agent
After all fixes are applied, republish the agent:
{
"method": "tools/call",
"params": {
"name": "publish_agent",
"arguments": { "agentId": "[demoId]" }
}
}
2e — Verify Fix
Use WebFetch on the demo URL (demo.inboxmate.psquared.dev/?id=[demoId]) to confirm the fixes are visible.
Quick sanity check:
- Color matches brand? ✓/✗
- Greeting is company-specific? ✓/✗
- Questions are relevant? ✓/✗
- Content looks accurate? ✓/✗
2f — Update CRM
Set demoStatus back to PENDING_REVIEW and clear demoReviewIssues:
curl -s -X POST https://crm.psquared.dev/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $PSQUARED_CRM_TOKEN" \
-d '{"query":"mutation { updateOpportunity(id: \"[opportunityId]\", data: { demoStatus: PENDING_REVIEW, demoReviewIssues: null }) { id demoStatus } }"}'
Announce after each:
Fixed: [Company Name] — [what was fixed]. Resubmitted for review.
STEP 3 — Handle Unfixable Demos
If a demo has a critical issue that can't be fixed by updating (e.g., "wrong company", fundamentally broken):
- Do NOT attempt to fix — flag for manual rebuild
- Add a note explaining why it can't be auto-fixed:
curl -s -X POST https://crm.psquared.dev/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $PSQUARED_CRM_TOKEN" \
-d '{"query":"mutation { updateOpportunity(id: \"[opportunityId]\", data: { demoReviewIssues: \"REQUIRES REBUILD: [reason]. Run /inboxmate-demo to recreate from scratch.\" }) { id } }"}'
Announce:
SKIP: [Company Name] — requires full rebuild. Reason: [reason]
STEP 4 — Report
Announce:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Fix Demos complete. Fixed & resubmitted: - [Company A] — [what was fixed] - [Company B] — [what was fixed] Skipped (need rebuild): - [Company C] — [reason] Next step: Run /review-demos to re-review fixed demos ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Important Reminders
- Always re-scrape the company website before fixing — don't guess from memory
- OpenBrand for colors — don't eyeball CSS, use the API
- Republish after changes — MCP changes don't go live until
publish_agentis called - Card format for questions — always objects with
{ text, title, description, icon }, always setstyle: "cards" - Every knowledge item needs
sourceUrl— the exact page URL it was scraped from - Clear
demoReviewIssueswhen resubmitting — prevents stale issue text from confusing the next review - Don't force-fix unfixable demos — flag for rebuild instead
More from psquared-development/psquared-skills
find-leads
Find new B2B leads in Germany for InboxMate outreach. Validates each lead against legal requirements (UWG), checks email is publicly visible, documents justification, and adds to CRM. Germany only — Austrian law (TKG) is stricter. Pass the number of leads to find as a parameter.
32review-demos
Review InboxMate demos waiting for QA. Finds CRM opportunities at SCREENING with demoStatus=PENDING_REVIEW, opens each demo link, checks quality, and flags as OK_TO_SEND or NEEDS_FIX with a note explaining why.
24setup-email-drafts
Create email drafts for approved InboxMate demos. Verifies all demos are ready, pulls contacts from CRM, creates CRM tasks, and creates draft emails via the notification service. Run after /review-demos has processed all pending demos.
24inboxmate-batch-demo
Batch-create InboxMate demos for CRM prospects. Queries Twenty CRM for companies without opportunities, validates their websites, creates demos for valid ones, and marks unreachable/outdated ones as DISQUALIFIED.
24check-outreach-status
Check status of sent demo outreach emails and monitor follow-up draft status. Follow-up drafts are created by /setup-email-drafts — this skill only monitors. Run periodically after /setup-email-drafts has been used.
23check-demo-analytics
Report on InboxMate demo page visits, email engagement, and pipeline health. Queries Ackee analytics and CRM to show which demos are getting traffic, which leads are converting, and which need attention.
23