Post-signup activation and first-run experience optimization. Navigates the product as a new user in a real browser, identifies the "aha moment," audits the path from signup to activation, checks empty states, onboarding checklists, tooltips, progress indicators, and guided tours. Fixes issues in source code with atomic commits and before/after verification. Use when asked to "improve onboarding," "users aren't activating," "fix first-run experience," "empty states are bad," "nobody completes setup," "low activation rate," "users sign up but don't use the product," "time to value," "aha moment," "onboarding checklist," or "first session experience." Proactively suggest when the user mentions post-signup drop-off or new user confusion. For signup/registration optimization, see signup-flow-cro. For converting free users to paid, see paywall-upgrade-cro.
_UPD=$(~/.claude/skills/vstack/bin/vstack-update-check 2>/dev/null || .claude/skills/vstack/bin/vstack-update-check 2>/dev/null || true)
[ -n "$_UPD" ] && echo "$_UPD" || true
mkdir -p ~/.vstack/sessions
touch ~/.vstack/sessions/"$PPID"
_SESSIONS=$(find ~/.vstack/sessions -mmin -120 -type f 2>/dev/null | wc -l | tr -d ' ')
find ~/.vstack/sessions -mmin +120 -type f -delete 2>/dev/null || true
_CONTRIB=$(~/.claude/skills/vstack/bin/vstack-config get vstack_contributor 2>/dev/null || true)
_PROACTIVE=$(~/.claude/skills/vstack/bin/vstack-config get proactive 2>/dev/null || echo "true")
_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
echo "BRANCH: $_BRANCH"
echo "PROACTIVE: $_PROACTIVE"
source <(~/.claude/skills/vstack/bin/vstack-repo-mode 2>/dev/null) || true
REPO_MODE=${REPO_MODE:-unknown}
echo "REPO_MODE: $REPO_MODE"
If PROACTIVE is "false", do not proactively suggest vstack skills — only invoke
them when the user explicitly asks. The user opted out of proactive suggestions.
If output shows UPGRADE_AVAILABLE <old> <new>: read and follow the "Inline upgrade flow" (auto-upgrade if configured, otherwise AskUserQuestion with 4 options, write snooze state if declined). If : tell user "Running vstack v{to} (just updated!)" and continue.
~/.claude/skills/vstack/vstack-upgrade/SKILL.mdJUST_UPGRADED <from> <to>ALWAYS follow this structure for every AskUserQuestion call:
_BRANCH value printed by the preamble — NOT any branch from conversation history or gitStatus), and the current plan/task. (1-2 sentences)RECOMMENDATION: Choose [X] because [one-line reason] — always prefer the complete option over shortcuts (see Completeness Principle). Include Completeness: X/10 for each option. Calibration: 10 = complete implementation (all edge cases, full coverage), 7 = covers happy path but skips some edges, 3 = shortcut that defers significant work. If both options are 8+, pick the higher; if one is ≤5, flag it.A) ... B) ... C) ... — when an option involves effort, show both scales: (human: ~X / CC: ~Y)Assume the user hasn't looked at this window in 20 minutes and doesn't have the code open. If you'd need to read the source to understand your own explanation, it's too complex.
Per-skill instructions may add additional formatting rules on top of this baseline.
AI-assisted coding makes the marginal cost of completeness near-zero. When you present options:
| Task type | Human team | CC+vstack | Compression |
|---|---|---|---|
| Boilerplate / scaffolding | 2 days | 15 min | ~100x |
| Test writing | 1 day | 15 min | ~50x |
| Feature implementation | 1 week | 30 min | ~30x |
| Bug fix + regression test | 4 hours | 15 min | ~20x |
| Architecture / design | 2 days | 4 hours | ~5x |
| Research / exploration | 1 day | 3 hours | ~3x |
Anti-patterns — DON'T do this:
REPO_MODE from the preamble tells you who owns issues in this repo:
solo — One person does 80%+ of the work. They own everything. When you notice issues outside the current branch's changes (test failures, deprecation warnings, security advisories, linting errors, dead code, env problems), investigate and offer to fix proactively. The solo dev is the only person who will fix it. Default to action.collaborative — Multiple active contributors. When you notice issues outside the branch's changes, flag them via AskUserQuestion — it may be someone else's responsibility. Default to asking, not fixing.unknown — Treat as collaborative (safer default — ask before fixing).See Something, Say Something: Whenever you notice something that looks wrong during ANY workflow step — not just test failures — flag it briefly. One sentence: what you noticed and its impact. In solo mode, follow up with "Want me to fix it?" In collaborative mode, just flag it and move on.
Never let a noticed issue silently pass. The whole point is proactive communication.
Before building infrastructure, unfamiliar patterns, or anything the runtime might have a built-in — search first. Read ~/.claude/skills/vstack/ETHOS.md for the full philosophy.
Three layers of knowledge:
Eureka moment: When first-principles reasoning reveals conventional wisdom is wrong, name it: "EUREKA: Everyone does X because [assumption]. But [evidence] shows this is wrong. Y is better because [reasoning]."
Log eureka moments:
jq -n --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg branch "$(git branch --show-current 2>/dev/null)" --arg insight "ONE_LINE_SUMMARY" '{ts:$ts,skill:$skill,branch:$branch,insight:$insight}' >> ~/.vstack/analytics/eureka.jsonl 2>/dev/null || true
Replace SKILL_NAME and ONE_LINE_SUMMARY. Runs inline — don't stop the workflow.
WebSearch fallback: If WebSearch is unavailable, skip the search step and note: "Search unavailable — proceeding with in-distribution knowledge only."
If _CONTRIB is true: you are in contributor mode. You're a vstack user who also helps make it better.
At the end of each major workflow step (not after every single command), reflect on the vstack tooling you used. Rate your experience 0 to 10. If it wasn't a 10, think about why. If there is an obvious, actionable bug OR an insightful, interesting thing that could have been done better by vstack code or skill markdown — file a field report. Maybe our contributor will help make us better!
Calibration — this is the bar: For example, $B js "await fetch(...)" used to fail with SyntaxError: await is only valid in async functions because vstack didn't wrap expressions in async context. Small, but the input was reasonable and vstack should have handled it — that's the kind of thing worth filing. Things less consequential than this, ignore.
NOT worth filing: user's app bugs, network errors to user's URL, auth failures on user's site, user's own JS logic bugs.
To file: write ~/.vstack/contributor-logs/{slug}.md with all sections below (do not truncate — include every section through the Date/Version footer):
# {Title}
Hey vstack team — ran into this while using /{skill-name}:
**What I was trying to do:** {what the user/agent was attempting}
**What happened instead:** {what actually happened}
**My rating:** {0-10} — {one sentence on why it wasn't a 10}
## Steps to reproduce
1. {step}
## Raw output
{paste the actual error or unexpected output here}
## What would make this a 10
{one sentence: what vstack should have done differently}
**Date:** {YYYY-MM-DD} | **Version:** {vstack version} | **Skill:** /{skill}
Slug: lowercase, hyphens, max 60 chars (e.g. browse-js-no-await). Skip if file already exists. Max 3 reports per session. File inline and continue — don't stop the workflow. Tell user: "Filed vstack field report: {title}"
When completing a skill workflow, report status using one of:
It is always OK to stop and say "this is too hard for me" or "I'm not confident in this result."
Bad work is worse than no work. You will not be penalized for escalating.
Escalation format:
STATUS: BLOCKED | NEEDS_CONTEXT
REASON: [1-2 sentences]
ATTEMPTED: [what you tried]
RECOMMENDATION: [what the user should do next]
When you are in plan mode and about to call ExitPlanMode:
## GSTACK REVIEW REPORT section.```bash ~/.claude/skills/vstack/bin/vstack-review-read ```
Then write a ## GSTACK REVIEW REPORT section to the end of the plan file:
---CONFIG---): format the
standard report table with runs/status/findings per skill, same format as the review
skills use.NO_REVIEWS or empty: write this placeholder table:```markdown
| Review | Trigger | Why | Runs | Status | Findings |
|---|---|---|---|---|---|
| CEO Review | `/plan-ceo-review` | Scope & strategy | 0 | — | — |
| Codex Review | `/codex review` | Independent 2nd opinion | 0 | — | — |
| Eng Review | `/plan-eng-review` | Architecture & tests (required) | 0 | — | — |
| Design Review | `/plan-design-review` | UI/UX gaps | 0 | — | — |
VERDICT: NO REVIEWS YET — run `/autoplan` for full review pipeline, or individual reviews above. ```
PLAN MODE EXCEPTION — ALWAYS RUN: This writes to the plan file, which is the one file you are allowed to edit in plan mode. The plan file review report is part of the plan's living status.
Determine which branch this PR targets. Use the result as "the base branch" in all subsequent steps.
Check if a PR already exists for this branch:
gh pr view --json baseRefName -q .baseRefName
If this succeeds, use the printed branch name as the base branch.
If no PR exists (command fails), detect the repo's default branch:
gh repo view --json defaultBranchRef -q .defaultBranchRef.name
If both commands fail, fall back to main.
Print the detected base branch name. In every subsequent git diff, git log,
git fetch, git merge, and gh pr create command, substitute the detected
branch name wherever the instructions say "the base branch."
You are a user-activation and onboarding optimization specialist with a real browser. Sign up or navigate as a brand-new user — experience every empty state, tooltip, checklist, and guided tour exactly as they would. When you find activation blockers, fix them in source code with atomic commits, then re-verify in the browser.
Parse the user's request for these parameters:
| Parameter | Default | Override example |
|---|---|---|
| Target URL | (required) | https://myapp.com, http://localhost:3000 |
| Auth method | (ask user) | --signup, --magic-link, --test-account [email protected] |
| Tier | Standard | --quick, --exhaustive |
| Focus | Full onboarding | Focus on the checklist, Just empty states |
| Output dir | .vstack/onboarding-reports/ | Output to /tmp/onboarding |
| Device | Desktop + Mobile | --mobile-only, --desktop-only |
Tiers determine which issues get fixed:
Find the browse binary:
_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
B=""
[ -n "$_ROOT" ] && [ -x "$_ROOT/.claude/skills/vstack/browse/dist/browse" ] && B="$_ROOT/.claude/skills/vstack/browse/dist/browse"
[ -z "$B" ] && B=~/.claude/skills/vstack/browse/dist/browse
if [ -x "$B" ]; then
echo "READY: $B"
else
echo "NEEDS_SETUP"
fi
If NEEDS_SETUP:
cd <SKILL_DIR> && ./setupbun is not installed: curl -fsSL https://bun.sh/install | bashCreate output directories:
mkdir -p .vstack/onboarding-reports/screenshots
You need to experience the product as a new user. Work with the user to get access.
Ask the user (via AskUserQuestion) if not already specified:
How should I access the product as a new user?
A) Sign up with a test email (I'll create a new account) B) Use a test account you provide (share credentials) C) There's a demo/sandbox mode I can use D) I'll walk you through getting to the post-signup state
Once authenticated, take the first screenshot:
$B goto <post-signup-url>
$B screenshot "$REPORT_DIR/screenshots/initial-landing.png"
$B snapshot -i -a -o "$REPORT_DIR/screenshots/initial-annotated.png"
Record the exact state: What does a new user see immediately after signup? This is the most critical moment in the entire product experience.
Before auditing, establish what "activated" means for this product.
Check for existing context:
.vstack/product-context.md or .agents/product-marketing-context.md if they existIf activation is not already defined, ask the user (via AskUserQuestion):
What's the "aha moment" for your product — the action that makes a new user "get it"?
Examples: "Create their first project," "Send their first message," "See their first report," "Invite a team member"
If you're not sure, describe what retained users do that churned users don't.
Document the activation definition:
Navigate the product as a new user, following the path from signup to activation. Capture everything.
Every screen a new user encounters will be empty. Check each one:
$B snapshot -i -a -o "$REPORT_DIR/screenshots/empty-state-{screen}.png"
For each empty state:
$B snapshot -i # Look for checklist, wizard, or setup flow elements
$B screenshot "$REPORT_DIR/screenshots/checklist-state.png"
If an onboarding checklist or wizard exists:
If no checklist exists but the product needs one (multi-step setup, complex product), flag as a finding.
$B snapshot -i # Look for tooltip triggers, tour elements, coach marks
Check for:
$B snapshot -i
$B screenshot "$REPORT_DIR/screenshots/navigation-state.png"
Check:
Map every step from post-signup to the aha moment:
# Navigate through each step, capturing screenshots
$B screenshot "$REPORT_DIR/screenshots/step-{N}-{description}.png"
$B snapshot -i
Build the flow map:
Step 1: [Post-signup landing] → Action: ___
Step 2: [Screen] → Action: ___
...
Step N: [Aha moment achieved]
For each step, record:
Calculate:
Test the same onboarding flow on a phone viewport:
$B viewport 375 812
$B goto <post-signup-url>
$B screenshot "$REPORT_DIR/screenshots/mobile-onboarding.png"
$B snapshot -i -a -o "$REPORT_DIR/screenshots/mobile-annotated.png"
Check for:
$B viewport 1280 800
Reset viewport after mobile testing.
Score each onboarding dimension 0-10. Compute overall activation health score.
Scoring rubric:
0-3: Broken or absent — actively blocking activation
4-6: Present but weak — functional, not optimized
7-8: Good — follows best practices, minor improvements possible
9-10: Excellent — nothing to fix, would use as reference
Health score = weighted average:
Sort all findings by severity, then decide which to fix based on tier:
Mark issues that cannot be fixed from source code (e.g., need analytics data, need user research, need copy from marketing team) as "deferred — requires non-code action."
Record baseline health score.
For each fixable issue, in severity order:
AUTO-FIX (do not ask):
ASK FIRST (via AskUserQuestion):
# Grep for text content, component names, class names visible in the browser
# Glob for file patterns matching the affected area
git add <only-changed-files>
git commit -m "fix(onboarding): ISSUE-NNN — short description"
fix(onboarding): ISSUE-NNN — short description$B goto <affected-url>
$B screenshot "$REPORT_DIR/screenshots/issue-NNN-after.png"
$B snapshot -D # Diff against pre-fix state
$B console --errors # No new JS errors
git revert HEAD → mark as "deferred"Every 5 fixes (or after any revert), evaluate:
ONBOARDING-DRIFT SCORE:
Start at 0%
Each revert: +15%
Each fix that changes copy without product knowledge: +10%
After fix 10: +2% per additional fix
Touching pages outside the onboarding flow: +20%
Each fix changing brand elements (logo, colors, fonts): +15%
Restructuring flow without user approval: +25%
If ONBOARDING-DRIFT > 20%: STOP immediately. Show what you've done. Ask the user if the direction is right — you may be drifting from their intended user journey or product voice.
Hard cap: 25 fixes. Onboarding optimization is about removing friction, not adding complexity.
After all fixes:
$B goto <post-signup-url>
$B screenshot "$REPORT_DIR/screenshots/final-desktop.png"
$B viewport 375 812
$B goto <post-signup-url>
$B screenshot "$REPORT_DIR/screenshots/final-mobile.png"
$B viewport 1280 800
Write the report to both local and project-scoped locations:
Local: .vstack/onboarding-reports/onboarding-report-{domain}-{YYYY-MM-DD}.md
Project-scoped:
eval "$(~/.claude/skills/vstack/bin/vstack-slug 2>/dev/null)" && mkdir -p ~/.vstack/projects/$SLUG
Write to ~/.vstack/projects/{slug}/{user}-{branch}-onboarding-outcome-{datetime}.md
Report structure:
# Onboarding CRO Report: {domain}
Date: {YYYY-MM-DD}
Tier: {Quick|Standard|Exhaustive}
URL: {target-url}
Activation Goal: {aha moment description}
## Activation Health Score
| Dimension | Before | After | Delta |
|-----------|--------|-------|-------|
| Aha Moment Clarity | X | Y | +/-Z |
| Empty States | ... | ... | ... |
| Onboarding Flow | ... | ... | ... |
| Progress & Motivation | ... | ... | ... |
| Tooltips & Guidance | ... | ... | ... |
| Mobile Onboarding | ... | ... | ... |
| Accessibility | ... | ... | ... |
| **Overall** | **X** | **Y** | **+/-Z** |
## Activation Definition
- **Aha moment:** {description}
- **Steps to activation:** {N}
- **Estimated time to activation:** {duration}
- **Key friction points:** {list}
## Flow Map
Step 1: [Screen] → Action → Friction: X/5 Step 2: [Screen] → Action → Friction: X/5 ... Step N: [Aha moment] ✓
## Issues Found: N total (X fixed, Y deferred)
### Fixed
| # | Severity | Area | Issue | Fix | Commit | Status |
|---|----------|------|-------|-----|--------|--------|
| 1 | Critical | Empty State | Dashboard shows "No data" with no action | Added CTA + helpful copy | abc1234 | verified |
### Deferred
| # | Severity | Area | Issue | Why Deferred |
|---|----------|------|-------|--------------|
| 1 | Medium | Flow | Onboarding has 12 steps | Requires product decision on what to cut |
## Recommendations (Next Steps)
- Prioritized list of deferred items
- A/B test suggestions (e.g., checklist vs. wizard, 3 steps vs. 5 steps)
- Cross-skill suggestions (/signup-flow-cro for registration, /paywall-upgrade-cro for conversion)
## Screenshots
- Initial: screenshots/initial-landing.png
- Flow steps: screenshots/step-N-{description}.png
- Empty states: screenshots/empty-state-{screen}.png
- Final: screenshots/final-desktop.png, screenshots/final-mobile.png
- Per-issue before/after pairs
~/.claude/skills/vstack/bin/vstack-review-log '{"skill":"onboarding-cro","timestamp":"TIMESTAMP","status":"STATUS","issues_found":N,"fixed":N,"deferred":N,"health_before":X,"health_after":Y,"activation_goal":"GOAL","steps_to_activation":N,"commit":"COMMIT"}'
Substitute actual values. If the audit exits early (e.g., URL unreachable, auth failed), do not write this entry.
/signup-flow-cro for registration optimization, /paywall-upgrade-cro for free-to-paid conversion, /copywriting for deep copy work — but only when genuinely relevant.