{"content":"# User Stories Setup\n\nCreate a structured format for documenting feature requirements as user stories. JSON files with testable acceptance criteria that AI agents can verify and track.\n\nUser stories provide structured acceptance criteria for features that AI coding agents can verify. Each story is a JSON file with testable scenarios.\n\n---\n\n## Step 1: Create the Directory Structure\n\nCreate a `docs/user-stories/` directory in your project root:\n\n```bash\nmkdir -p docs/user-stories\n```\n\n## Step 2: Add the Verification Script\n\nCreate `scripts/verify-user-stories.ts` to validate all user stories have the correct format:\n\n```typescript\n#!/usr/bin/env bun\n/**\n * Verify all user stories have correct format\n *\n * Usage: bun scripts/verify-user-stories.ts\n */\nimport { readdirSync, readFileSync, statSync, existsSync } from \"fs\";\nimport { join, extname } from \"path\";\nimport { z } from \"zod\";\n\nconst FeatureSchema = z.object({\n  description: z.string().min(1),\n  steps: z.array(z.string().min(1)).min(1),\n  passes: z.boolean(),\n});\n\nconst UserStorySchema = z.array(FeatureSchema).min(1);\n\nconst rootDir = join(import.meta.dir, \"..\");\nconst userStoriesDir = join(rootDir, \"docs\", \"user-stories\");\n\nlet hasErrors = false;\n\nfunction error(msg: string) {\n  console.error(`  ${msg}`);\n  hasErrors = true;\n}\n\nfunction success(msg: string) {\n  console.log(`  ${msg}`);\n}\n\nfunction validateDirectory(dir: string, prefix = \"\") {\n  const entries = readdirSync(dir);\n\n  for (const entry of entries) {\n    const entryPath = join(dir, entry);\n    const stat = statSync(entryPath);\n\n    if (stat.isDirectory()) {\n      // Recursively validate subdirectories\n      console.log(`${prefix}${entry}/`);\n      validateDirectory(entryPath, prefix + \"  \");\n      continue;\n    }\n\n    // Check for non-JSON files\n    if (extname(entry) !== \".json\") {\n      error(`${prefix}${entry} - not a .json file`);\n      continue;\n    }\n\n    // Validate JSON file\n    try {\n      const content = readFileSync(entryPath, \"utf-8\");\n      const json = JSON.parse(content);\n      const result = UserStorySchema.safeParse(json);\n\n      if (!result.success) {\n        error(`${prefix}${entry} - invalid schema`);\n        for (const issue of result.error.issues) {\n          console.log(`${prefix}    ${issue.path.join(\".\")}: ${issue.message}`);\n        }\n      } else {\n        const passing = result.data.filter((f) => f.passes).length;\n        const total = result.data.length;\n        success(`${prefix}${entry} (${passing}/${total} passing)`);\n      }\n    } catch (e) {\n      if (e instanceof SyntaxError) {\n        error(`${prefix}${entry} - invalid JSON: ${e.message}`);\n      } else {\n        error(`${prefix}${entry} - ${e}`);\n      }\n    }\n  }\n}\n\nconsole.log(`\\nVerifying user stories...\\n`);\n\nif (!existsSync(userStoriesDir)) {\n  console.log(\"No docs/user-stories directory found\\n\");\n  process.exit(0);\n}\n\nvalidateDirectory(userStoriesDir);\n\nconsole.log();\n\nif (hasErrors) {\n  console.log(\"Verification failed\\n\");\n  process.exit(1);\n} else {\n  console.log(\"All user stories valid\\n\");\n  process.exit(0);\n}\n```\n\n## Step 3: Add npm Script\n\nAdd a script to `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"user-stories:verify\": \"bun run scripts/verify-user-stories.ts\"\n  }\n}\n```\n\n---\n\n## JSON Format\n\nEach user story file is a JSON array of features:\n\n```json\n[\n  {\n    \"description\": \"User signs in with email and password\",\n    \"steps\": [\n      \"Navigate to /sign-in page\",\n      \"Enter email and password\",\n      \"Submit the form\",\n      \"Verify successful login\",\n      \"Verify redirect to /chats\"\n    ],\n    \"passes\": false\n  }\n]\n```\n\n### Fields\n\n- **description**: One-line summary of the feature/behavior being tested\n- **steps**: Array of verifiable actions or assertions\n- **passes**: `true` when verified working, `false` when not yet implemented or failing\n\n### File Naming\n\nUse kebab-case names that describe the feature area. Group related scenarios in one file:\n\n- `authentication-sign-in.json` - sign-in flows\n- `authentication-sign-up.json` - sign-up flows\n- `chat-create.json` - chat creation behaviors\n- `profile-change-password.json` - password change flow"}