skills/fix-demos/SKILL.md
Fix InboxMate demos flagged as NEEDS_FIX during QA review. Reads review issues from CRM, applies fixes via MCP (colors, prompts, knowledge, questions), and resubmits for review. Run after /review-demos has flagged issues.
npx skillsauth add psquared-development/psquared-skills fix-demosInstall 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.
Announce:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Fix Demos started. Finding demos that need fixes... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
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 keyMCP connection:
https://app.psquared.dev/api/mcpAuthorization: Bearer <NUXT_MCP_DEMO_TOKEN>Call tools/list on the MCP server to confirm connectivity and get available tools.
Once verified:
Environment OK. Connecting to MCP...
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.
For each opportunity with NEEDS_FIX, parse the demoReviewIssues field and apply the appropriate fixes.
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. |
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:
/kontakt or /contact/impressum or /imprint/leistungen or /servicesFor 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.
After all fixes are applied, republish the agent:
{
"method": "tools/call",
"params": {
"name": "publish_agent",
"arguments": { "agentId": "[demoId]" }
}
}
Use WebFetch on the demo URL (demo.inboxmate.psquared.dev/?id=[demoId]) to confirm the fixes are visible.
Quick sanity check:
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.
If a demo has a critical issue that can't be fixed by updating (e.g., "wrong company", fundamentally broken):
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]
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 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
publish_agent is called{ text, title, description, icon }, always set style: "cards"sourceUrl — the exact page URL it was scraped fromdemoReviewIssues when resubmitting — prevents stale issue text from confusing the next reviewtools
Generate a polished psquared client offer as a multi-page PDF (title, project description, screenshots, Angebot/pricing, AGB). Walks the user through gathering inputs (or accepts a JSON config), renders branded HTML templates with Playwright in two passes (title page edge-to-edge + body pages with margins and pagination), then merges with pdf-lib.
data-ai
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.
development
Audit or fix SEO issues for a single website or page. Checks meta tags, structured data, technical SEO, content quality, i18n, and AI readiness using only WebFetch — no external APIs. Pass a URL and mode (audit or fix) as parameters.
development
Run SEO audit or fix across all psquared websites autonomously. Dispatches parallel agents for psquared.dev, inboxmate.psquared.dev, ki-linz.at, and agenthub.psquared.dev, then presents a combined report. Pass mode (audit or fix) as parameter.