abdullah4ai/personal-shopper/SKILL.md
Personal Shopper — multi-agent product/service research and recommendation for Saudi Arabia. USE WHEN: - User asks to find, compare, recommend, or buy a product or service - "what's the best X", "compare X vs Y", "find me a good X" - "أبغى أشتري", "وش أفضل", "قارن لي", "ابحث لي عن" - User asks "is this a good deal" or "should I buy X or Y" - Product comparison by specs, price, or value DON'T USE WHEN: - Market analysis for business entry → use mckinsey-research - Comparing companies as businesses (not products) → use mckinsey-research - Price tracking over time or deal alerts → not supported - Reviewing/troubleshooting a product they already own → answer directly - Simple factual question about a product ("how much RAM does iPhone have") → answer directly - Order placement, returns, or refunds → not supported EDGE CASES: - "أبغى أشتري لابتوب" → this skill - "أبغى أفتح متجر لابتوبات" → mckinsey-research (business, not purchase) - "وش أفضل شاشة" → this skill - "وش حجم سوق الشاشات" → mckinsey-research - "هل السعر هذا حلو على أمازون" → this skill - "حلل لي سوق التجارة الإلكترونية" → mckinsey-research - "قارن لي بين منتجين" → this skill - "قارن لي بين شركتين" → mckinsey-research INPUTS: Product type or name, budget (optional), use case (optional), preferences (optional) TOOLS: sessions_spawn (sub-agents), web_fetch, web_search, camofox_* (with strict limits per agent) OUTPUT: HTML report saved to shopping-reports/{date}-{slug}.html (Arabic, RTL, mobile-friendly) SUCCESS: User gets 3 ranked options with verified prices, source URLs, coupons, and a clear recommendation
npx skillsauth add openclaw/skills جاك العلمInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
An agent orchestration skill. The main assistant acts as Router/Orchestrator, spawning sub-agents to research products or services, then scoring and rendering a final Arabic HTML report.
Reference files in
references/provide supplementary detail. If any reference file contradicts this file, follow SKILL.md.
[User Request]
|
[Router] ← main assistant, NOT a sub-agent
|
┌────┼──────────┐
│ │ │
Simple Standard Service
Scout A+K Finder
│ (parallel) │
│ │ │
│ Bargain Verifier
│ (sequential) │
└────┼──────────┘
|
[Court]
|
[Renderer → HTML Report]
The main assistant classifies every request. Do not spawn a sub-agent for routing.
{
"category": "electronics|grocery|medicine|clothing|furniture|services|automotive|toys",
"type": "product|service",
"complexity": "simple|standard|service",
"search_language": "both|ar_only",
"stores_tier1": ["..."],
"stores_tier2": ["..."],
"mainstream_brands": ["brand1", "brand2"],
"query_en": "English search query",
"query_ar": "استعلام بحث عربي"
}
| Path | Trigger | Agents | Token Budget | |------|---------|--------|-------------| | Simple | ANY 2 of: commodity item, est. price < 50 SAR, exact product specified, fungible | Scout → Court → Renderer | ~115K | | Standard | Meaningful product differentiation (electronics, furniture, clothing, appliances) | Advocate + Skeptic ‖ → Bargain Hunter → Court → Renderer | ~235K | | Service | Services (massage, salon, restaurant, repair, delivery) | Finder → Verifier → Court → Renderer | ~155K |
| Category | Language |
|----------|----------|
| Electronics, Clothing, Furniture | both (EN + AR queries) |
| Grocery, Medicine, Services | ar_only |
Router identifies the top 2-3 dominant brands in the category and passes them as mainstream_brands. These are banned for the Skeptic agent. Examples:
| Category | Stores | |----------|--------| | Electronics | amazon.sa, noon.com, jarir.com, extra.com | | Grocery | nana.sa, danube.com.sa, carrefourksa.com | | Medicine | nahdi.sa, al-dawaa.com | | Clothing | namshi.com, noon.com, 6thstreet.com | | Furniture | ikea.sa, homebox.sa, noon.com, homezmart.com | | Services | Google Maps, fresha.com | | General | noon.com, amazon.sa |
| Category | Stores | |----------|--------| | Electronics | aliexpress.com, ubuy.com.sa | | Furniture | pan-home.com, abyat.com | | General | haraj.com.sa, Facebook Marketplace |
| Store | Method | Notes |
|-------|--------|-------|
| amazon.sa | web_fetch ✅ | |
| noon.com | web_fetch ✅ | |
| jarir.com | camofox ⚠️ | JS-heavy |
| extra.com | web_fetch ✅ | |
| nana.sa | camofox ⚠️ | JS-heavy |
| danube.com.sa | camofox ⚠️ | JS-heavy |
| Google Maps | camofox ⚠️ | Or Google Local Pack via DDG |
| All others | web_fetch first, camofox fallback | |
This is the most critical section. Token overflow is the #1 cause of agent failure.
PRIMARY — DuckDuckGo Lite via web_fetch
web_fetch("https://lite.duckduckgo.com/lite/?q=YOUR+QUERY+HERE")
Returns ~5K tokens (titles + URLs + snippets). Then web_fetch on promising result URLs for details (~10K tokens each).
SECONDARY — Camoufox (fallback for JS-heavy sites only)
TERTIARY — web_search (Brave API, if available)
1. DDG Lite search (query_ar) → scan results → pick 3-5 URLs
2. DDG Lite search (query_en) → scan results → pick 3-5 URLs [if language=both]
3. web_fetch each promising URL → extract product name, price, specs
4. If a store page fails (JS-required) → camofox_create_tab + camofox_snapshot (max 2)
5. If web_search is available → use it for supplementary queries
Each agent is spawned as a sub-agent with a specific task prompt, input data, and output schema.
When: Simple path selected by Router.
Task prompt:
Find the top 3 options for a commodity product in Saudi Arabia (Riyadh). Focus on availability and price. Use DuckDuckGo Lite as primary search.
Input from Router:
{
"query_ar": "...",
"query_en": "...",
"search_language": "ar_only|both",
"stores_tier1": ["..."],
"category": "..."
}
Instructions:
query_ar (and query_en if search_language=both)web_fetch calls totalcamofox snapshot (only if critical store is JS-blocked)camofox_screenshot and save to shopping-reports/screenshots/{date}-{slug}.png. Include path in output.Output schema:
{
"candidates": [
{
"name": "Product Name",
"brand": "Brand",
"price_sar": 29.99,
"store": "noon.com",
"source_url": "https://...",
"price_from_page": true,
"screenshot_path": "shopping-reports/screenshots/2026-02-19-product-name.png",
"notes": "Free delivery, in stock"
}
],
"search_summary": "Searched 3 stores, found 5 listings, selected top 3 by price"
}
Token budget: 60K
When: Standard path. Runs in parallel with Skeptic.
Task prompt:
Find the BEST product in this category regardless of price. Prioritize quality, build, real user reviews, and long-term value. The goal is the best possible product for the user.
Input from Router:
{
"query_ar": "...",
"query_en": "...",
"search_language": "both",
"stores_tier1": ["..."],
"category": "..."
}
Instructions:
web_fetch calls, max 2 camofox snapshotscamofox_screenshot immediately and save to shopping-reports/screenshots/{date}-{brand-model-slug}.png. Create the folder if it doesn't exist. Include path in output.Output schema:
{
"candidates": [
{
"name": "Product Name",
"brand": "Brand",
"price_sar": 599,
"store": "amazon.sa",
"source_url": "https://...",
"price_from_page": true,
"screenshot_path": "shopping-reports/screenshots/2026-02-19-brand-model.png",
"quality_evidence": "4.6★ on 2,300 reviews, recommended by rtings.com",
"why_best": "Highest color accuracy in price range, 3-year warranty"
}
],
"search_summary": "..."
}
Token budget: 60K
When: Standard path. Runs in parallel with Advocate.
Task prompt:
Find alternatives the mainstream ignores. BANNED from recommending these brands: {mainstream_brands}. Find genuinely different products — not variations of popular ones. Check Tier 2 stores. Look for underdog brands with real quality.
Input from Router:
{
"query_ar": "...",
"query_en": "...",
"search_language": "both",
"stores_tier1": ["..."],
"stores_tier2": ["..."],
"mainstream_brands": ["Samsung", "LG"],
"category": "..."
}
Instructions:
mainstream_brandsweb_fetch calls, max 2 camofox snapshotscamofox_screenshot immediately and save to shopping-reports/screenshots/{date}-{brand-model-slug}.png. Include path in output.Output schema: Same as Advocate, plus:
{
"candidates": [
{
"name": "...",
"brand": "...",
"screenshot_path": "shopping-reports/screenshots/2026-02-19-brand-model.png",
"why_different": "Chinese brand with 90% of Samsung quality at 60% price, popular on r/monitors"
}
]
}
Token budget: 60K
When: Standard path. Runs AFTER Advocate and Skeptic complete.
Task prompt:
Given a list of products already researched, find the best LOCAL price for each, check for coupons/cashback/installments, and advise on timing. Do NOT search for new products.
Input: Combined candidate list from Advocate + Skeptic (deduplicated).
Instructions:
web_fetch calls (hard cap — plan carefully)camofox unless absolutely necessary (max 1)Output schema:
{
"price_checks": [
{
"candidate_name": "...",
"best_price_sar": 499,
"best_store": "noon.com",
"source_url": "https://...",
"price_from_page": true,
"coupon": "SAVE50 on almowafir.com (-50 SAR)",
"cashback": "Al Rajhi 5% on noon.com",
"installments": "Tamara 4x125 SAR",
"effective_price_sar": 424
}
],
"timing": {
"recommendation": "buy_now|wait|unclear",
"reason": "Ramadan sale expected in 3 weeks, historically 20-30% off electronics on noon",
"wait_until": "2026-03-10"
}
}
Token budget: 60K
When: Service path selected.
Task prompt:
Locate and rank local services in Riyadh, Saudi Arabia. Use Google Local Pack results via DuckDuckGo. Focus on: rating, review count, price range, location.
Input from Router:
{
"query_ar": "مساج رياض",
"category": "services",
"stores_tier1": ["Google Maps", "fresha.com"]
}
Instructions:
{query_ar} الرياض and {query_ar} site:fresha.comweb_fetch on top results for prices and detailsweb_fetch calls, max 2 camofox snapshotsOutput schema:
{
"candidates": [
{
"name": "Spa Name",
"rating": 4.7,
"review_count": 342,
"price_range": "200-400 SAR",
"address": "حي العليا، الرياض",
"source_url": "https://...",
"hours": "10AM-12AM",
"notes": "Highly rated for deep tissue"
}
]
}
Token budget: 60K
When: Service path. Runs after Finder.
Task prompt:
Given the Finder's top 2 service picks, verify they are real, open, and accurately described. Check reviews for authenticity, confirm prices, confirm operating hours.
Input: Finder's top 2 candidates.
Instructions:
web_fetch each candidate's source URL — confirm it loads, info matches"{service name}" review الرياض)web_fetch callsOutput schema:
{
"verifications": [
{
"candidate_name": "...",
"verified": true,
"price_confirmed": true,
"still_open": true,
"review_authenticity": "high|medium|low",
"red_flags": [],
"notes": "Reviews look genuine, mix of 3-5 stars, specific details mentioned"
}
]
}
Token budget: 40K
When: All paths, after research agents complete.
Task prompt:
Score all candidates using the weighted scoring framework. Do NO searching. Only judge based on data provided. Be strict. Apply all rules.
Input: All candidate data + Bargain Hunter/Verifier data (if applicable) + scoring weights for category.
Instructions:
web_fetch one source_url, confirm product/service existsCourt Rules:
source_url → score capped at 30 (effectively eliminated)price_from_page: false → Source Trust capped at 60; if estimated → capped at 40Output schema:
{
"rankings": [
{
"rank": 1,
"name": "...",
"brand": "...",
"score": 82,
"breakdown": {
"value": 25,
"quality": 22,
"availability": 9,
"source_trust": 13,
"deal_quality": 13
},
"source_url": "...",
"screenshot_path": "shopping-reports/screenshots/2026-02-19-brand-model.png",
"price_sar": 499,
"effective_price_sar": 424,
"verdict": "Best overall value with strong reviews and active coupon"
}
],
"spot_check": {
"url": "...",
"result": "pass|fail",
"notes": "Product page exists, price matches"
},
"fallback_needed": false,
"fallback_instruction": null
}
Token budget: 30K
When: All paths, after Court completes.
Task prompt:
Build an Arabic HTML report from the Court's output using the جاك العلم brand system. Output must be RTL, mobile-friendly (Telegram-width), visually polished.
Input: Court rankings + all metadata (timing, coupons, etc.)
⚠️ CRITICAL — Brand Files (READ BEFORE GENERATING):
references/brand-guideline.md — colors, typography, card design, brand voicereferences/html-template.md — the exact HTML template to useInstructions:
screenshot_path exists, read the file and base64-encode it. Embed as <img src="data:image/png;base64,{b64}"> inside the product card. If file missing or unreadable, skip gracefully (no broken image icon).shopping-reports/{date}-{query_slug}.htmlScreenshot embedding code (Python):
import base64, os
ALLOWED_DIR = os.path.abspath("shopping-reports/screenshots")
def embed_screenshot(path):
if not path:
return None
abs_path = os.path.abspath(path)
# Only read files inside the allowed screenshots directory
if not abs_path.startswith(ALLOWED_DIR):
return None
if not abs_path.endswith(".png"):
return None
if os.path.exists(abs_path) and os.path.getsize(abs_path) < 5_000_000:
with open(abs_path, 'rb') as f:
return base64.b64encode(f.read()).decode()
return None
Report Sections (in order):
| # | Section | Content |
|---|---------|---------|
| 1 | الغاية | What the user asked for |
| 2 | الطريقة | Which path was used, how many agents, stores checked — البلاسيبو: اعرض عدد المصادر + خطوات البحث |
| 3 | المصادر | List of stores/URLs consulted |
| 4 | العرض | 3 product/service cards — use card template from brand-guideline.md |
| 5 | رأي المحكمة | Court's verdict, scoring breakdown (collapsible <details>) |
| 6 | السعر | Price comparison table, effective prices after coupons |
| 7 | التوصيل | Delivery info per store |
| 8 | التوقيت | Timing recommendation (buy now / wait / unclear + reason) |
| 9 | التوصية | Final recommendation — one clear pick with reasoning, brand voice |
Design Rules (from references/brand-guideline.md):
#F8F7F4 (Canvas) — NOT #f5f5f5Token budget: 35K (includes reading brand-guideline.md + html-template.md)
Worked Example — Kill Doubt Text:
Good: "نفس شريحة M4 اللي في MacBook Pro بس بسعر أقل بـ 40%. الفرق الوحيد حجم الشاشة. لو شغلك مو على شاشة خارجية هذا الخيار الأذكى"
Bad: "نوصي بشدة بهذا المنتج الرائع الذي يتميز بمواصفات عالية الجودة"
The first kills doubt. The second is generic AI filler. Always write like the first.
| Criterion | Electronics | Grocery | Clothing | Furniture | Medicine | General | |-----------|------------|---------|----------|-----------|----------|---------| | Value (price/perf) | 30% | 40% | 25% | 30% | 40% | 30% | | Quality Signal | 25% | 15% | 20% | 25% | 20% | 20% | | Availability | 10% | 20% | 15% | 10% | 20% | 15% | | Source Trust | 15% | 15% | 15% | 15% | 15% | 15% | | Deal Quality | 20% | 10% | 25% | 20% | 5% | 20% |
| Criterion | Weight | |-----------|--------| | Rating | 30% | | Review Volume | 15% | | Price | 25% | | Location (Riyadh proximity) | 15% | | Verification | 15% |
Value (price/performance): How much you get per SAR. Cheapest ≠ best value — a 500 SAR item lasting 5 years beats a 200 SAR item lasting 1 year.
Quality Signal: Review scores (weighted by count), expert reviews, build materials, warranty length. Community evidence (Reddit, forums) > marketing specs.
Availability: In stock? Local delivery? Same-day/next-day? International-only → capped at 30.
Source Trust: Known store? Price verified on page? Secure checkout? source_url required or score capped at 30. price_from_page: false → capped at 40.
Deal Quality: Active coupons, cashback, installment options, bundle deals. Higher = more savings available right now.
When a store is unreachable or returns no results:
1. web_fetch fails → retry once with different URL pattern
2. Still fails → try camofox (if within budget)
3. camofox fails → mark store as "غير متاح" and move to next store
4. If ALL Tier 1 stores fail → switch to Tier 2 stores
5. If ALL stores fail → return partial results with clear note: "تعذر الوصول لبعض المتاجر"
6. Never hallucinate prices or availability from failed fetches
Court returns fallback_needed: true
→ Router reads fallback_instruction
→ Max 1 retry
→ Retry MUST change something:
- Different query terms
- Different stores (add Tier 2)
- Different language (try EN if was AR-only)
→ Re-run the same path with changes
→ If still < 2 results after retry:
- Generate "limited results" report
- Include manual search suggestions
- Be honest: "لم نجد خيارات كافية"
Every candidate in every path must include:
| Field | Required | Effect if Missing |
|-------|----------|-------------------|
| source_url | Yes | Score capped at 30 |
| price_from_page | Yes | If false → Source Trust capped at 40 |
| store | Yes | Used for delivery/trust assessment |
Court spot-check: The Court web_fetches 1 random source_url per run to confirm the product/service exists and price is approximately correct.
1. User: "أبي شاشة كمبيوتر 27 بوصة للتصميم"
2. Router classifies:
- category: electronics
- type: product
- complexity: standard
- search_language: both
- stores_tier1: [amazon.sa, noon.com, jarir.com, extra.com]
- stores_tier2: [aliexpress.com, ubuy.com.sa]
- mainstream_brands: [Samsung, LG]
- query_en: "27 inch monitor for design color accurate"
- query_ar: "شاشة 27 بوصة للتصميم دقة ألوان"
3. Router spawns Advocate + Skeptic IN PARALLEL:
- Advocate gets: query, language=both, tier1 stores
- Skeptic gets: query, language=both, tier1+tier2 stores, banned=[Samsung, LG]
4. Both complete → Router collects results → deduplicates
5. Router spawns Bargain Hunter SEQUENTIALLY:
- Input: deduplicated candidate list from step 4
- Checks prices, coupons, timing
6. Bargain Hunter completes → Router spawns Court:
- Input: all candidates + bargain data + scoring weights for electronics
7. Court scores, ranks, spot-checks → output top 3
8. Router spawns Renderer:
- Input: Court output + all metadata
- Generates HTML report → saves to shopping-reports/
9. Router sends report to user
1. User: "أبي بطاريات AA"
2. Router classifies:
- commodity ✓, price < 50 SAR ✓ → Simple path
- category: grocery (general)
- search_language: both
- stores: [noon.com, amazon.sa, nana.sa]
3. Router spawns Scout only → finds 3 options
4. Router spawns Court → scores
5. Router spawns Renderer → HTML report
1. User: "أبي مساج في الرياض"
2. Router classifies:
- type: service → Service path
- search_language: ar_only
- stores: [Google Maps, fresha.com]
3. Router spawns Finder → finds 5 services
4. Router spawns Verifier → verifies top 2
5. Router spawns Court → scores (service weights)
6. Router spawns Renderer → HTML report
Use the platform's sub-agent mechanism. Each agent gets:
shopping-{agent_name} (e.g., shopping-advocate)web_fetch, web_search, camofox_* (with limits stated per agent)Advocate and Skeptic can run simultaneously. Spawn both, wait for both to complete before spawning Bargain Hunter.
Simple: Scout → Court → Renderer
Standard: [Advocate ‖ Skeptic] → Bargain Hunter → Court → Renderer
Service: Finder → Verifier → Court → Renderer
Standard path runs 5+ sequential agent steps and can exceed 200K tokens. Design for continuity:
previous_response_id when continuing multi-step orchestration in the same thread.null and continue with available data.shopping-reports/ directory.shopping-reports/{date}-{query_slug}.htmlshopping-reports/screenshots/{date}-{brand-model}.pngshopping-reports/ directory (reports and screenshots)references/ within this skill, and shopping-reports/screenshots/*.png for base64 embeddingThese are hard-won. Violating any of these will produce bad results.
| Don't | Why | Do Instead |
|-------|-----|------------|
| Don't tell Skeptic to "look for alternatives" | Produces the same mainstream products with different wording | Ban specific brands: mainstream_brands: ["Samsung", "LG"] |
| Don't use Camoufox for search result pages | 50K tokens per snapshot, overflows context | Use DDG Lite (~5K tokens) for search. Camofox only for specific product pages |
| Don't pass raw HTML to Court | Court crashes or hallucinates from unstructured data | Always pass structured JSON summaries from research agents |
| Don't spawn Bargain Hunter before researchers finish | Missing candidate data causes empty price checks | Enforce sequential: Advocate+Skeptic complete → then Bargain Hunter |
| Don't add mainstream_brands after Skeptic starts searching | Bans are ineffective retroactively | Router must pass brands in the initial spawn payload |
| Don't assume web_search is available | Brave API key may be missing | DDG Lite is the guaranteed fallback. Always try it first |
| Don't skip timing advice | Users overpay by 30-40% buying before sales | Bargain Hunter always checks: Ramadan, White Friday, 11.11, back-to-school |
| Don't trust marketing specs over community reviews | Specs lie. Real users don't | Agents prioritize Reddit, forums, real-user reviews over product page claims |
| Don't use Standard path for batteries or USB cables | Wastes ~120K tokens on commodity items | Use Simple path when ANY 2 of: commodity, <50 SAR, exact product specified, fungible |
| Don't use Advocate+Skeptic for services | Services need location, ratings, hours — not specs and builds | Use Finder+Verifier path for services |
| Don't skip screenshots when using Camofox | Screenshots are free (0 tokens) and make reports trustworthy | Always camofox_screenshot right after opening a product page |
| Component | Simple | Standard | Service | |-----------|--------|----------|---------| | Router | 5K | 5K | 5K | | Scout | 60K | — | — | | Advocate | — | 60K | — | | Skeptic | — | 60K | — | | Bargain Hunter | — | 60K | — | | Finder | — | — | 60K | | Verifier | — | — | 40K | | Court | 30K | 30K | 30K | | Renderer | 35K | 35K | 35K | | Total | ~130K | ~250K | ~170K |
tools
Use when the user wants to connect to, test, or use the McDonalds service at mcp.mcd.cn, including checking authentication, probing MCP endpoints, listing tools, or calling McDonalds MCP tools through a reusable local CLI.
development
Web scraping platform — Twitter/X data, Vinted marketplace, and general web scraping API
development
SlowMist AI Agent Security Review — comprehensive security framework for skills, repositories, URLs, on-chain addresses, and products (Claude Code version)
data-ai
去除中文文本中的 AI 写作痕迹,使其读起来自然。基于维基百科 AI 写作特征指南,检测 24 种 AI 模式。触发词:humanizer-cn、去除 AI 痕迹、去除 AI 写作痕迹、中文文本人性化。