should-i-buy — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited should-i-buy (Agent Skill) and scored it 87/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 3 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
_On startup, use Read to load ~/.claude/skills/should-i-buy/preferences.md. If missing, treat as first-run (see First-time detection below)._
Defaults when no preferences exist:
output-root: ~/Desktop/should-i-buy/ (confirmed on first run)currency: USDbudget-style: value (value / premium / bargain — shapes the verdict weighting)tone: friendly-cli (terse, direct, warm — like a friend who actually knows the category)open-report: true (auto-open the HTML report when done)verdict-style: decisive (decisive / balanced — decisive means I pick one and say why; balanced lays out the trade-off)_Also load ~/.claude/skills/should-i-buy/feedback-journal.md if present — it contains thumbs-up/down on past verdicts. Summarize its signal (e.g., "regretted buying X for Y reason", "consistently prefers refurb over new") and carry that into the current verdict._
_On startup, use Bash to detect: today's date (date +%Y-%m-%d), and whether the output-root folder exists (ls or absence). Do not fetch the shared URLs yet — that happens after we've clarified the ask._
Check $ARGUMENTS:
help → show help, stopconfig → run config flow, stopreset → delete preferences + feedback journal, confirm, stopfeedback → collect thumbs-up/down on the most recent decision (see Feedback section), stophistory → list recent decision folders with titles and dates, stopsetup or preflight → run the Chrome extension setup/onboarding flow (see Setup section), stopshould-i-buy — Paste links, get a verdict with a 2026-aesthetic comparison report
Usage:
/should-i-buy <url> [more urls...] One or more product links
/should-i-buy [...] --for <context> Who/what this is for (e.g., "me, daily driver")
/should-i-buy [...] --budget <range> Budget constraint (e.g., "under $200")
/should-i-buy [...] --use <use-case> How you'll actually use it
/should-i-buy [...] --deadline <when> "by Friday", "this month" — affects wait-for-sale advice
/should-i-buy [...] --notes <text> Constraints, dealbreakers, leanings
/should-i-buy config Set preferences
/should-i-buy reset Clear preferences + feedback journal
/should-i-buy feedback Rate the last verdict (teaches the skill)
/should-i-buy history List past decision folders
/should-i-buy setup Walk through Chrome extension setup
/should-i-buy help This help
Examples:
/should-i-buy https://www.amazon.com/dp/B0XXXXXX https://www.rei.com/product/123
--for "me, weekend hiking" --budget "under $180"
/should-i-buy https://bestbuy.com/... --use "home office, 2 monitors" --notes "USB-C PD required"
/should-i-buy https://apple.com/shop/buy-mac/mac-mini --deadline "before WWDC"
Output:
{output-root}/{YYYY-MM-DD}-{kebab-title}/
├── report.html ← modern 2026 single-file report with verdict
├── data.json ← structured data (options, scores, verdict)
├── options/
│ ├── {slug-1}/
│ │ ├── hero.png ← product image
│ │ ├── page.png ← screenshot of listing (best-effort)
│ │ └── notes.md
│ └── ...
└── sources.md ← URLs visited + reasoning trail
Current preferences:
(loaded from preferences.md)Use AskUserQuestion to collect:
~/Desktop/should-i-buy/)Save to ~/.claude/skills/should-i-buy/preferences.md in the format:
# /should-i-buy preferences
Updated: {date}
## Defaults
- output-root: {path}
- currency: {USD|EUR|CAD|...}
- amazon-tld: {com|co.uk|ca|...}
- budget-style: {value|premium|bargain}
- verdict-style: {decisive|balanced}
- tone: {friendly-cli|detailed|minimal}
- dealbreakers: {free text}
## Profile (optional — edit freely)
- Favored brands:
- Avoided brands:
- Aesthetic: (minimal, maximalist, vintage, tech-forward, etc.)
- Sustainability: (important / nice-to-have / not a factor)
- Risk tolerance: (safe/proven only / will try new/indie)
- Return behavior: (rarely returns / returns if imperfect — affects how heavily return policy weighs)
- Past regrets: (free text — things you wish you hadn't bought and why)
## Learned
<!-- Patterns auto-appended as they emerge from feedback journal -->After saving, confirm with a warm one-liner: "Saved. I'll use this as the baseline — and I'll keep sharpening as you rate my verdicts."
Delete both ~/.claude/skills/should-i-buy/preferences.md and ~/.claude/skills/should-i-buy/feedback-journal.md. Confirm: "All cleared. I'll start from scratch on the next decision."
If no preferences file exists, show a warm onboarding (not a blocker):
First time running /should-i-buy — quick intro:
Paste me one or more product links and I'll help you decide. I open each
link in a real Chrome window you control, pull price / specs / reviews /
return policy, cross-check a few independent reviews, and write a single-file
HTML report with a clear verdict (buy / wait / pick X / skip).
I ask at most two sharp questions up front — your context and your
dealbreakers — then I get out of your way.
I get smarter over time. After each decision you can run
`/should-i-buy feedback` and tell me if I called it right. I save that and
factor it into future verdicts (past regrets are especially useful signal).
To browse the web, I need the Claude in Chrome extension. If you haven't
set it up yet, run: /should-i-buy setup
Otherwise, continue and I'll auto-check the connection.Then proceed to Step 0 (preflight). After the first successful decision, ask inline if they want to save any quick prefs (budget style, verdict style, dealbreakers) — don't force the full config flow.
When invoked as /should-i-buy setup (or when Step 0 preflight fails and the user asks for help), walk through the Chrome extension setup. Reference: the official docs at https://code.claude.com/docs/en/chrome.
Before we go:
1. Browser Google Chrome or Microsoft Edge
(Brave, Arc, other Chromium browsers: not yet supported)
Windows WSL: not supported
2. Plan A direct Anthropic plan — Pro, Max, Team, or Enterprise
(Free tier and third-party providers like Bedrock/Vertex
don't have Chrome integration)
3. Claude Code Version 2.0.73 or higher
Check: claude --version
4. Extension "Claude" by Anthropic, version 1.0.36 or higher
Install:
https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn
After install, pin it via the puzzle-piece icon.Use Bash to run claude --version and surface the result so the user knows where they stand.
Tell the user exactly what to type (they run these themselves — you can't run slash commands for them):
Next:
A. Inside Claude Code, type: /chrome
Select "Enable" — or "Enabled by default" to auto-enable every session.
B. To verify, type: /mcp
Look for "claude-in-chrome" in the list.
C. Site permissions are managed inside the Chrome extension itself
(click the extension icon → settings). Allow whichever sites you
actually shop on — common ones:
amazon.com, apple.com, bestbuy.com, rei.com, bhphotovideo.com,
target.com, walmart.com, costco.com, and any specialty retailer
your links point to.If the user reports trouble, walk through in this order (from the official docs):
| Symptom | Fix |
|---|---|
| "Extension not detected" | Open chrome://extensions, confirm it's installed and enabled. Update if version < 1.0.36. |
| "Browser extension is not connected" | Restart Chrome and Claude Code, then run /chrome → "Reconnect extension". |
| Works once, then dies after a pause | Extension service worker went idle. Run /chrome → "Reconnect extension". |
| "Receiving end does not exist" | Same as above — reconnect. |
| "No tab available" | Ask Claude to create a new tab, then retry. |
| First-time connection fails | Restart Chrome — the native messaging host config is picked up on Chrome startup. |
Once the user says they're set up, run the preflight (Step 0 below). If it passes, say:
Connection good. You're ready — paste your links:
/should-i-buy <url> [more urls...]Before anything else, verify the Claude-in-Chrome extension is connected. Without it, the decision can't run.
mcp__claude-in-chrome__tabs_context_mcp.Hmm — the Claude-in-Chrome extension isn't responding.
Common causes:
• Extension not installed → https://chromewebstore.google.com/detail/claude/fcoeoabgfenejglbffodgkkbkcdhcgfn
• Chrome integration not enabled in this session → run /chrome and select "Enable"
• Extension idle → run /chrome → "Reconnect extension"
• First time ever → restart Chrome once after enabling, then retry
Need the full walkthrough? Run: /should-i-buy setupThen stop. One retry allowed: if the user replies "retry" or "try again", call tabs_context_mcp once more. If it still fails, route them to /should-i-buy setup.
Extract from $ARGUMENTS:
http:// or https:// (dedupe, preserve order)--for <context> — who/what this is for--budget <range> — budget constraint--use <use-case> — concrete usage scenario--deadline <when> — urgency (affects wait-for-sale advice)--notes <text> — extra constraints or leaningsValidation gates (fail fast):
Fire one AskUserQuestion call with up to two questions. Skip any question that's already answered by flags. The goal is minimum interruption, maximum signal.
If the user has a feedback-journal with strong signal, mention it in one line before asking: e.g., "Your past regrets say you over-index on brand reputation — I'll weight that. Still want to answer:"
Show a crisp plan and wait for go (or a tweak):
Plan:
├── Options: {N} links ({domains summary})
├── What matters most: {answer}
├── Dealbreakers: {answer}
├── Scoring factors: {derived — 3-5, weighted per answers}
└── Verdict style: {decisive|balanced}
Reply 'go' to open the links, or tweak any of the above.This is the only hard gate. Keep it fast.
Generate a slug from the ask: {YYYY-MM-DD}-{kebab-summary-max-60chars}. Summary should capture the decision, not just the product, e.g.:
2026-04-19-standing-desk-under-500-rei-vs-amazon2026-04-19-macbook-air-m4-13-vs-152026-04-19-hiking-boots-weekend-usemkdir -p {output-root}/{slug}/optionsClear policy: only the per-decision folder is created fresh. Never delete sibling folders or anything outside {output-root}/{slug}/.
tabs_context_mcp to see current tabs — never reuse a prior session's tab IDs.tabs_create_mcp. Resize to 1440x900 on the first tab for consistent screenshots.javascript_tool (prefer structured JSON over get_page_text):javascript_tool, then curl -L -o {options}/{slug}/hero.png "<url>".javascript_tool with html2canvas dynamically loaded, or skip silently if it fails.Cross-source reviews (adds credibility, do for each finalist):
WebSearch for "<exact product name>" review — look for Wirecutter, Rtings, Consumer Reports, Reddit threads, reputable YouTubers.WebSearch for "<product>" price history or "<product>" sale — helps the wait-vs-buy-now call.Graceful degradation: if a page blocks extraction (common on some retailers), log the gap in sources.md and continue with partial data. Note the gap in the report so the verdict is honest about what's known.
Compute a composite score per option (0-100) using the weighted factors from Step 3. Then compose the verdict using the user's verdict-style:
Decisive style — pick one and say why in 2-3 sentences. Always name the runner-up and what would flip the call.
Balanced style — lay out the trade-off matrix (option A wins on X, option B wins on Y) and surface the decision criterion back to the user.
Special verdicts to consider:
Write data.json with the full structured data: options, specs, scores, verdict, reasoning, sources, query metadata.
Generate a single self-contained report.html (no external JS dependencies — inline everything). Aesthetic targets:
prefers-color-scheme — CSS variables only<script> for live filtering; NEVER split into multiple HTML files. The "open anywhere, no server" property mattersStructure:
~/.claude/skills/should-i-buy/icon.svg at ~32px next to the H1 with color: var(--accent) so it themes with light/dark mode. Title reflects the decision (e.g., "Standing desk under $500 — REI vs. Amazon"). Date + a muted timestamp.Priority: {value} — clickable, cycles through the Q1 options (or opens a small inline dropdown)Dealbreakers: {chip list} — each dealbreaker is a separate × removable chip; plus an inline "+ add" affordance to toggle others back onBudget style: {value} — clickable, cycles value / premium / bargainContext: {context} — display-only (can't usefully re-filter free-text)hero.png rendered as a large square (~280-320px on desktop, full-width on mobile), rounded corners, subtle border. This is the quick-identify surface.BUY THIS: {option} + 3-5 bullet reasonsPICK {option A} OVER {option B} + the single deciding factor + when-to-flip noteWAIT — {reason} + recommended trigger ("buy when it drops under $X")SKIP ALL — {reason} + one-line advice on what to search for instead.stale class to the verdict card: opacity: 0.55; filter: saturate(0.6).opacity: 0.4 rather than disappearing — the user still sees what's being filtered out and why./should-i-buy feedback.Inline JS responsibilities (keep it ~150 lines max, vanilla, no framework):
<script type="application/json" id="session"> payload embedded in the pageisStale = current !== original, toggle the .stale class and banner visibilityscoreOption(option, weights, dealbreakers) function in the JSON payload's _recompute hint, or inline it), re-sort the comparison table, re-dim filtered rowsReference ~/.claude/skills/should-i-buy/reference/report-template.html if it exists (load on demand; otherwise generate from scratch following the aesthetic above).
sources.md — every URL visited + one-line rationale per extraction decision.Verdict — {kebab decision}
{one-line verdict}
Top pick: {title} → ${price} (score {N}/100)
Runner-up: {title}
{optional third line — "Skip:" or "Wait until:"}
Folder: {output-root}/{slug}/
Report: {output-root}/{slug}/report.html
Open it? (y/N) — or rate the call with: /should-i-buy feedbackIf open-report: true, run open {output-root}/{slug}/report.html.
After opening the report, ask ONCE via AskUserQuestion (skip if the user has said "don't ask again" in the past — save that as a preference):
Save a copy of this report as a reference example in the skill's `examples/` folder? The next time you run/publish-skillsit'll be pushed to the public skills repo and linked from the README, so anyone browsing/should-i-buycan see what the output actually looks like.
Options: Yes / No, this one / Never ask / Edit first (opens the file so the user can scrub anything sensitive before saving).
On Yes:
{kebab-summary}.html (strip the date prefix — examples don't need chronology).{output-root}/{slug}/report.html → ~/.claude/skills/should-i-buy/examples/{filename}.html.~/.claude/skills/should-i-buy/examples/index.md doesn't exist, create it with a header; append a link entry: - [{decision title}]({filename}.html) — {one-line verdict summary}.On Edit first: run open -e {output-root}/{slug}/report.html so the user can hand-scrub before saving, then re-prompt.
On Never ask: save ask-save-example: never in preferences.md.
The examples/ folder is already picked up by /publish-skills (it copies examples/ recursively per skill), so no separate publish flow is needed.
End with a soft prompt (not a blocker):
When you've decided (or bought it and lived with it a week), run /should-i-buy feedback and tell me if I called it right. Honest signal here makes future verdicts sharper — especially if you regret something I approved.When invoked as /should-i-buy feedback:
{output-root}/.~/.claude/skills/should-i-buy/feedback-journal.md:## {decision slug} — {date}
- Verdict given: {what I recommended}
- User outcome: {nailed/close/missed/different/pending}
- Weight more: {factors}
- Regret / correction: {free text}
- Signal extracted: {one-line generalization, e.g., "over-weighted brand, under-weighted in-hand weight for mobile gear"}## Learned section of preferences.md. Mention the promotion: "Noticed {pattern} across recent decisions — saving that as a standing signal."The journal is human-editable. Respect whatever the user writes there directly.
{YYYY-MM-DD}-{kebab-summary} — 60 chars max in the summary half, frame around the decision not the product (e.g., standing-desk-under-500-rei-vs-amazon, not just standing-desk){kebab-product-short-name} — 40 chars max, derived from product title (not a counter); for Amazon items without a clean name, fall back to {brand}-{model}-2, -3 — if two options would collide, differentiate by brand or model numbertabs_context_mcp first; always create a new tab with tabs_create_mcp rather than reusing one from a prior session.javascript_tool returning clean JSON over dumping get_page_text. Smaller context, higher accuracy.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.