search-products▌
etsy.com/search-products-t1kplk · updated May 21, 2026
MDX-style export adds YAML metadata + attribution linking explainx.ai and this canonical listing URL.
Search Etsy for listings matching a query (free-form text, full search URL, listing-ID list, or shop URL) with the full filter surface — category, price range, item type, ship-to, color, sort, etc. — and return structured listing data (id, title, shop, price, original price, rating, badges, free-shipping, ad-flag, canonical URL) plus the fuzzy result count and active filter chips. Read-only.
| name | search-products |
| title | Etsy Product Search |
| description | >- Search Etsy for listings matching a query (free-form text, full search URL, listing-ID list, or shop URL) with the full filter surface — category, price range, item type, ship-to, color, sort, etc. — and return structured listing data (id, title, shop, price, original price, rating, badges, free-shipping, ad-flag, canonical URL) plus the fuzzy result count and active filter chips. Read-only. |
| website | etsy.com |
| category | marketplace |
| tags | - etsy - marketplace - search - listings - datadome - read-only |
| source | 'browserbase: agent-runtime 2026-05-18' |
| updated | '2026-05-18' |
| recommended_method | browser |
| alternative_methods | - method: api rationale: >- Etsy's Open API v3 (openapi.etsy.com) is reachable and would be dramatically more reliable than scraping — but it's partner-gated, requiring an approved app's 'keystring:shared_secret' OAuth credential. Verified iter-1: a key-less request returns the literal error "Invalid API key: should be in the format 'keystring:shared_secret'." Without partner credentials this path is unusable; the generic agent runtime falls back to the browser surface. - method: url-param rationale: >- Every filter Etsy's UI exposes is reflected as a URL query param (q, order, min, max, ship_to, explicit, free_shipping, price_bucket, on_sale, accepts_returns, ready_to_ship_in_1_day, is_personalizable, is_customizable, is_made_to_order, min_rating, attr_<facet>, page, plus locale prefixes /uk/, /de-en/, /ca/, /au/). Construct the URL directly rather than driving the filter UI — same canonical surface, fewer clicks, fewer DataDome-trigger opportunities. - method: hybrid rationale: >- For category-browse without a keyword (`/c/{slug}` paths), Browserbase's lightweight Fetch API returns 200 OK and the same listing-card HTML as a full browser session — DataDome doesn't gate static category landings. Use Fetch for category-only browse; promote to a verified browser session as soon as a keyword query (`?q=`), search path (`/search`), or listing-detail page (`/listing/{id}`) is needed. |
| verified | true |
| proxies | true |
Etsy Search Products
Purpose
Search Etsy for listings matching a free-form query (or full search URL, or shop URL, or listing-ID list) and return the matching items as structured JSON — listing ID, title, shop name + ID, primary + alternate image URLs, current price + original price + discount %, sale-end datetime, rating + review count, "Bestseller" / "Star Seller" / "Etsy's Pick" badges, free-shipping flag, shipping-from country, ready-to-ship-in-N-days indicator, returns-accepted flag, "X people have this in their cart" social-proof, item-type (Handmade / Vintage / Craft Supply / Digital), the canonical /listing/{id}/{slug} URL, ad/sponsored flag, plus the page-wide "X,XXX results, with Ads" fuzzy total and the active filter chips. Read-only — never clicks Add to Cart, Buy it Now, Favorite, Sign In, or any purchase-flow control.
When to Use
- A user pastes any of: an
etsy.com/search?q=...URL, a keyword query ("hand-poured soy candle"), a keyword + category ("earrings in Jewelry"), a list of listing IDs, or a/shop/{name}URL. - A user supplies a multi-facet filter combination (category + price range + color + ship-to + sort) and wants the top N results.
- Bulk monitoring of a saved-search across pages.
- Any flow that would otherwise scrape Etsy HTML and you want the canonical, anti-bot-aware playbook.
Workflow
Etsy is DataDome-protected (not Akamai, despite what some older notes claim — confirmed iter-1 by Server: DataDome + X-Datadome: protected + X-Dd-B: 259 on every blocked response). The site renders the listing grid server-side as HTML — there is no JSON-LD blob and no window.__INITIAL_STATE__ on the search page; listing data lives in data-listing-id-attributed <div class="v2-listing-card"> cards under <div data-search-results>. Therefore: drive a remote Browserbase session with --verified --proxies, navigate to the canonical search URL, then parse the rendered HTML.
A lightweight HTTP fetch (Browserbase cloud fetch API, raw curl, partner-less Open-API-v3) does not work for search — see Site-Specific Gotchas.
1. Build the URL
Start from https://www.etsy.com/search and append the filter surface as query params. All filters are URL-driven — no cookie / POST state required. Locale prefixes (/uk/, /de-en/, /ca/, /au/, ...) work identically: https://www.etsy.com/uk/search?q=....
| Filter | Param | Notes |
|---|---|---|
| Query | q=<URL-encoded text> | Free-form. |
| Sort | order=most_relevant|most_recent|highest_price|lowest_price|top_customer_reviews | Default most_relevant. |
| Custom price | min=<USD> + max=<USD> | Whole dollars; min= or max= alone is fine. |
| Bucketed price | price_bucket=1 (<$25), 2 ($25-$50), 3 ($50-$100), 4 ($100-$200), 5 (>$200) | Maps to the chip-style price filter. |
| Item type | explicit=1 (Handmade), 2 (Vintage), 4 (Craft Supplies), 8 (Digital) | Bit-field — sum for multi (e.g. explicit=9 = Handmade + Digital). |
| Ship to | ship_to=<ISO-3166-α2> | e.g. US, GB, DE. Drives the "Ships to your country" chip. |
| Free shipping | free_shipping=true | |
| Accepts returns | accepts_returns=true | |
| Ready in 1 day | ready_to_ship_in_1_day=true | |
| On sale | on_sale=true | |
| Accepts gift cards | accepts_gift_cards=true | |
| Personalizable | is_personalizable=true | |
| Customizable | is_customizable=true | |
| Made to order | is_made_to_order=true | |
| Min rating | min_rating=4 | Only "4+ stars" is exposed in the UI. |
| Dynamic facets | attr_<facet>=<value> (URL-encoded) | Color, material, occasion, recipient, holiday, room. The facet keys are surfaced dynamically per category in the left-rail filter HTML. Color values use Etsy's canonical names: Beige, Black, Blue, Bronze, Brown, Clear, Copper, Gold, Gray, Green, Orange, Pink, Purple, Rainbow, Red, Rose+Gold, Silver, White, Yellow. |
| Page | page=N | ~64 listings per page; Etsy caps pagination at 250 pages (~16,000 results). |
| Category scope | use /c/{category-slug} path with the same filter params | e.g. https://www.etsy.com/c/home-and-living/candles-and-holders/candles?q=soy&min=25. |
| Shop scope | https://www.etsy.com/shop/{shopname}?search_query=<text> | Scopes search to a single seller. |
For a listing-ID list input, skip search entirely and hit https://www.etsy.com/listing/{listingId} directly per ID.
For a full search URL input, use it verbatim — Etsy's URL params are stable and the canonical form is what you receive.
2. Create a verified + proxies session
DataDome is the wall. A bare session gets HTTP 403 + a DataDome CAPTCHA-delivery HTML stub. Verified mode (TLS-fingerprint + JS-challenge resolution) plus residential proxies (geo + IP-reputation diversity) is the minimum that produces a 200 in our testing.
SID=$(browse cloud sessions create --keep-alive --verified --proxies | jq -r .id)
export BROWSE_SESSION="$SID"
For non-US locales (/uk/, /de-en/, …) prefer a region-matched proxy: --region eu-central-1 for EU paths reduces the captcha rate.
3. Navigate and wait for the listing grid
browse open "https://www.etsy.com/search?q=hand-poured+soy+candle&order=most_recent" --remote
browse wait load --remote
browse wait selector --remote 'div[data-search-results]' # the grid container
browse wait timeout 1500 --remote # let lazy thumbnails settle
If browse get title --remote returns etsy.com (single-word) or browse get html body --remote contains Please enable JS and disable any ad blocker, DataDome blocked the load. Try once more with a fresh session; if still blocked, treat as the anti-bot wall.
4. Pull the HTML and parse listing cards
HTML=$(browse get html body --remote)
Each result is a <div class="v2-listing-card" data-listing-id="..." data-shop-id="..." data-page-type="search"> inside <div data-search-results>. Iterate per card and extract:
| Field | Selector / regex |
|---|---|
listing_id | [data-listing-id] (or [data-palette-listing-id]) |
shop_id | [data-shop-id] |
canonical_url | a.listing-link[href] — strip the tracking suffix: drop everything from ?click_key=… onward. Final form: https://www.etsy.com/listing/{id}/{slug}. |
title | a.listing-link[title] (also the <h3 class="v2-listing-card__title"> text) |
image_url | img[data-listing-card-listing-image][src]; srcset carries 1x / 2x variants |
rating_decimal | input[name="rating"][value] (e.g. "4.91") — there are two inputs (initial-rating + rating); they're identical |
rating_count | the (N,NNN) text node next to the star sprite |
star_seller | presence of .star-seller-badge-lavender-text-light / text "Star Seller" |
etsys_pick | text "Etsy's Pick" or search_collage-promotion-* class |
bestseller | text "Bestseller" |
is_ad | text "Ad by Etsy Seller" or "Ad by Etsy" — and &pro=1 appearing in the href querystring is a reliable secondary signal |
price_current | .n-listing-card__price .currency-symbol + .currency-value (formatted: combine; raw decimal: read currency-value) |
currency | .currency-symbol text ($, £, €, …) — Etsy localizes by IP/locale |
price_original | .wt-text-strikethrough .currency-value (present only on sale) |
discount_pct | derive: round((1 - current/original) * 100); Etsy may also render "XX% off" inline |
sale_label | wt-screen-reader-only text "Sale Price …" / "Original Price …" (accessible-only) |
free_shipping | text "FREE shipping" or "Free shipping" (class wt-text-slime) |
ready_to_ship | text "Ready to ship in N business day(s)" |
cart_social_proof | text "X people have this in their cart" (renders only when count > threshold) |
returns_accepted | text "Accepts returns and exchanges" (chip-conditional; not always rendered on card) |
shipping_from | text "From {Country}" / "Ships from {Country}" near footer of card |
item_type | derived from explicit= URL bit or the "Vintage" / "Craft Supply" / "Digital download" badge text |
5. Capture page-wide metadata
- Result count: the heading text matches
/^([0-9,]+)\s+results?(?:,\s+with Ads)?/near the top of<div data-search-results>. Etsy intentionally fuzzes large counts (e.g. "1,000,000+ results") — store the raw string as well as a parsed integer. - Active filter chips:
button[aria-pressed="true"]inside the filter pill bar, plus parse the URL params themselves. - Pagination:
a[rel="next"]href, or compute?page=N+1directly.nav[aria-label="Pagination"]exposes total pages. - Search context: read
data-primary-event-name(search_pagevscategory_pagevsshop_search) and thecategory_idJSON value embedded in the inline log script — useful to confirm which surface you landed on if a redirect happened.
6. Paginate
Increment &page=N. Each page reloads the full DOM; there is no client-side infinite-scroll API to call directly. Re-use the same session (don't recreate) — DataDome rate-limits new sessions harder than repeated nav inside a warm session.
7. Release the session
browse cloud sessions update "$SID" --status REQUEST_RELEASE
Site-Specific Gotchas
- DataDome, not Akamai. Etsy's anti-bot is DataDome (
Server: DataDome,X-Datadome: protected,X-Dd-B: 259on blocked responses). Don't waste time on Akamai-specific evasion. Both--proxies-on and--proxies-off via the Fetch API return 403 + a captcha-delivery HTML stub (<p>Please enable JS and disable any ad blocker</p>+ct.captcha-delivery.com/i.js). The X-Datadome-Riskscore was 0.76 (no proxy) vs 0.12 (with proxy) on the same query — proxies lower the score but don't bypass the block at the Fetch layer; a verified JS-executing browser session is required. - The lightweight Fetch API path is a dead end for
/search.browse cloud fetch https://www.etsy.com/search?q=...returns 403 with or without--proxies. Same for/listing/{id}detail pages. The only Etsy surfaces that return 200 via Fetch in our testing are/robots.txtand/c/<category-slug>category-browse pages (no?q=). For listing-ID lookups and search, you must use a verified browser session. /search?q=is explicitly disallowed inrobots.txt. Specifically:Disallow: /search?*q=,Disallow: /search/?*q=,Disallow: /search/*?*q=,Disallow: /search/*/?*q=. Many filter-bearing variants are also disallowed:attr_*=,price_bucket=,ship_to=,search_type=,*?order=*,*min=*,*max=*. Use the canonical web surface; honor rate limits; do not run bulk-scrape patterns from a single session.- No JSON-LD / no
window.__INITIAL_STATE__on search pages. Despite some scraping-tutorial claims, the Etsy search page renders listing data as plain server-rendered HTML inside<div data-search-results>with<div class="v2-listing-card">children. There is no consolidated JSON blob to parse — extract per-card attributes from the DOM. (Etsy's internal Apollo / config blob is present but contains site chrome + translations, not listing payload.) - Canonical URLs come with tracking junk.
a.listing-link[href]ishttps://www.etsy.com/listing/{id}/{slug}?click_key=…&click_sum=…&ls=a&ga_order=…&ga_search_type=…&ga_view_type=…&ga_search_query=…&ref=search_grid-XXX-X-X&pro=…&frs=…&sts=…. Always strip from?onward when emitting. Thepro,frs,stsflags in the original URL are useful intermediate signals:pro=1⇒ sponsored placement,frs=1⇒ free-shipping promo,sts=1⇒ Star Seller. Confirm against the visible badge text — do not rely on URL flags alone. - Ad / sponsored cards interleave with organic results. Etsy injects ~1 sponsored placement per 4 cards. Detect via text "Ad by Etsy Seller" / "Ad by Etsy" near the card title, and/or
pro=1in thehref. The fuzzy "X results, with Ads" count includes them. Flagis_ad: truein the output so downstream callers can filter. - The "X results, with Ads" count is intentionally fuzzed for large result sets. Beyond ~1,000 hits Etsy displays "1,000,000+ results" / "100,000+ results" instead of an exact number. Store both the raw display string and the best-effort parsed integer.
- Pagination caps at 250 pages. Even when the result count is in the millions,
page=251returns the page-1 results or an empty grid. The effective ceiling is ~16,000 listings per query. To go deeper, partition the query by category, price bucket, orexplicit=item type and union the results. explicit=is a bit-field, not an enum.1=Handmade,2=Vintage,4=Craft Supplies,8=Digital downloads. Combinations sum:explicit=9= Handmade + Digital,explicit=15= all four. The default (noexplicit=) returns Handmade + Vintage + Craft Supply mixed.- Vintage means ≥ 20 years old. Etsy enforces this at listing time; the filter is reliable. Item-type badge wording on cards is "Vintage", not the year.
ship_to=controls the "Ships to your country" chip and influences which sellers surface — Etsy weights inventory that the seller has tagged as shippable to that ISO-2. Withoutship_to=, Etsy uses IP-geo to pick a default; use an explicitship_to=to make results reproducible across proxies. The currency symbol on cards also followsship_to=.- The currency symbol is locale-dependent. A US-IP session sees
$; a UK locale (/uk/search) sees£; an EU locale sees€. The.currency-valueis the raw decimal in the displayed currency, not USD. Read.currency-symbolto disambiguate; do not assume USD. - Star-Seller badge is per-shop, not per-listing. A listing's Star Seller flag reflects the shop's current status — it may flip across queries. Don't cache.
- "Bestseller" is per-listing, surfaced by Etsy when the listing is in the top-1% of its category by recent sales. Etsy may revoke it without notice.
- Etsy's Pick is editorial. Shows up as an explicit badge label.
- Listing-detail page is also DataDome-blocked from raw Fetch (verified iter-1:
/listing/1234567890returns 403 with the same DataDome stub). Use the warm browser session you opened for search to fan out to listing details when more fields are needed (description, full image gallery, variant matrix). - Etsy Open API v3 is partner-gated.
openapi.etsy.com/v3/application/listings/activeis reachable and responds, but only with an approved app'skeystring:shared_secretOAuth credential pair —"Invalid API key: should be in the format 'keystring:shared_secret'."is the literal response with an empty key. Do not advertise the Open API as a fallback to end-users without a credential. If you happen to have partner credentials, that path is dramatically more reliable than scraping and should be preferred — but it's out of reach for the generic agent runtime, so this skill leads with the browser path. - CAPTCHA appears mid-session sporadically. If a navigation lands on the DataDome challenge page (body text "Please enable JS …"), don't retry the same URL in a tight loop — back off, re-create the session, and slow inter-request cadence below 1 req/s.
- Category-browse pages (
/c/{slug}) are NOT DataDome-walled for static category landings without a?q=query (verified iter-1:/c/jewelry?ref=catnav-10855returns 200 OK, 1.03 MB HTML, 64 unique listing cards via Fetch even with--proxies). The renderer is identical (search2_neu), so this is a viable lightweight Fetch fallback for category-only browsing. Adding any of?q=,?min=…&max=…, or other filter params can flip the response to 403 / 404 / DataDome; treat the category-page Fetch path as best-effort for category-only requests, not for keyword queries. - No
application/ld+jsonProductblocks on the search page. (Listing-detail pages do carry product LD-JSON, but you'll need a browser session to reach them.) - Embedded
category_idis per-page-load. The inline log script carries"category_id":<int>"— useful when you arrive via/c/{slug}and want the numeric ID for cross-referencing. Note that the slugged URL is canonical for end-users; the numeric ID is internal.
Expected Output
{
"query": "hand-poured soy candle",
"url": "https://www.etsy.com/search?q=hand-poured+soy+candle&order=most_recent",
"search_context": "search_page",
"result_count_display": "26,000+ results, with Ads",
"result_count_estimate": 26000,
"result_count_is_fuzzy": true,
"page": 1,
"page_size": 64,
"active_filters": {
"q": "hand-poured soy candle",
"order": "most_recent"
},
"currency": "USD",
"listings": [
{
"listing_id": "1030725081",
"shop_id": "24569729",
"shop_name": "ExampleShop",
"shop_location": "California, United States",
"url": "https://www.etsy.com/listing/1030725081/oval-cut-natural-yellow-sapphire-stud",
"title": "Oval Cut Natural Yellow Sapphire Stud Earrings 14K White Gold Diamond Earrings",
"image_url": "https://i.etsystatic.com/24569729/c/597/474/94/137/il/ec19d2/3125518692/il_340x270.3125518692_2ga7.jpg",
"image_urls_2x": "https://i.etsystatic.com/24569729/c/597/474/94/137/il/ec19d2/3125518692/il_680x540.3125518692_2ga7.jpg",
"price_current_formatted": "$700.50",
"price_current_raw": 700.50,
"price_original_formatted": "$934.00",
"price_original_raw": 934.00,
"discount_pct": 25,
"currency_symbol": "$",
"rating_decimal": 4.91,
"rating_count": 3442,
"badges": ["Star Seller"],
"is_ad": false,
"free_shipping": true,
"ready_to_ship_days": null,
"shipping_from_country": "United States",
"returns_accepted": null,
"cart_social_proof": null,
"sale_end_at": null,
"item_type": "Handmade",
"is_personalizable": false,
"is_customizable": false,
"is_made_to_order": false,
"variant_indicators": []
}
],
"pagination": {
"current_page": 1,
"has_next_page": true,
"next_page_url": "https://www.etsy.com/search?q=hand-poured+soy+candle&order=most_recent&page=2",
"max_page_observed": 250
}
}
Listing-ID-list input — output is the same shape with query: null, active_filters: {}, and listings[] populated by direct /listing/{id} fetches.
Shop-scoped input — search_context: "shop_search", plus "shop": {"name": "...", "shop_id": "..."} at the top level; listings[] shape unchanged.
Anti-bot wall encountered — emit:
{
"success": false,
"reason": "anti_bot_wall",
"wall": "datadome",
"url_attempted": "...",
"evidence": "Server: DataDome · X-Datadome: protected · 403"
}
How to use search-products on Cursor
AI-first code editor with Composer
Prerequisites
Before installing skills in Cursor, ensure your development environment meets these requirements:
- ›Cursor installed and configured on your development machine
- ›Node.js version 16.0+ with npm package manager (verify with
node --version) - ›Active project directory or workspace where you want to add search-products
Execute installation command
Execute the skills CLI command in your project's root directory to begin installation:
The skills CLI fetches search-products from GitHub repository etsy.com/search-products-t1kplk and configures it for Cursor.
Select Cursor when prompted
The CLI will show a list of available agents. Use arrow keys to navigate and space to select Cursor:
Verify installation
Confirm successful installation by checking the skill directory location:
Reload or restart Cursor to activate search-products. Access the skill through slash commands (e.g., /search-products) or your agent's skill management interface.
Security & Verification Notice
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your development environment. Always verify the publisher's identity, review recent commits, and test in isolated environments before production deployment.
List & Monetize Your Skill
Submit your Claude Code skill and start earning
Use Cases▌
Task Automation & Efficiency
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Knowledge Enhancement
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Quality Improvement
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
Implementation Guide▌
Prerequisites
- ›Claude Desktop or compatible AI client with skill support
- ›Clear understanding of task or problem to solve
- ›Willingness to iterate and refine outputs
Time Estimate
15-45 minutes depending on use case complexity
Installation Steps
- 1.Install skill using provided installation command
- 2.Test with simple use case relevant to your work
- 3.Evaluate output quality and relevance
- 4.Iterate on prompts to improve results
- 5.Integrate into regular workflow if valuable
Common Pitfalls
- ⚠Expecting perfect results without iteration
- ⚠Not providing enough context in prompts
- ⚠Using skill for tasks outside its intended scope
- ⚠Accepting outputs without review and validation
Best Practices▌
✓ Do
- +Start with clear, specific prompts
- +Provide relevant context and constraints
- +Review and refine all outputs before using
- +Iterate to improve output quality
- +Document successful prompt patterns
✗ Don't
- −Don't use without understanding skill limitations
- −Don't skip validation of outputs
- −Don't share sensitive information in prompts
- −Don't expect skill to replace human judgment
💡 Pro Tips
- ★Be specific about desired format and style
- ★Ask for multiple options to choose from
- ★Request explanations to understand reasoning
- ★Combine AI efficiency with human expertise
When to Use This▌
✓ Use When
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid When
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
Learning Path▌
- 1Familiarize yourself with skill capabilities and limitations
- 2Start with low-risk, non-critical tasks
- 3Progress to more complex and valuable use cases
- 4Build expertise through regular use and experimentation
Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.5★★★★★45 reviews- ★★★★★Chinedu Gill· Dec 28, 2024
Keeps context tight: search-products is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Neel Malhotra· Dec 24, 2024
Registry listing for search-products matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Chaitanya Patil· Dec 8, 2024
search-products reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Neel Khanna· Dec 8, 2024
I recommend search-products for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Alexander Robinson· Dec 4, 2024
Solid pick for teams standardizing on skills: search-products is focused, and the summary matches what you get after install.
- ★★★★★Piyush G· Nov 27, 2024
I recommend search-products for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Aditi Diallo· Nov 27, 2024
search-products reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Hana Park· Nov 23, 2024
We added search-products from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
- ★★★★★Neel Srinivasan· Nov 15, 2024
Useful defaults in search-products — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Shikha Mishra· Oct 18, 2024
Useful defaults in search-products — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
showing 1-10 of 45