Install the "user-journeys" agent skill from https://github.com/alinaqi/maggy/tree/main/skills/user-journeys into .claude/skills/user-journeys/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "user-journeys", then confirm the skill loads.
Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
skills CLI
$ npx skills add alinaqi/maggy --skill user-journeys -a codex
Project install goes to .agents/skills/; add -g for ~/.codex/skills/.
Install the "user-journeys" agent skill from https://github.com/alinaqi/maggy/tree/main/skills/user-journeys into .agents/skills/user-journeys/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "user-journeys", then confirm the skill loads.
Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add alinaqi/maggy --skill user-journeys -a cursor
Project install goes to .agents/skills/; add -g for ~/.cursor/skills/.
Install the "user-journeys" agent skill from https://github.com/alinaqi/maggy/tree/main/skills/user-journeys into .cursor/skills/user-journeys/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "user-journeys", then confirm the skill loads.
Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
skills CLI
$ npx skills add alinaqi/maggy --skill user-journeys -a gemini-cli
Project install goes to .agents/skills/; add -g for ~/.gemini/skills/.
Install the "user-journeys" agent skill from https://github.com/alinaqi/maggy/tree/main/skills/user-journeys into .gemini/skills/user-journeys/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "user-journeys", then confirm the skill loads.
Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
GitHub CLI
$ gh skill install alinaqi/maggy user-journeys
Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
skills CLI
$ npx skills add alinaqi/maggy --skill user-journeys -a github-copilot
Project install goes to .agents/skills/; add -g for ~/.copilot/skills/.
Install the "user-journeys" agent skill from https://github.com/alinaqi/maggy/tree/main/skills/user-journeys into .github/skills/user-journeys/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "user-journeys", then confirm the skill loads.
GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
skills CLI
$ npx skills add alinaqi/maggy --skill user-journeys -a opencode
OpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
Install the "user-journeys" agent skill from https://github.com/alinaqi/maggy/tree/main/skills/user-journeys into .opencode/skills/user-journeys/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "user-journeys", then confirm the skill loads.
OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
Facts
Skill name
user-journeys
GitHub stars
707
Token cost
~4.2k tokens
SKILL.md length
254 words
Files
1
Skills in repo
71
Repo updated
First seen
Licence
MIT
At a glance
User experience flows - journey mapping, UX validation, error recovery
Tasks that involve Customer journey mapping
SKILL.md covers Philosophy, Journey Documentation Structure, Journey Template and Critical Journey Examples, plus 6 more sections
Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
Tasks that involve UX design
What it does
User Journeys is an agent skill from alinaqi/maggy. User experience flows - journey mapping, UX validation, error recovery
Its SKILL.md is about 4.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Product & Project Management, covering Customer journey mapping and UX design. The repository describes itself as: What started as an opinionated Claude Code setup kit is now an autonomous AI engineering command center. The licence is MIT.
When your agent uses it
Tasks that involve Customer journey mapping
Tasks that involve UX design
Example prompts
“/user-journeys”
What it can do on your machine
Read from SKILL.md and the folder at commit 72a456e. It shows what the files ask for, not the result of running them.
Tool permissions
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Runs code
No scripts in the folder and no shell commands in SKILL.md (its code samples are markdown, typescript and json).
From the folder's file list and the shell code blocks in SKILL.md.
Network
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Credentials
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Context cost
User Journeys loads about 4.2k tokens when it runs. Until then it costs about 21 tokens; SKILL.md has 254 words of instructions outside code blocks.
Always· name and description, kept in context so the agent knows when to use it
~21
When it runs· the whole SKILL.md, loaded when a task matches
~4.2k
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
Safety
Auto-check passed
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
# Journey: [Name]
## Overview
| Attribute | Value |
|-----------|-------|
| **Priority** | Critical / High / Medium |
| **User Type** | New / Returning / Admin |
| **Frequency** | Daily / Weekly / One-time |
| **Success Metric** | Conversion rate, time to complete, drop-off rate |
## User Goal
What is the user trying to accomplish? Write from their perspective.
> "I want to [goal] so that I can [benefit]."
## Preconditions
- User state (logged in, has subscription, first visit)
- Data state (has items in cart, has team members)
- Environment (mobile, desktop, slow connection)
## Journey Steps
### Step 1: [Entry Point]
**User Action:** What the user does
**System Response:** What they should see/experience
**Success Criteria:**
- [ ] Page loads in < 2 seconds
- [ ] Primary CTA is immediately visible
- [ ] User understands what to do next
**Potential Friction:**
- Slow load time → Show skeleton/loader
- Unclear CTA → A/B test copy variations
---
### Step 2: [Next Action]
**User Action:** ...
**System Response:** ...
**Success Criteria:**
- [ ] ...
**Potential Friction:**
- ...
---
## Error Scenarios
### E1: [Error Name]
**Trigger:** What causes this error
**User Sees:** Error message/state
**Recovery Path:** How user gets back on track
**Test:** How to verify recovery works
## Metrics to Track
- Time to complete journey
- Drop-off rate at each step
- Error rate and recovery rate
- User satisfaction (if surveyed)
## E2E Test Reference
Link to Playwright test: `e2e/tests/journeys/[name].spec.ts`
Critical Journey Examples
Signup to First Value
markdown
# Journey: Signup to First Value
## Overview
| Attribute | Value |
|-----------|-------|
| **Priority** | Critical |
| **User Type** | New |
| **Frequency** | One-time |
| **Success Metric** | % reaching "aha moment" within 5 min |
## User Goal
> "I want to try this product quickly to see if it solves my problem."
## Preconditions
- First visit to site
- No account
- Came from landing page or ad
## Journey Steps
### Step 1: Landing Page
**User Action:** Clicks "Get Started Free" or "Try Now"
**System Response:** Signup form appears (modal or new page)
**Success Criteria:**
- [ ] CTA visible above fold
- [ ] No distracting elements
- [ ] Clear value proposition visible
**Potential Friction:**
- Too many form fields → Reduce to email + password only
- Social login missing → Add Google/GitHub options
### Step 2: Account Creation
**User Action:** Enters email and password (or uses social login)
**System Response:**
- Creates account
- Sends verification email (don't block on it)
- Redirects to onboarding
**Success Criteria:**
- [ ] Account created in < 3 seconds
- [ ] No email verification wall (verify later)
- [ ] Clear next step shown
**Potential Friction:**
- Email already exists → Offer login link
- Weak password → Show requirements inline, not after submit
### Step 3: Onboarding (Quick Win)
**User Action:** Completes 1-2 setup questions
**System Response:**
- Personalizes experience
- Shows progress indicator
- Leads to first action
**Success Criteria:**
- [ ] Max 3 questions
- [ ] Skip option available
- [ ] < 60 seconds total
**Potential Friction:**
- Too many questions → User abandons
- No skip option → User feels trapped
### Step 4: First Value (Aha Moment)
**User Action:** Completes core action (creates first X, sees first result)
**System Response:**
- Celebrates success
- Shows value delivered
- Suggests next step
**Success Criteria:**
- [ ] User experiences core value
- [ ] Completion feels rewarding
- [ ] Clear path to continue
## Error Scenarios
### E1: Email Already Registered
**Trigger:** User tries existing email
**User Sees:** "Already have an account? Log in or reset password"
**Recovery Path:** Click to login or reset
**Test:** `signup-existing-email.spec.ts`
### E2: Social Login Fails
**Trigger:** OAuth provider error
**User Sees:** "Couldn't connect. Try email signup or try again."
**Recovery Path:** Email signup form shown as fallback
**Test:** `social-login-failure.spec.ts`
## Metrics to Track
- Signup → First Value: Target < 5 min
- Drop-off at each step
- Social vs email signup ratio
- Skip rate on onboarding
Checkout Purchase
markdown
# Journey: Checkout Purchase
## Overview
| Attribute | Value |
|-----------|-------|
| **Priority** | Critical (Revenue) |
| **User Type** | Any |
| **Frequency** | Variable |
| **Success Metric** | Checkout completion rate |
## User Goal
> "I want to pay quickly and securely without surprises."
## Journey Steps
### Step 1: Cart Review
**User Action:** Views cart before checkout
**System Response:**
- Shows all items with images, prices
- Shows subtotal, taxes, shipping
- Clear "Checkout" CTA
**Success Criteria:**
- [ ] No hidden fees revealed later
- [ ] Easy to modify quantities
- [ ] Saved items visible
### Step 2: Checkout Start
**User Action:** Clicks "Checkout"
**System Response:**
- Shows checkout form or redirect to payment
- Progress indicator (Step 1 of 3)
- Order summary sidebar
**Success Criteria:**
- [ ] Guest checkout option
- [ ] Express checkout (Apple/Google Pay) prominent
- [ ] Form fields pre-filled if logged in
### Step 3: Payment
**User Action:** Enters payment info
**System Response:**
- Secure input fields (Stripe/payment provider)
- Real-time validation
- Clear "Pay $XX" button
**Success Criteria:**
- [ ] Card validation inline, not after submit
- [ ] Multiple payment options
- [ ] Security indicators visible
### Step 4: Confirmation
**User Action:** Submits payment
**System Response:**
- Processing indicator
- Success page with order details
- Email confirmation sent
**Success Criteria:**
- [ ] Confirmation within 5 seconds
- [ ] Order number clearly visible
- [ ] Next steps clear (shipping, access, etc.)
## Error Scenarios
### E1: Payment Declined
**Trigger:** Card declined by processor
**User Sees:** "Payment declined. Please try another card."
**Recovery Path:**
- Stay on payment step
- Pre-fill other fields
- Offer alternative payment methods
**Test:** `payment-declined-recovery.spec.ts`
### E2: Session Timeout During Checkout
**Trigger:** User away too long
**User Sees:** Cart preserved, re-auth required
**Recovery Path:**
- Quick login
- Return to same checkout step
- Cart contents intact
**Test:** `checkout-session-timeout.spec.ts`
Journey Testing with Playwright
Journey Test Structure
typescript
// e2e/tests/journeys/signup-to-value.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Journey: Signup to First Value', () => {
test.describe.configure({ mode: 'serial' }); // Run in order
test('Step 1: Landing page has clear CTA', async ({ page }) => {
await page.goto('/');
// CTA visible above fold without scrolling
const cta = page.getByRole('button', { name: /get started|try free/i });
await expect(cta).toBeVisible();
await expect(cta).toBeInViewport();
});
test('Step 2: Can create account quickly', async ({ page }) => {
await page.goto('/');
await page.getByRole('button', { name: /get started/i }).click();
// Minimal fields
await expect(page.getByLabel('Email')).toBeVisible();
await expect(page.getByLabel('Password')).toBeVisible();
// Complete signup
const startTime = Date.now();
await page.getByLabel('Email').fill('newuser@example.com');
await page.getByLabel('Password').fill('SecurePass123!');
await page.getByRole('button', { name: /sign up|create/i }).click();
// Should reach onboarding quickly
await expect(page).toHaveURL(/onboarding|welcome|setup/);
expect(Date.now() - startTime).toBeLessThan(5000); // < 5 seconds
});
test('Step 3: Onboarding is skippable', async ({ page }) => {
// ... login as new user ...
await page.goto('/onboarding');
// Skip option exists
const skipButton = page.getByRole('button', { name: /skip/i });
await expect(skipButton).toBeVisible();
});
test('Step 4: Can reach first value in < 5 min', async ({ page }) => {
// Full journey timing
const journeyStart = Date.now();
// ... complete full journey ...
// Verify first value delivered
await expect(page.getByText(/success|created|done/i)).toBeVisible();
// Total time check
const totalTime = (Date.now() - journeyStart) / 1000 / 60; // minutes
expect(totalTime).toBeLessThan(5);
});
});
Error Recovery Tests
typescript
// e2e/tests/journeys/checkout-recovery.spec.ts
import { test, expect } from '@playwright/test';
test.describe('Journey: Checkout Error Recovery', () => {
test('recovers from payment decline gracefully', async ({ page }) => {
// Setup: Add item to cart, go to checkout
await page.goto('/products');
await page.getByTestId('add-to-cart').first().click();
await page.getByRole('link', { name: 'Checkout' }).click();
// Use Stripe test card that declines
const stripeFrame = page.frameLocator('iframe[name*="stripe"]');
await stripeFrame.getByPlaceholder('Card number').fill('4000000000000002');
await stripeFrame.getByPlaceholder('MM / YY').fill('12/30');
await stripeFrame.getByPlaceholder('CVC').fill('123');
await page.getByRole('button', { name: /pay/i }).click();
// Verify friendly error
await expect(page.getByText(/declined|try another/i)).toBeVisible();
// Verify still on checkout (not kicked out)
await expect(page).toHaveURL(/checkout/);
// Verify can try again with different card
await stripeFrame.getByPlaceholder('Card number').fill('4242424242424242');
await page.getByRole('button', { name: /pay/i }).click();
// Should succeed now
await expect(page).toHaveURL(/success|confirmation/);
});
test('preserves cart after session timeout', async ({ page, context }) => {
// Add items to cart
await page.goto('/products');
await page.getByTestId('add-to-cart').first().click();
// Clear session (simulate timeout)
await context.clearCookies();
// Return to site
await page.goto('/cart');
// Cart should be preserved (local storage or recovered)
await expect(page.getByTestId('cart-item')).toHaveCount(1);
});
});
User Experience Validation
UX Checklist per Journey Step
markdown
## UX Validation Checklist
### Clarity
- [ ] User knows where they are (breadcrumbs, progress)
- [ ] User knows what to do next (clear CTA)
- [ ] User knows what just happened (feedback)
### Speed
- [ ] Page loads < 2 seconds
- [ ] Actions complete < 3 seconds
- [ ] Progress shown for longer operations
### Forgiveness
- [ ] Mistakes are easy to undo
- [ ] Errors explain what went wrong
- [ ] Recovery path is clear
### Accessibility
- [ ] Keyboard navigation works
- [ ] Screen reader announces changes
- [ ] Focus management correct
- [ ] Color contrast sufficient
### Mobile
- [ ] Touch targets >= 44px
- [ ] No horizontal scroll
- [ ] Forms don't zoom unexpectedly
- [ ] Works on slow 3G
Automated UX Checks
typescript
// e2e/utils/ux-validators.ts
import { Page, expect } from '@playwright/test';
export async function validatePageLoad(page: Page, maxMs = 2000) {
const timing = await page.evaluate(() => {
const nav = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
return nav.loadEventEnd - nav.startTime;
});
expect(timing).toBeLessThan(maxMs);
}
export async function validateCTAVisible(page: Page, ctaText: RegExp) {
const cta = page.getByRole('button', { name: ctaText });
await expect(cta).toBeVisible();
await expect(cta).toBeInViewport();
}
export async function validateNoLayoutShift(page: Page) {
const cls = await page.evaluate(() => {
return new Promise<number>((resolve) => {
let clsValue = 0;
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (!(entry as any).hadRecentInput) {
clsValue += (entry as any).value;
}
}
});
observer.observe({ type: 'layout-shift', buffered: true });
setTimeout(() => {
observer.disconnect();
resolve(clsValue);
}, 1000);
});
});
expect(cls).toBeLessThan(0.1); // Good CLS score
}
export async function validateAccessibility(page: Page) {
// Check focus visible on interactive elements
const buttons = page.getByRole('button');
const count = await buttons.count();
for (let i = 0; i < Math.min(count, 5); i++) {
await buttons.nth(i).focus();
await expect(buttons.nth(i)).toBeFocused();
}
}
User Journeys next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
Complete Product Owner / Product Manager capability — a wiki-style knowledge map of product practice in active software development: the role and its boundaries, strategy cascade (vision → OKRs →…
UX research and design toolkit for Senior UX Designer/Researcher including data-driven persona generation, journey mapping, usability testing frameworks, and research synthesis.
Writes usage scenarios, use cases and storyboards that show real people using screen readers, switches, voice control and other assistive technology to finish tasks.
User experience flows - journey mapping, UX validation, error recovery. User Journeys is an agent skill from alinaqi/maggy.
When should I use User Journeys?
User Journeys fits situations like: tasks that involve Customer journey mapping; tasks that involve UX design.
How do I install User Journeys in Claude Code?
Run `npx skills add alinaqi/maggy --skill user-journeys -a claude-code`. Or copy the skill folder (skills/user-journeys in alinaqi/maggy) into .claude/skills/user-journeys in your project. Claude Code loads it when a task matches its description.
How do I install User Journeys in Codex?
Run `npx skills add alinaqi/maggy --skill user-journeys -a codex`. Or copy the skill folder (skills/user-journeys in alinaqi/maggy) into .agents/skills/user-journeys in your project. Codex loads it when a task matches its description.
Can I use User Journeys in Cursor, Gemini CLI or GitHub Copilot?
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add alinaqi/maggy --skill user-journeys -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/user-journeys, .gemini/skills/user-journeys, .github/skills/user-journeys and .opencode/skills/user-journeys in your project.
What does User Journeys need to run?
SKILL.md names no scripts, command-line tools or credentials: User Journeys is instructions for the agent only.
Does User Journeys access the network?
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Is User Journeys safe to install?
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
What licence does User Journeys use?
User Journeys is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
How many tokens does User Journeys use?
About 4.2k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
What are the alternatives to User Journeys?
Skills that share tags, products or a category with User Journeys: Super Product Owner (syahiidkamil/Software-Engineer-AI-Agent-Atlas, 401 stars), UX Researcher Designer (alirezarezvani/claude-skills, 28k stars), UX Researcher Designer (borghei/Claude-Skills, 891 stars) and User Onboarding (manojbajaj95/claude-gtm-plugin, 105 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
Who maintains User Journeys?
alinaqi (a GitHub user) maintains it in alinaqi/maggy, which has 707 GitHub stars. The repository holds 71 skills in this directory. The repository was last updated on September 24, 2026.
Source: alinaqi/maggy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.