| 1 | # Original v3.0.0 First-Run NUX Wizard (reference capture) |
| 2 | |
| 3 | Captured verbatim from `SKILL.md` at git commit `0a9ff16` (v3.0.0, 2026-04-08), |
| 4 | the first-run setup wizard Matt built. Preserved here for provenance and as the |
| 5 | source for the restored modal NUX (see docs/plans/2026-06-22-001-feat-restore-nux-wizard-plan.md). |
| 6 | This is a historical snapshot - the live wizard in SKILL.md Step 0 uses the CURRENT |
| 7 | source inventory (Digg, youtube_comments, SC backups) and omits Threads/Pinterest. |
| 8 | |
| 9 | ```markdown |
| 10 | ## Step 0: First-Run Setup Wizard |
| 11 | |
| 12 | **CRITICAL: ALWAYS execute Step 0 BEFORE Step 1, even if the user provided a topic.** If the user typed `/last30days Mercer Island`, you MUST check for FIRST_RUN and present the wizard BEFORE running research. The topic "Mercer Island" is preserved — research runs immediately after the wizard completes. Do NOT skip the wizard because a topic was provided. The wizard takes 10 seconds and only runs once ever. |
| 13 | |
| 14 | To detect first run: check if `~/.config/last30days/.env` exists. If it does NOT exist, this is a first run. **Do NOT run any Bash commands or show any command output to detect this — just check the file existence silently.** If the file exists and contains `SETUP_COMPLETE=true`, skip this section **silently** and proceed to Step 1. **Do NOT say "Setup is complete" or any other status message — just move on.** The user doesn't need to be told setup is done every time they run the skill. |
| 15 | |
| 16 | **When first run is detected, detect your platform first:** |
| 17 | |
| 18 | **If you do NOT have WebSearch capability (OpenClaw, Codex, raw CLI):** Run the OpenClaw setup flow below. |
| 19 | **If you DO have WebSearch (Claude Code):** Run the standard setup flow below. |
| 20 | |
| 21 | --- |
| 22 | |
| 23 | ### OpenClaw / Non-WebSearch Setup Flow |
| 24 | |
| 25 | Run environment detection first: |
| 26 | ```bash |
| 27 | python3 "${SKILL_ROOT}/scripts/last30days.py" setup --openclaw |
| 28 | ``` |
| 29 | |
| 30 | Read the JSON output. It tells you what's already configured. Display a status summary: |
| 31 | |
| 32 | ``` |
| 33 | 👋 Welcome to /last30days! |
| 34 | |
| 35 | Detected: |
| 36 | {✅ or ❌} yt-dlp (YouTube search) |
| 37 | {✅ or ❌} X/Twitter ({method} configured) |
| 38 | {✅ or ❌} ScrapeCreators (TikTok, Instagram, Reddit backup) |
| 39 | {✅ or ❌} Web search ({backend} configured) |
| 40 | ``` |
| 41 | |
| 42 | Then for each missing item, offer setup in priority order: |
| 43 | |
| 44 | 1. **ScrapeCreators** (if not configured): "ScrapeCreators adds TikTok and Instagram search (plus a Reddit backup if public Reddit gets rate-limited). 10,000 free calls, no credit card. (No referrals, no kickbacks - we don't get a cut.)" |
| 45 | - Option A: "ScrapeCreators via GitHub (recommended)" -- Check if `gh` CLI was detected in the environment detection output above. If gh IS detected: description should say "Registers directly via GitHub CLI in ~2 seconds - no browser needed". Before running the command, display: "Registering via GitHub CLI..." If gh is NOT detected: description should say "Copies a one-time code to your clipboard and opens GitHub to authorize". Before running the command, display: "I'll copy a one-time code to your clipboard and open GitHub. When GitHub asks for a device code, just paste (Cmd+V / Ctrl+V)." Then run `python3 "${SKILL_ROOT}/scripts/last30days.py" setup --github`, parse JSON output. Tries PAT first (if `gh` is installed), falls back to device flow which copies a one-time code to your clipboard and opens your browser. If `status` is `success`, write `SCRAPECREATORS_API_KEY={api_key}` to .env. |
| 46 | - Option B: "I have a key" -- accept paste, write to .env |
| 47 | - Option C: "Skip for now" |
| 48 | |
| 49 | 2. **X/Twitter** (if not configured): "X search finds tweets and conversations. To unlock X: add FROM_BROWSER=auto (reads browser cookies, free), XAI_API_KEY (no browser access, api.x.ai), or AUTH_TOKEN+CT0 (manual cookies)." |
| 50 | - Option A: "I have an xAI API key" (recommended for servers -- persistent, no expiry). Write XAI_API_KEY to .env. |
| 51 | - Option B: "I have AUTH_TOKEN + CT0 from my browser" -- accept both, write to .env |
| 52 | - Option C: "Skip for now" |
| 53 | |
| 54 | 3. **YouTube** (if yt-dlp not found): "YouTube search needs yt-dlp. Run: `pip install yt-dlp`" |
| 55 | |
| 56 | 4. **Web search** (if no Brave/Exa/Serper key): "A web search key enables smarter results. Brave Search is free for 2,000 queries/month at brave.com/search/api" |
| 57 | |
| 58 | After setup, write `SETUP_COMPLETE=true` to .env and proceed to research. |
| 59 | |
| 60 | **Skip to "END OF FIRST-RUN WIZARD" below after completing the OpenClaw flow.** |
| 61 | |
| 62 | --- |
| 63 | |
| 64 | ### Claude Code Setup Flow (Standard) |
| 65 | |
| 66 | **You MUST follow these steps IN ORDER. Do NOT skip ahead to the topic picker or research. The sequence is: (1) welcome text -> (2) setup modal -> (3) run setup if chosen -> (4) optional ScrapeCreators modal -> (5) topic picker. You MUST start at step 1.** |
| 67 | |
| 68 | **Step 1: Display the following welcome text ONCE as a normal message (not blockquoted). Then IMMEDIATELY call AskUserQuestion - do NOT repeat any of the welcome text inside the AskUserQuestion call.** |
| 69 | |
| 70 | Welcome to /last30days! |
| 71 | |
| 72 | I research any topic across Reddit, X, YouTube, and other sources - synthesizing what people are actually saying right now. |
| 73 | |
| 74 | Auto setup gives you 5 core sources for free in 30 seconds: |
| 75 | - X/Twitter - reads your x.com browser cookies to authenticate (not saved to disk). Chrome on macOS will prompt for Keychain access. |
| 76 | - Reddit with comments - public JSON, no API key needed |
| 77 | - YouTube search + transcripts - installs yt-dlp (open source, 190K+ GitHub stars) |
| 78 | - Hacker News + Polymarket + GitHub (if `gh` CLI installed) - always on, zero config |
| 79 | |
| 80 | Want TikTok and Instagram too? ScrapeCreators adds those (10,000 free calls, scrapecreators.com). No kickbacks, no affiliation. |
| 81 | |
| 82 | **Then call AskUserQuestion with ONLY this question and these options - no additional text:** |
| 83 | |
| 84 | Question: "How would you like to set up?" |
| 85 | Options: |
| 86 | - "Auto setup (~30 seconds) - scans browser cookies for X + installs yt-dlp for YouTube" |
| 87 | - "Manual setup - show me what to configure" |
| 88 | - "Skip for now - Reddit (with comments), HN, Polymarket, GitHub (if gh installed), Web" |
| 89 | |
| 90 | **If the user picks 1 (Auto setup):** |
| 91 | |
| 92 | **Before running the setup command, get cookie consent:** |
| 93 | |
| 94 | Check if `BROWSER_CONSENT=true` already exists in `~/.config/last30days/.env`. If it does, skip the consent prompt and run setup directly. |
| 95 | |
| 96 | If `BROWSER_CONSENT=true` is NOT present, **call AskUserQuestion:** |
| 97 | Question: "Auto setup will scan your browser for x.com cookies to authenticate X search. Cookies are read live, not saved to disk. Chrome on macOS will prompt for Keychain access. OK to proceed?" |
| 98 | Options: |
| 99 | - "Yes, scan my cookies for X" - Run setup as normal. Append `BROWSER_CONSENT=true` to .env after setup completes. |
| 100 | - "Skip X, just set up YouTube" - Run setup with YouTube only (install yt-dlp). Do not scan cookies. |
| 101 | - "I have an xAI API key instead" - Ask them to paste it, write XAI_API_KEY to .env. Then install yt-dlp. |
| 102 | |
| 103 | Run the setup subcommand: |
| 104 | ```bash |
| 105 | cd {SKILL_DIR} && python3 scripts/last30days.py setup |
| 106 | ``` |
| 107 | Show the user the results (what cookies were found, whether yt-dlp was installed). |
| 108 | |
| 109 | **Then show the optional ScrapeCreators offer (plain text, then modal):** |
| 110 | |
| 111 | Want TikTok and Instagram too? ScrapeCreators adds those platforms - 10,000 free calls, no credit card. It also serves as a Reddit backup if public Reddit ever gets rate-limited. |
| 112 | |
| 113 | **Before showing the ScrapeCreators modal, check for `gh` CLI:** Run `which gh` via Bash silently. Store the result as gh_available (true if found, false if not). |
| 114 | |
| 115 | **Call AskUserQuestion:** |
| 116 | Question: "Want to add TikTok, Instagram, and Reddit backup via ScrapeCreators? (We don't get a cut.)" |
| 117 | Options: |
| 118 | - "ScrapeCreators via GitHub (fastest, recommended)" - If gh_available: description should say "Registers directly via GitHub CLI in ~2 seconds - no browser needed". If NOT gh_available: description should say "Copies a one-time code to your clipboard and opens GitHub to authorize". After the user selects this option: If gh_available, display "Registering via GitHub CLI..." before running the command. If NOT gh_available, display "I'll copy a one-time code to your clipboard and open GitHub. When GitHub asks for a device code, just paste (Cmd+V on Mac, Ctrl+V on Windows/Linux)." Then run `cd {SKILL_DIR} && python3 scripts/last30days.py setup --github` via Bash with a 5-minute timeout. This tries PAT auth first (if `gh` CLI is installed, zero browser needed), then falls back to GitHub device flow which copies a one-time code to your clipboard and opens GitHub in your browser. Parse the JSON stdout. If `status` is `success`, write `SCRAPECREATORS_API_KEY={api_key}` to `~/.config/last30days/.env`. If `method` is `pat`, show: "You're in! Registered via GitHub CLI - zero browser needed. 10,000 free calls. TikTok, Instagram, and Reddit backup are now active." If `method` is `device` and `clipboard_ok` is true, show: "You're in! (The authorization code was copied to your clipboard automatically.) 10,000 free calls. TikTok, Instagram, and Reddit backup are now active." If `method` is `device` and `clipboard_ok` is false, show: "You're in! 10,000 free calls. TikTok, Instagram, and Reddit backup are now active." If `status` is `timeout` or `error`, show: "GitHub auth didn't complete. No worries - you can sign up at scrapecreators.com instead or try again later." Then offer the web signup option. |
| 119 | - "Open scrapecreators.com (Google sign-in)" - run `open https://scrapecreators.com` via Bash to open in the user's browser. Then ask them to paste the API key they get. When they paste it, write SCRAPECREATORS_API_KEY={key} to ~/.config/last30days/.env |
| 120 | - "I have a key" - accept the key, write to .env |
| 121 | - "Skip for now" - proceed without ScrapeCreators |
| 122 | |
| 123 | **After SC key is saved (not if skipped), show the TikTok/Instagram opt-in:** |
| 124 | |
| 125 | Your ScrapeCreators key powers TikTok, Instagram, Threads, Pinterest, and YouTube comments. Want those on for every research run? (Each additional source uses a ScrapeCreators call per search.) |
| 126 | |
| 127 | **Call AskUserQuestion:** |
| 128 | Question: "Which ScrapeCreators sources do you want on?" |
| 129 | Options: |
| 130 | - "TikTok + Instagram (recommended)" - append `INCLUDE_SOURCES=tiktok,instagram` to ~/.config/last30days/.env. Confirm: "TikTok and Instagram are on, plus Reddit backup if public Reddit has issues. You can add threads, pinterest, youtube_comments to INCLUDE_SOURCES anytime." |
| 131 | - "Everything - TikTok, Instagram, Threads, Pinterest, YouTube comments" - append `INCLUDE_SOURCES=tiktok,instagram,threads,pinterest,youtube_comments` to ~/.config/last30days/.env. Confirm: "All ScrapeCreators sources are on." |
| 132 | - "Just the basics - let's run our first search" - don't write the flag. Confirm: "Got it. ScrapeCreators will serve as Reddit backup. You can add sources to INCLUDE_SOURCES in your .env anytime." |
| 133 | |
| 134 | **After TikTok/Instagram opt-in (or SC skip), show the first research topic modal:** |
| 135 | |
| 136 | **Call AskUserQuestion:** |
| 137 | Question: "What do you want to research first?" |
| 138 | Options: |
| 139 | - "Claude Code vs Codex" - tech comparison |
| 140 | - "Sam Altman" - person in the news |
| 141 | - "Warriors Basketball" - sports |
| 142 | - "AI Legal Prompting Techniques" - niche/professional |
| 143 | - "Type my own topic" |
| 144 | |
| 145 | If user picks an example, run research with that topic. If they pick "Type my own", ask them what they want to research. If the user originally provided a topic with the command (e.g., `/last30days Mercer Island`), skip this modal and use their topic directly. |
| 146 | |
| 147 | **END OF FIRST-RUN WIZARD. Everything above in Step 0 ONLY runs on first run. If SETUP_COMPLETE=true exists in .env, skip ALL of Step 0 — no welcome, no setup, no ScrapeCreators modal, no topic picker. Go directly to Step 1 (Parse User Intent). The topic picker is ONLY for first-time users who haven't run /last30days before.** |
| 148 | |
| 149 | **If the user picks 2 (Manual setup):** |
| 150 | Show them this guide (present as plain text, not blockquoted): |
| 151 | |
| 152 | The magic of /last30days is Reddit comments + X posts together - and both are free. Here's how to unlock each source. |
| 153 | |
| 154 | Add these to `~/.config/last30days/.env`: |
| 155 | |
| 156 | X/Twitter (pick one - this is the most important): |
| 157 | - `FROM_BROWSER=auto` - free. Reads your x.com login cookies at search time to authenticate. Cookies are read live each run, not saved to disk. Chrome on macOS will prompt for Keychain access the first time. Firefox and Safari don't. |
| 158 | - `XAI_API_KEY=xxx` - no browser access needed. Get a key at api.x.ai. Best for servers or if you don't want cookie scanning. |
| 159 | - `AUTH_TOKEN=xxx` + `CT0=xxx` - paste your X cookies manually (x.com -> F12 -> Application -> Cookies) |
| 160 | |
| 161 | Reddit (free, works out of the box): |
| 162 | - Public JSON gives you threads + top comments with upvote counts. No setup required. |
| 163 | - `SCRAPECREATORS_API_KEY=xxx` - optional backup source if public Reddit gets rate-limited. |
| 164 | - `OPENAI_API_KEY=xxx` - optional fallback if public Reddit search has trouble finding threads. |
| 165 | |
| 166 | YouTube (free, open source): |
| 167 | - Run `brew install yt-dlp` - free, open source, 190K+ GitHub stars. Enables YouTube search and transcripts. |
| 168 | |
| 169 | Bonus: TikTok, Instagram, Threads, Pinterest, YouTube comments (ScrapeCreators): |
| 170 | - `SCRAPECREATORS_API_KEY=xxx` - 10,000 free calls at scrapecreators.com. |
| 171 | - After adding your key, set `INCLUDE_SOURCES=tiktok,instagram` to turn on the most popular ones. Add threads, pinterest, youtube_comments for more. |
| 172 | |
| 173 | GitHub Issues/PRs (free, no key needed): |
| 174 | - If you have the `gh` CLI installed (`brew install gh`), GitHub search is automatic. No API key required. |
| 175 | |
| 176 | Perplexity Sonar Pro (AI-synthesized research via OpenRouter): |
| 177 | - `OPENROUTER_API_KEY=xxx` - adds AI-synthesized research with citations as an additive source alongside Reddit/X/YouTube. Returns structured narratives with specific dates, names, and numbers that social sources miss. ~$0.02/run. |
| 178 | - After adding your key, set `INCLUDE_SOURCES=perplexity` (or append to existing, e.g. `INCLUDE_SOURCES=tiktok,instagram,perplexity`). |
| 179 | - Use `--deep-research` flag for exhaustive 50+ citation reports (~$0.90/query) on topics that need serious investigation. |
| 180 | - Bonus: also powers the planning and reranking engine if you don't have a Gemini/OpenAI/xAI key. |
| 181 | |
| 182 | Other bonus sources (add anytime): |
| 183 | - `EXA_API_KEY=xxx` - semantic web search, 1K free/month (exa.ai) |
| 184 | - `BSKY_HANDLE=you.bsky.social` + `BSKY_APP_PASSWORD=xxx` - Bluesky (free app password) |
| 185 | - `BRAVE_API_KEY=xxx` - Brave web search |
| 186 | |
| 187 | Always add this last line: `SETUP_COMPLETE=true` |
| 188 | |
| 189 | **CRITICAL: NEVER overwrite an existing .env file.** Before writing ANY key to `~/.config/last30days/.env`: |
| 190 | 1. Check if the file exists: `test -f ~/.config/last30days/.env` |
| 191 | 2. If it exists, READ it first, then APPEND only missing keys using `>>` (double redirect) |
| 192 | 3. NEVER use `>` (single redirect) which destroys existing content |
| 193 | 4. If it doesn't exist, create it: `mkdir -p ~/.config/last30days && touch ~/.config/last30days/.env` |
| 194 | |
| 195 | **Then call AskUserQuestion:** |
| 196 | Question: "How do you want to add your keys?" |
| 197 | Options: |
| 198 | - "Open .env in my editor" - Creates the file with a commented template and opens it. You edit, save, and come back. |
| 199 | - "Paste keys here" - Paste your API keys and I'll write the file for you. |
| 200 | - "I'll do it myself" - I'll tell you the file path and you handle it. |
| 201 | |
| 202 | **If the user picks "Open .env in editor":** |
| 203 | Create `~/.config/last30days/.env` if it doesn't exist (check first!), pre-populated with this template: |
| 204 | ``` |
| 205 | ``` |
| 206 |