Generates full scam experience story content for Scam Avenger: narrative, first-person, emotional stories in eight sections. Input: CSV file (serial_number, title, category, optional angle/region, status, story_file) and either serial number (batch size 1) or serial number + batch size. Updates CSV status to done after each batch. One run = story creation + website integration (index listing, links, story page, sitemap, feed). User expectations (style, CSV as queue, batch/serial, story_file for cloud) are in the skill and in docs/STORY_DEVELOPMENT_EXPERIENCE.md. Cloud output format: docs/STORY_CLOUD_OUTPUT_FORMAT.md. Use when the user asks to create scam stories from a CSV, run a batch by serial number, or produce story files for frontend integration.
Generate scam stories that are narrative, first-person, and emotionally engaging. Stories can be driven from a CSV file using a serial number (and optional batch size); after completing each batch, update the CSV status column to done.
One run = story creation + full website integration. When you edit scam-stories.ts and add a story file under scam-stories-content/ (one file per story: {slug}.ts), the story is automatically listed on the stories index page, linked from the index, and rendered on its /stories/[slug] page; the sitemap and RSS feed also include it. No separate integration step is needed.
Path resolution: All paths in this skill (e.g. docs/story-queue.csv, docs/STORY_CLOUD_OUTPUT_FORMAT.md, frontend/src/data/scam-stories-content/) are relative to the project/workspace root (the repository root where the skill is used), not relative to the skill file’s location (.cursor/skills/scamenger-story-writer/). When the agent runs in the scamenger repo, docs/ and resolve to that repo’s and directories. Use these paths as-is in prompts (e.g. “from ”). The skill's own is (section definitions, emotional goals, copy-paste prompts, and format rules).
frontend/docs/frontend/docs/story-queue.csv.cursor/skills/scamenger-story-writer/reference.mdThe following expectations apply whether you run in-repo (editing TS directly) or produce cloud output (e.g. JSON files for later integration). For full rationale, read docs/STORY_DEVELOPMENT_EXPERIENCE.md.
pending rows are processed. After a story is successfully created, set that row's status to done and write the CSV back so progress is persisted.story_file (e.g. {slug}.json) is the expected output filename. Cloud code should write one file per story with that name; see docs/STORY_CLOUD_OUTPUT_FORMAT.md for the exact JSON shape. After integration, set the row's status to done and save the CSV.| Input | Required | Description |
|---|---|---|
| CSV file path | Yes | Path to a CSV with columns: serial_number, title, category, angle_or_region (optional), status, story_file. Optional column: slug. |
| Serial number | When using serial | Row number (1-based) in the CSV. Used to select which row(s) to process. |
| Batch size | Optional | Integer ≥ 1. If only serial number is given, treat batch size = 1. If serial number and batch size are both given, process up to that many pending rows starting from that serial. If only batch size is given (no serial), process the first N pending rows. |
Invocation modes:
serial_number if it is pending.serial_number ≥ given serial and status = pending, take the first batch size rows in order and process them.serial_number,title,category,angle_or_region,status,story_file. Use docs/story-queue.csv (full list) or docs/story-queue-example.csv (sample). Rows to process must have status = pending.scam-stories.ts and adds one file per story under scam-stories-content/{slug}.ts (and registers it in scam-stories-content/index.ts), sets those rows' status to done, and saves the CSV. This creates the story and integrates it with the website in one go: the story appears on the index page, is linked from the index, and has a full page at /stories/[slug]; the sitemap and stories RSS feed pick it up automatically./stories and /stories/[slug] to confirm the new story is listed and renders.Use these as templates; replace the CSV path and numbers as needed.
Serial only (one story, batch size = 1):
docs/story-queue.csv.docs/story-queue-example.csv.Serial + batch size (multiple stories starting from a serial):
docs/story-queue.csv starting at serial 10 with batch size 3.docs/story-queue.csv, process serial 1 with batch size 2.Batch size only (first N pending):
docs/story-queue.csv.docs/story-queue.csv with batch size 2.With explicit skill mention:
docs/story-queue.csv, serial 7, batch size 1.docs/story-queue.csv from serial 20 with batch size 4.serial_number,title,category,angle_or_region,status,story_file (first column is 1-based serial).{slug}.json). Use this name so the file can be copied and integrated into the frontend; see docs/STORY_CLOUD_OUTPUT_FORMAT.md for the expected JSON shape.status = pending (case-insensitive) are processed. Set to done after generating content.status to done and write the CSV file back to the same path.Example:
serial_number,title,category,angle_or_region,status,story_file
1,"The guru and the pump-and-dump group",financial,,"pending",the-guru-and-the-pump-and-dump-group.json
2,LPG payment pending link phone hijacked,online,India,"pending",lpg-payment-pending-link-phone-hijacked.json
serial_number equals the given serial and status is pending. If that row is not pending or missing, do nothing and report.status = pending and serial_number ≥ given serial; sort by serial_number; take the first min(batch size, count) rows. If batch size > available pending from that serial onward, effective batch = number of those pending rows.status = pending; take the first min(batch size, pending count) rows..cursor/skills/scamenger-story-writer/reference.md for section order, emotional goals, section definitions and prompts, and format rules (or docs/SCAM_STORIES_STRUCTURE_for_Writer.md in the repo).StoryContent interface and frontend/src/data/scam-stories-content/ for one-file-per-story examples (e.g. pump-and-dump-fake-guru-investment-group.ts, lpg-payment-pending-link-phone-hijacked.ts).slug, ensure entry exists in scam-stories.ts, then add full content as a new file scam-stories-content/{slug}.ts and register it in scam-stories-content/index.ts (or, for cloud: write output to the file named in story_file per docs/STORY_CLOUD_OUTPUT_FORMAT.md).For full section definitions, emotional goals, and copy-paste prompts, see .cursor/skills/scamenger-story-writer/reference.md.
**double asterisks** (emotions, red flags, turning points, takeaways).\u2029 between paragraphs (e.g. 'First paragraph.\u2029Second paragraph.'). Required for production (Vercel).\u2019 inside single-quoted strings where an apostrophe would otherwise end the string (e.g. didn\u2019t, I\u2019d).\u201c and \u201d for “ and ” when inside strings.**bold**. Site adds Report/Spot-and-avoid links; don't repeat in every bullet.| File | Action |
|---|---|
| CSV file | After successfully generating each story, set that row's status to done and save the CSV so the next run only processes remaining pending rows. |
| frontend/src/data/scam-stories.ts | For each story: ensure one entry in SCAM_STORY_ENTRIES: { slug, title, category }. Slug from CSV or derived from title. Category must be a valid ScamCategoryId. |
| frontend/src/data/scam-stories-content/ | For each story: add one file {slug}.ts exporting a default StoryContent object (all eight fields) and register it in index.ts. |
Editing the two data files above is the full integration. The site reads from them as follows:
/stories): Renders all entries from SCAM_STORY_ENTRIES. Each story card links to /stories/[slug]. Featured and “Latest” sections use the same list. No extra step to “link” a story to the index—adding the entry to SCAM_STORY_ENTRIES is enough./stories/[slug]): Uses the entry for title/category and getStoryContent(slug) from scam-stories-content/ for the body. Once content exists for that slug, the page shows the full story instead of a “coming soon” message.app/sitemap.ts and app/stories/feed/route.ts both iterate over SCAM_STORY_ENTRIES, so new stories are included in the sitemap and stories feed after the next build or request.So when you run “Process stories from docs/story-queue.csv …”, the skill combines story creation and website integration: generate content → write to the two data files → story is live on the index, linked, and on its own page (and in sitemap/feed). No separate integration or linking step is required.
online | phone | financial | impersonation | employment | housing | prizes_charity | identity_benefits | government | emerging | other
From title: lowercase, replace spaces and non-alphanumeric characters with single hyphens, trim hyphens from start/end. Example: "The guru and the pump" → the-guru-and-the-pump. Ensure uniqueness (if slug already exists in SCAM_STORY_ENTRIES, append a number or use the existing entry).
scam-stories.ts for this slug (if missing).scam-stories-content/{slug}.ts (and entry in index.ts) with default export = full StoryContent object, narrative and first-person with emotional touch.\u2029; apostrophes use \u2019 where needed in quoted strings.status in the CSV set to done and CSV file saved.serial_number.scam-stories.ts, add scam-stories-content/{slug}.ts and register in index.ts, then set row's status to done. This creates the story and integrates it with the website (index listing, index links, /stories/[slug] page, sitemap, RSS) in one run.See also: .cursor/skills/scamenger-story-writer/reference.md (section definitions, prompts, format rules, in-skill), docs/STORY_DEVELOPMENT_EXPERIENCE.md (user expectations and rationale), docs/STORY_CREATION_SKILL_GUIDE.md (CSV format and example), docs/STORY_CLOUD_OUTPUT_FORMAT.md (expected JSON output and integration when story content is produced by cloud code).