flow

SKILL.md

<tool_restrictions>

MANDATORY Tool Restrictions

BANNED TOOLS — calling these is a skill violation:

  • EnterPlanMode — BANNED. Do NOT call this tool. This skill manages its own workflow.
  • ExitPlanMode — BANNED. You are never in plan mode. There is nothing to exit.

REQUIRED TOOLS:

  • AskUserQuestion — ALWAYS use this for questions. Never ask questions as plain text. Every question — confirming dev server, auth status, handling stale flows — MUST use AskUserQuestion. Keep context before the question to 2-3 sentences max. </tool_restrictions>

User Flow Discovery & Verification

Discover user flows from your codebase, store them as walkable artifacts, and execute them in Chrome to verify they work.

Announce at start: "I'm using the flow skill to [discover/walk/check] user flows."


Mode Dispatch

Parse the first argument to determine mode:

Argument Mode Description
discover Discover Scan codebase, generate flow artifacts
walk Walk Execute stored flows in browser
check Check Detect drift via file checksums
(none) Smart routing Assess state, ask what to do

Mode: Smart Routing (no arguments)

When invoked without a mode argument, assess the current state and route intelligently.

Step 1: Check State

Check if docs/arc/flows/ exists and read any .md files. Count flows by status.

Step 2: Route Based on State

No flows exist (directory missing or empty):

"No user flows discovered yet. I'll scan your codebase for routes and generate walkable flows."

→ Proceed directly to Discover mode. No question needed — discovery is the only useful action.

Flows exist, some are stale: Show a brief status summary, then ask:

AskUserQuestion:
  question: "[X] flows found ([Y] stale). What would you like to do?"
  header: "User Flows"
  options:
    - label: "Check for drift"
      description: "[Y] flows may be out of date — check which source files changed"
    - label: "Walk all flows"
      description: "Execute all [X] flows in Chrome to verify they work"
    - label: "Re-discover"
      description: "Regenerate stale flows from current code"
    - label: "Discover new routes"
      description: "Scan for routes not yet covered by flows"

Flows exist, none stale, some not yet walked:

AskUserQuestion:
  question: "[X] flows found ([V] not yet walked). What would you like to do?"
  header: "User Flows"
  options:
    - label: "Walk all flows"
      description: "Execute flows in Chrome to verify they work"
    - label: "Walk unwalked only"
      description: "Just the [V] flows that haven't been tested yet"
    - label: "Check for drift"
      description: "See if source files have changed since discovery"
    - label: "Discover new routes"
      description: "Scan for routes not yet covered"

Flows exist, all current and passed:

AskUserQuestion:
  question: "All [X] flows are current and passing. What would you like to do?"
  header: "User Flows"
  options:
    - label: "Walk all flows"
      description: "Re-run all flows to verify they still pass"
    - label: "Check for drift"
      description: "See if any source files have changed"
    - label: "Discover new routes"
      description: "Scan for routes not yet covered"

Flows exist, some failed:

AskUserQuestion:
  question: "[X] flows found ([Z] failing). What would you like to do?"
  header: "User Flows"
  options:
    - label: "Walk failed flows"
      description: "Re-run the [Z] failing flows to see if they pass now"
    - label: "Walk all flows"
      description: "Execute all [X] flows"
    - label: "Check for drift"
      description: "See if source files have changed"
    - label: "Re-discover failed"
      description: "Regenerate the failing flows from current code"

After the user selects, proceed to the corresponding mode.


Mode: Discover

Step 1: Detect Framework

Check package.json for framework:

Check Framework Route glob pattern
"next" in dependencies Next.js App Router app/**/page.{tsx,jsx,ts,js} (exclude app/api/**)
"next" + pages/ dir exists Next.js Pages Router pages/**/*.{tsx,jsx,ts,js} (exclude pages/api/**)
"@sveltejs/kit" in dependencies SvelteKit src/routes/**/+page.svelte
"@remix-run" in dependencies Remix app/routes/**/*.{tsx,jsx}

If no framework detected:

"Could not detect a supported framework. Supported: Next.js, SvelteKit, Remix.
Is this the right directory?"

Stop.

Step 2: Glob for Routes

Use the detected glob pattern to find all route files.

If zero routes found:

"No route files found using pattern [pattern]. Is this the right directory?
Detected framework: [framework]"

Stop.

Step 3: Classify Routes (Auth)

Read middleware/proxy file to determine which routes are protected:

Framework Auth file to check
Next.js proxy.ts, middleware.ts, src/proxy.ts, src/middleware.ts
SvelteKit src/hooks.server.ts
Remix app/root.tsx or route-level loaders

Detect auth provider by scanning package.json dependencies and middleware:

Signal Provider
@clerk/nextjs + clerkMiddleware Clerk
@workos-inc/authkit-nextjs + authkitMiddleware WorkOS
Session/JWT patterns without known provider Self-rolled
No auth middleware None
Both Clerk and WorkOS detected Ask user which is primary

Classify each route:

  • Routes explicitly in public matchers → auth: none
  • Routes behind middleware protection → auth: user
  • Routes with role checks (admin, org) → auth: admin or auth: org-admin
  • If unclear → default to auth: user (safer to over-classify)

Step 4: Check Existing Flows

If docs/arc/flows/ already has .md files:

Read each existing flow file's route field. Build a set of already-discovered routes.

Check if --force was passed as an argument.

  • Without --force: Skip routes that already have a flow file. Report: "Found X existing flows. New routes will be added, existing flows preserved."
  • With --force: Overwrite all. Report: "Found X existing flows. All will be regenerated (--force)."

Step 5: Group Routes

Group remaining routes by top-level path segment:

  • /root group
  • /about, /pricingmarketing group (or by first segment)
  • /dashboard/*dashboard group
  • /settings/*settings group

Max 10 routes per group. If a group exceeds 10, split it.

Step 6: Dispatch Flow Discoverer Agents

For each route group, dispatch the flow-discoverer agent via a parallel Agent tool call:

Agent flow-discoverer: "Discover user flows for these routes.

Framework: [detected framework]
Auth provider: [detected provider]
Today's date: [YYYY-MM-DD]

Routes in this group:
1. [route path] → [file path] (auth: [level])
2. [route path] → [file path] (auth: [level])
...

Read each route's component code, follow imports to find interactive elements,
and generate flow artifacts using the step DSL.

See agents/workflow/flow-discoverer.md for the full protocol."

Dispatch all groups in a single message for maximum parallelism.

If an agent errors or times out, log a warning and continue with other groups:

"Warning: Could not discover flows for [group name] routes. [X] other groups completed successfully."

Step 7: Write Flow Files

Parse each agent's output for flow artifacts (separated by --- FLOW: <name> ---).

For each flow artifact:

  1. Create docs/arc/flows/<name>.md with the artifact content
  2. If the file already exists and --force was not passed, skip it

Step 8: Report

Discovery complete:
- Routes scanned: X
- Flows generated: Y (Z public, W authenticated)
- Skipped (already existed): V
- Auth provider: [provider]

Flows written to docs/arc/flows/

Next steps:
- /arc:flow walk --all — Execute all flows in Chrome
- /arc:flow check — Check for drift later

Mode: Walk

Step 1: Select Browser Tool

Browser tool hierarchy:

  1. Chrome MCP (preferred) — mcp__claude-in-chrome__* tools
  2. agent-browser/agent-browser skill as fallback outside Claude Code
  3. Playwright — scripted browser fallback as last resort

Check for Chrome MCP availability first. If Chrome MCP tools are not available, check for agent-browser. If neither is available, note that Playwright would need to be scripted manually and ask the user how to proceed.

Step 2: Confirm Dev Server

AskUserQuestion:
  question: "What's your dev server URL?"
  header: "Dev server"
  options:
    - label: "localhost:3000"
      description: "Default Next.js / Remix dev server"
    - label: "localhost:5173"
      description: "Default Vite / SvelteKit dev server"
    - label: "localhost:4321"
      description: "Default Astro dev server"
    - label: "Custom URL"
      description: "I'll type the URL"

Step 3: Verify Dev Server

Navigate the browser to the base URL:

mcp__claude-in-chrome__tabs_context_mcp (get current tabs)
mcp__claude-in-chrome__navigate to [base URL]

If the page fails to load or shows a connection error:

"Dev server doesn't seem to be running at [URL]. Please start it and try again."

Stop.

Step 4: Read Flow Files

Read all .md files from docs/arc/flows/.

If no flows found:

"No flows found in docs/arc/flows/. Run /arc:flow discover first."

Stop.

Filter flows:

  • --flow <name>: Walk only the named flow
  • --all: Walk all flows
  • No filter specified: Ask which flows to walk

Sort order: Public flows first (auth: none), then authenticated flows.

Stale flow handling:

  • If stale flows are selected and --force was NOT passed:
    AskUserQuestion:
      question: "Some selected flows are stale (source files changed). Walk them anyway?"
      header: "Stale flows"
      options:
        - label: "Walk anyway"
          description: "Run the flows as-is — they may fail due to code changes"
        - label: "Skip stale"
          description: "Only walk current flows"
        - label: "Re-discover first"
          description: "Regenerate stale flows from current code, then walk"
    

Step 5: Auth Gate

If any selected flows have auth other than none:

  1. Detect auth provider (scan package.json and middleware)
  2. Report:
    "Your app uses [provider]. [X] flows require authentication.
    Please log in to your app at [base URL] in Chrome, then confirm."
    
  3. Ask:
    AskUserQuestion:
      question: "Are you logged in?"
      header: "Authentication"
      options:
        - label: "Yes, I'm logged in"
          description: "Continue with all flows including authenticated ones"
        - label: "Skip authenticated flows"
          description: "Only walk public flows for now"
    

Step 6: Walk Each Flow

For each flow in order (public first, then authenticated):

  1. Navigate to [base URL][route]

    mcp__claude-in-chrome__navigate to [full URL]
    
  2. Execute each step sequentially:

    • navigate: mcp__claude-in-chrome__navigate
    • click: mcp__claude-in-chrome__find to locate element, then mcp__claude-in-chrome__computer to click
    • fill: mcp__claude-in-chrome__form_input with selector and value
    • select: mcp__claude-in-chrome__form_input with selector and value
    • wait: mcp__claude-in-chrome__find with retries
  3. Check expectations after each step:

    • expect: url /path — read current tab URL, check it ends with /path
    • expect: visible "text"mcp__claude-in-chrome__find for the text
    • expect: heading "text"mcp__claude-in-chrome__find for heading with text
    • expect: not-visible "text"mcp__claude-in-chrome__find returns no match
  4. Resolve $ENV_VAR values before filling:

    echo $TEST_EMAIL
    

    If a variable is not set, abort with: "Missing environment variable: [VAR]. Set it before walking authenticated flows."

  5. Translate >> selectors: button >> "Create Account" → use mcp__claude-in-chrome__find with query Create Account, then verify the matched element is a button, then click it.

  6. On step failure (element not found, expectation failed, timeout):

    • Record: flow name, failing step index, step text, error message
    • Mark flow as failed
    • Skip remaining steps
    • Move to next flow
  7. On all steps passed:

    • Mark flow as passed

Step 7: Update Flow Files

For each walked flow, update the frontmatter:

  • Set last_walked: YYYY-MM-DD
  • Set status: passed or status: failed

Use the Edit tool to update only the frontmatter fields, preserving the rest of the file.

Step 8: Report Results

Walk complete:

Passed (X):
  ✓ signup-create-account
  ✓ home-view
  ✓ dashboard-view

Failed (Y):
  ✗ settings-profile-edit — Step 3: fill [name="phone"] → element not found
  ✗ checkout-submit — Step 5: expect url /confirmation → got /checkout/error

Skipped (Z):
  ○ admin-users-list — auth required, skipped

Mode: Check

Step 1: Read All Flows

Read all .md files from docs/arc/flows/.

If no flows found:

"No flows to check. Run /arc:flow discover first."

Stop.

Step 2: Compute Current Checksums

For each flow, read the source_files list from frontmatter.

For each source file:

sha256sum <file path> | cut -c1-8

If a source file doesn't exist:

  • Record: "source file not found: [path]"
  • Mark flow as needing staleness update

Step 3: Compare Checksums

For each flow:

  • If all checksums match stored values → flow is current
  • If any checksum differs OR any source file is missing → flow is stale

Step 4: Update Stale Flows

For each stale flow:

  • Set status: stale in frontmatter
  • If a source file was deleted, add to Notes: "Source file not found: [path] (detected [date])"

Step 5: Report

Drift check complete:

Current (X):
  ✓ home-view
  ✓ signup-create-account

Stale (Y):
  ⚠ dashboard-view — src/components/dashboard-stats.tsx changed
  ⚠ settings-profile-edit — src/app/settings/profile/page.tsx changed
  ⚠ admin-users-list — src/components/admin/user-table.tsx deleted

Step 6: Offer Next Steps

If stale flows found:

AskUserQuestion:
  question: "What would you like to do with the stale flows?"
  header: "Stale flows"
  options:
    - label: "Re-discover"
      description: "Regenerate stale flows from current code"
    - label: "Walk anyway"
      description: "Run the stale flows to see if they still pass"
    - label: "Do nothing"
      description: "Just the report for now"

If "Re-discover": Run the Discover mode for only the stale routes (re-read the route files, dispatch flow-discoverer for those routes, overwrite the stale flow files).

If "Walk anyway": Run the Walk mode with --force for the stale flows.

<required_reading> Read before running:

  • docs/arc/specs/2026-03-13-user-flows-design.md — Full design spec with decisions and rationale
  • references/authentication.md — Auth patterns for Clerk, WorkOS, self-rolled (when auth is detected)
  • references/platform-tools.md — Browser tool mappings across platforms </required_reading>

<progress_append> After completing any mode, append to progress journal:

## YYYY-MM-DD HH:MM — /arc:flow [mode]
**Task:** [Mode] user flows
**Outcome:** [Complete / Partial]
**Details:**
- Mode: [discover/walk/check]
- Flows: [count by status]
- Auth: [detected provider]
**Next:** [suggested next step]

---

</progress_append>

Weekly Installs
1
Repository
howells/arc
GitHub Stars
15
First Seen
3 days ago
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1