#98 by GitHub stars

browser-use/browser-harness

Let Claude Code, Codex or Cursor use your real Chrome, logged in as you. One prompt to set up. Open source, MIT.

History

Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.

View weekly changes

SKILL.md

Week of Nov 2, 2026 · +2 / −0 lines

Before Network or broad shell → After Network or broad shell

4ced8e0087d2 → 6e69c7fbe97e

+ 181 Cloud browsers ignore viewport and device emulation (`Emulation.setDeviceMetricsOverride`, touch, window bounds) unless started with `start_remote_daemon(name, allowResizing=True)`.
+ 182 

Compare on GitHub

Week of Oct 26, 2026 · Line counts unavailable

Before Not checked yet → After Network or broad shell

First observation → 4ced8e0087d2

No earlier version was observed for comparison.

Compare on GitHub

skills/browser-harness/SKILL.md

Week of Nov 2, 2026 · +0 / −0 lines

Before Network or broad shell → After Network or broad shell

4ced8e0087d2 → 6e69c7fbe97e

Compare on GitHub

Week of Oct 26, 2026 · Line counts unavailable

Before Not checked yet → After Network or broad shell

First observation → 4ced8e0087d2

No earlier version was observed for comparison.

Compare on GitHub

src/browser_harness/SKILL.md

Week of Nov 2, 2026 · +0 / −0 lines

Before Network or broad shell → After Network or broad shell

4ced8e0087d2 → 6e69c7fbe97e

Compare on GitHub

Week of Oct 26, 2026 · Line counts unavailable

Before Not checked yet → After Network or broad shell

First observation → 4ced8e0087d2

No earlier version was observed for comparison.

Compare on GitHub

View on GitHubAdd to my skills

Verified commit 6e69c7fbe97edded9934e3fb305d9af3536f941f

git clone --filter=blob:none --no-checkout https://github.com/browser-use/browser-harness.git .hotskills/browser-use-browser-harness && git -C .hotskills/browser-use-browser-harness checkout --detach 6e69c7fbe97edded9934e3fb305d9af3536f941f # Copy each selected skill directory from .hotskills/browser-use-browser-harness into .claude/skills/<skill-name>/
git clone --filter=blob:none --no-checkout https://github.com/browser-use/browser-harness.git .hotskills/browser-use-browser-harness && git -C .hotskills/browser-use-browser-harness checkout --detach 6e69c7fbe97edded9934e3fb305d9af3536f941f # Copy each selected skill directory from .hotskills/browser-use-browser-harness into .agents/skills/<skill-name>/
18.9kGitHub stars
135stars in 7 days
3skills in this repository
139commits in 30 days

Heat

7.2
  • Star growth, last 7 daysAhead of 79% of tracked repositories
  • Star growth, last 24 hoursAhead of 84% of tracked repositories
  • Rank movement, last 7 daysAhead of 80% of tracked repositories
  • Commits, last 30 daysAhead of 95% of tracked repositories
  • Accounts asking about it through MCP, last 7 daysNot available
  • Hot votes this weekAhead of 0% of tracked repositories

Heat never changes the order by stars, and sponsorship never touches it. How heat works

Stars over time

Aug 2, 2026Nov 6, 202618,899

Individual skills in this repository

How it works

browser-harness

When your agent uses it

Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those.

What it loads into context

Frontmatter

51 tokens

Always available to the agent

SKILL.md

3,322 tokens

When the skill is activated

Reference documents

739,099 tokens

Loaded on request

Token counts are estimates. Scripts run separately; they are not counted as reference context.

The playbook

  1. When Not to Use
  2. Usage
  3. Local Chrome
  4. Remote Browsers
  5. Page Workflow
  6. Recordings and Videos
  7. Interaction Skills
  8. Design Constraints
  9. Gotchas
  10. Domain Skills

Scripts executed separately

  • agent-workspace/agent_helpers.py
  • agent-workspace/domain-skills/browser-use-cloud/cleanup-zombies.py
  • agent-workspace/domain-skills/claude-ai/extract-share-transcript.py
  • browser-harness
  • src/mcp_server.py
  • tests/__init__.py
  • tests/conftest.py
  • tests/integration/__init__.py
  • tests/integration/test_js.py
  • tests/unit/__init__.py
  • tests/unit/test_admin.py
  • tests/unit/test_auth.py
  • tests/unit/test_brave_origin.py
  • tests/unit/test_daemon.py
  • tests/unit/test_helpers.py
  • tests/unit/test_ipc.py
  • tests/unit/test_macos.py
  • tests/unit/test_mcp_cli.py
  • tests/unit/test_mcp_server.py
  • tests/unit/test_recorder.py
  • tests/unit/test_run.py
  • tests/unit/test_skill.py
  • tests/unit/test_video_render.py

Files

  • .claude-plugin/marketplace.jsonasset750 bytes
  • .claude-plugin/plugin.jsonasset694 bytes
  • .env.exampleasset102 bytes
  • .github/ISSUE_TEMPLATE/bug-report.ymlasset1,468 bytes
  • .github/ISSUE_TEMPLATE/config.ymlasset395 bytes
  • .github/ISSUE_TEMPLATE/feature-request.ymlasset909 bytes
  • .github/VOUCHED.tdasset470 bytes
  • .github/workflows/release.ymlasset545 bytes
  • .gitignoreasset101 bytes
  • AGENTS.mddoc2,185 bytes
  • CONTRIBUTING.mddoc1,272 bytes
  • LICENSEasset1,068 bytes
  • README.mddoc8,867 bytes
  • SKILL.mdcore14,519 bytes
  • SKILL.mdcore14,519 bytes
  • agent-workspace/agent_helpers.pyruns243 bytes
  • agent-workspace/domain-skills/BOSS-zhipin/chat.mddoc12,942 bytes
  • agent-workspace/domain-skills/BOSS-zhipin/job-search.mddoc13,045 bytes
  • agent-workspace/domain-skills/BOSS-zhipin/navigation.mddoc2,650 bytes
  • agent-workspace/domain-skills/aa/checkout.mddoc10,076 bytes
  • agent-workspace/domain-skills/admin/microsoft-365.mddoc123 bytes
  • agent-workspace/domain-skills/agentlist/discovery.mddoc5,996 bytes
  • agent-workspace/domain-skills/agoda/scraping.mddoc34,654 bytes
  • agent-workspace/domain-skills/airbnb/monthly-search.mddoc3,140 bytes
  • agent-workspace/domain-skills/alaska/checkout.mddoc5,751 bytes
  • agent-workspace/domain-skills/aliexpress/scraping.mddoc44,619 bytes
  • agent-workspace/domain-skills/amazon/order-history.mddoc4,977 bytes
  • agent-workspace/domain-skills/amazon/product-search.mddoc8,703 bytes
  • agent-workspace/domain-skills/ap/namecheap.mddoc96 bytes
  • agent-workspace/domain-skills/apartments-com/scraping.mddoc27,001 bytes
  • agent-workspace/domain-skills/apollo/search-and-lists.mddoc4,641 bytes
  • agent-workspace/domain-skills/app/apollo.mddoc95 bytes
  • agent-workspace/domain-skills/app/smartlead.mddoc107 bytes
  • agent-workspace/domain-skills/apple-app-store/scraping.mddoc32,355 bytes
  • agent-workspace/domain-skills/archive-org/scraping.mddoc15,174 bytes
  • agent-workspace/domain-skills/articulate-rise/code-blocks.mddoc9,646 bytes
  • agent-workspace/domain-skills/arxiv-bulk/scraping.mddoc13,989 bytes
  • agent-workspace/domain-skills/arxiv/scraping.mddoc13,766 bytes
  • agent-workspace/domain-skills/atlas/overview.mddoc3,467 bytes
  • agent-workspace/domain-skills/bbb/scraping.mddoc25,063 bytes
  • agent-workspace/domain-skills/best-buy/scraping.mddoc41,992 bytes
  • agent-workspace/domain-skills/bigbang-hr/checkout.mddoc4,739 bytes
  • agent-workspace/domain-skills/bilbasen/search.mddoc4,235 bytes
  • agent-workspace/domain-skills/bilibili/navigation.mddoc11,330 bytes
  • agent-workspace/domain-skills/bluesky/scraping.mddoc35,756 bytes
  • agent-workspace/domain-skills/booking-com/scraping.mddoc22,283 bytes
  • agent-workspace/domain-skills/booking/frontier-checkout.mddoc128 bytes
  • agent-workspace/domain-skills/browser-use-cloud/cleanup-zombies.pyruns5,841 bytes
  • agent-workspace/domain-skills/browser-use-cloud/cloud.mddoc8,884 bytes
  • agent-workspace/domain-skills/capterra/scraping.mddoc18,700 bytes
  • agent-workspace/domain-skills/centilebrain/generate-estimates.mddoc5,218 bytes
  • agent-workspace/domain-skills/chess-com/scraping.mddoc25,391 bytes
  • agent-workspace/domain-skills/claude-ai/extract-share-transcript.pyruns2,814 bytes
  • agent-workspace/domain-skills/claude-ai/share-export.mddoc3,886 bytes
  • agent-workspace/domain-skills/claude/custom-connectors.mddoc2,061 bytes
  • agent-workspace/domain-skills/claude/skills.mddoc3,409 bytes
  • agent-workspace/domain-skills/clinicaltrials-gov/scraping.mddoc30,162 bytes
  • agent-workspace/domain-skills/coingecko/scraping.mddoc14,610 bytes
  • agent-workspace/domain-skills/coinmarketcap/scraping.mddoc16,916 bytes
  • agent-workspace/domain-skills/costco/scraping.mddoc25,432 bytes
  • agent-workspace/domain-skills/coursera/scraping.mddoc13,453 bytes
  • agent-workspace/domain-skills/craigslist/scraping.mddoc15,804 bytes
  • agent-workspace/domain-skills/crossref/scraping.mddoc23,847 bytes
  • agent-workspace/domain-skills/ctrip/hotels.mddoc10,296 bytes
  • agent-workspace/domain-skills/dashboard/stripe.mddoc112 bytes
  • agent-workspace/domain-skills/dev-to/scraping.mddoc13,439 bytes
  • agent-workspace/domain-skills/dexscreener/scraping.mddoc45,805 bytes
  • agent-workspace/domain-skills/dice/scraping.mddoc28,180 bytes
  • agent-workspace/domain-skills/discogs/scraping.mddoc24,385 bytes
  • agent-workspace/domain-skills/docs/google-sheets.mddoc124 bytes
  • agent-workspace/domain-skills/doordash/search-and-product-pages.mddoc7,572 bytes
  • agent-workspace/domain-skills/duckduckgo/scraping.mddoc15,857 bytes
  • agent-workspace/domain-skills/ebay/scraping.mddoc21,125 bytes
  • agent-workspace/domain-skills/espn/scraping.mddoc14,404 bytes
  • agent-workspace/domain-skills/etsy/scraping.mddoc18,940 bytes
  • agent-workspace/domain-skills/eventbrite/scraping.mddoc15,703 bytes
  • agent-workspace/domain-skills/expedia/api.mddoc3,298 bytes
  • agent-workspace/domain-skills/expedia/automation.mddoc5,084 bytes
  • agent-workspace/domain-skills/expedia/flights-search.mddoc10,356 bytes
  • agent-workspace/domain-skills/facebook/groups.mddoc10,089 bytes
  • agent-workspace/domain-skills/facebook/pages.mddoc13,754 bytes
  • agent-workspace/domain-skills/feishu/docx-scraping.mddoc4,887 bytes
  • agent-workspace/domain-skills/figma/comments.mddoc2,418 bytes
  • agent-workspace/domain-skills/finviz/scraping.mddoc21,415 bytes
  • agent-workspace/domain-skills/flighthub/flights-search.mddoc6,911 bytes
  • agent-workspace/domain-skills/flipkart/shopping.mddoc10,290 bytes
  • agent-workspace/domain-skills/flyfrontier/checkout.mddoc116 bytes
  • agent-workspace/domain-skills/framer/editor.mddoc6,841 bytes
  • agent-workspace/domain-skills/fred/scraping.mddoc19,679 bytes
  • agent-workspace/domain-skills/frontier/checkout.mddoc7,479 bytes
  • agent-workspace/domain-skills/furnishedfinder/search.mddoc4,509 bytes
  • agent-workspace/domain-skills/g2/scraping.mddoc22,513 bytes
  • agent-workspace/domain-skills/gemini/spark-skills.mddoc1,654 bytes
  • agent-workspace/domain-skills/genius/scraping.mddoc20,164 bytes
  • agent-workspace/domain-skills/github/repo-actions.mddoc3,508 bytes
  • agent-workspace/domain-skills/github/scraping.mddoc8,031 bytes
  • agent-workspace/domain-skills/glassdoor/scraping.mddoc20,069 bytes
  • agent-workspace/domain-skills/gmail/compose.mddoc5,586 bytes
  • agent-workspace/domain-skills/goodreads/scraping.mddoc19,783 bytes
  • agent-workspace/domain-skills/google-maps/scraping.mddoc21,894 bytes
  • agent-workspace/domain-skills/google-patents/scraping.mddoc27,972 bytes
  • agent-workspace/domain-skills/google-play/scraping.mddoc32,693 bytes
  • agent-workspace/domain-skills/google-sheets/writing-cells.mddoc2,761 bytes
  • agent-workspace/domain-skills/google-trends/scraping.mddoc21,520 bytes
  • agent-workspace/domain-skills/google/flights-multi-city.mddoc5,377 bytes
  • agent-workspace/domain-skills/gutenberg/scraping.mddoc16,280 bytes
  • agent-workspace/domain-skills/hackernews/scraping.mddoc8,669 bytes
  • agent-workspace/domain-skills/home-depot/scraping.mddoc43,604 bytes
  • agent-workspace/domain-skills/howlongtobeat/scraping.mddoc22,177 bytes
  • agent-workspace/domain-skills/hubspot/private-app-webhooks.mddoc6,123 bytes
  • agent-workspace/domain-skills/iherb/product-labels.mddoc2,840 bytes
  • agent-workspace/domain-skills/imdb/scraping.mddoc12,706 bytes
  • agent-workspace/domain-skills/itch-io/scraping.mddoc17,293 bytes
  • agent-workspace/domain-skills/jetblue/checkout.mddoc8,555 bytes
  • agent-workspace/domain-skills/job-boards/indeed-glassdoor.mddoc36,538 bytes
  • agent-workspace/domain-skills/kalshi/scraping.mddoc27,623 bytes
  • agent-workspace/domain-skills/letterboxd/scraping.mddoc15,039 bytes
  • agent-workspace/domain-skills/linkedin/invitation-manager.mddoc4,568 bytes
  • agent-workspace/domain-skills/loom/folder-enumeration.mddoc8,793 bytes
  • agent-workspace/domain-skills/loom/read-recording.mddoc4,688 bytes
  • agent-workspace/domain-skills/lulu/account-currency.mddoc1,926 bytes
  • agent-workspace/domain-skills/ly-com/hotels.mddoc10,500 bytes
  • agent-workspace/domain-skills/macrotrends/scraping.mddoc21,013 bytes
  • agent-workspace/domain-skills/manus/tasks.mddoc12,220 bytes
  • agent-workspace/domain-skills/medium/article-hydration.mddoc5,663 bytes
  • agent-workspace/domain-skills/medium/scraping.mddoc17,239 bytes
  • agent-workspace/domain-skills/mercari/scraping.mddoc25,679 bytes
  • agent-workspace/domain-skills/mermaid/render.mddoc2,965 bytes
  • agent-workspace/domain-skills/metacritic/scraping.mddoc20,734 bytes
  • agent-workspace/domain-skills/microsoft-365/domain-setup.mddoc1,765 bytes
  • agent-workspace/domain-skills/musicbrainz/scraping.mddoc19,581 bytes
  • agent-workspace/domain-skills/namecheap/advanced-dns.mddoc1,664 bytes
  • agent-workspace/domain-skills/nasa/scraping.mddoc15,105 bytes
  • agent-workspace/domain-skills/news-aggregation/multi-source.mddoc8,133 bytes
  • agent-workspace/domain-skills/nordic/product-labels.mddoc1,141 bytes
  • agent-workspace/domain-skills/ods/fact-sheets.mddoc1,762 bytes
  • agent-workspace/domain-skills/open-library/scraping.mddoc19,294 bytes
  • agent-workspace/domain-skills/openalex/scraping.mddoc18,250 bytes
  • agent-workspace/domain-skills/openstreetmap/scraping.mddoc20,955 bytes
  • agent-workspace/domain-skills/outlook/webmail-compose.mddoc2,110 bytes
  • agent-workspace/domain-skills/package-registries/npm-pypi.mddoc16,645 bytes
  • agent-workspace/domain-skills/partsouq/vin-lookup.mddoc1,654 bytes
  • agent-workspace/domain-skills/perplexity/computer.mddoc16,424 bytes
  • agent-workspace/domain-skills/polymarket/scraping.mddoc13,673 bytes
  • agent-workspace/domain-skills/poshmark/scraping.mddoc25,121 bytes
  • agent-workspace/domain-skills/producthunt/scraping.mddoc11,349 bytes
  • agent-workspace/domain-skills/pubmed/scraping.mddoc18,774 bytes
  • agent-workspace/domain-skills/qbo/report-export.mddoc5,786 bytes
  • agent-workspace/domain-skills/quora/scraping.mddoc16,564 bytes
  • agent-workspace/domain-skills/rawg/scraping.mddoc13,740 bytes
  • agent-workspace/domain-skills/realtor-com/scraping.mddoc30,754 bytes
  • agent-workspace/domain-skills/reddit/scraping.mddoc8,480 bytes
  • agent-workspace/domain-skills/redfin/scraping.mddoc33,903 bytes
  • agent-workspace/domain-skills/rest-countries/scraping.mddoc9,951 bytes
  • agent-workspace/domain-skills/rightmove/scraping.mddoc34,054 bytes
  • agent-workspace/domain-skills/rotten-tomatoes/scraping.mddoc35,789 bytes
  • agent-workspace/domain-skills/salesforce/.gitkeepasset0 bytes
  • agent-workspace/domain-skills/sec-edgar/scraping.mddoc15,988 bytes
  • agent-workspace/domain-skills/sephora/scraping.mddoc23,117 bytes
  • agent-workspace/domain-skills/shopify-admin/README.mddoc2,101 bytes
  • agent-workspace/domain-skills/shopify-admin/embedded-apps.mddoc2,607 bytes
  • agent-workspace/domain-skills/shopify-admin/forms-app.mddoc2,227 bytes
  • agent-workspace/domain-skills/shopify-admin/knowledge-base.mddoc4,258 bytes
  • agent-workspace/domain-skills/shopify-admin/polaris-inputs.mddoc5,379 bytes
  • agent-workspace/domain-skills/shopify-storefronts/scraping.mddoc25,154 bytes
  • agent-workspace/domain-skills/slack/files.mddoc3,410 bytes
  • agent-workspace/domain-skills/smartlead/mailbox-warmup.mddoc3,465 bytes
  • agent-workspace/domain-skills/sofascore/scraping.mddoc25,540 bytes
  • agent-workspace/domain-skills/soundcloud/scraping.mddoc14,202 bytes
  • agent-workspace/domain-skills/spotify/scraping.mddoc14,821 bytes
  • agent-workspace/domain-skills/spreadshirt/.gitkeepasset0 bytes
  • agent-workspace/domain-skills/stackoverflow/scraping.mddoc18,587 bytes
  • agent-workspace/domain-skills/steam/scraping.mddoc22,127 bytes
  • agent-workspace/domain-skills/stripe/account-sandboxes.mddoc1,797 bytes
  • agent-workspace/domain-skills/substack/scraping.mddoc12,204 bytes
  • agent-workspace/domain-skills/supabase/dashboard.mddoc2,684 bytes
  • agent-workspace/domain-skills/target/scraping.mddoc25,196 bytes
  • agent-workspace/domain-skills/tasksquad-ai/agents.mddoc3,035 bytes
  • agent-workspace/domain-skills/tasksquad-ai/auth.mddoc3,118 bytes
  • agent-workspace/domain-skills/tasksquad-ai/tasks.mddoc6,452 bytes
  • agent-workspace/domain-skills/tcgplayer/scraping.mddoc23,445 bytes
  • agent-workspace/domain-skills/thetechgeeks/pricing.mddoc2,615 bytes
  • agent-workspace/domain-skills/thorne/product-labels.mddoc1,580 bytes
  • agent-workspace/domain-skills/ticketmaster/scraping.mddoc22,874 bytes
  • agent-workspace/domain-skills/tiktok/upload.mddoc3,918 bytes
  • agent-workspace/domain-skills/tradingview/scraping.mddoc12,728 bytes
  • agent-workspace/domain-skills/trello/boards-and-lists.mddoc3,616 bytes
  • agent-workspace/domain-skills/tripadvisor/scraping.mddoc23,302 bytes
  • agent-workspace/domain-skills/trulia/scraping.mddoc26,054 bytes
  • agent-workspace/domain-skills/trustpilot/scraping.mddoc13,939 bytes
  • agent-workspace/domain-skills/twitch/scraping.mddoc42,469 bytes
  • agent-workspace/domain-skills/ulta/scraping.mddoc39,949 bytes
  • agent-workspace/domain-skills/upwork/scraping.mddoc19,341 bytes
  • agent-workspace/domain-skills/vercel/archive-and-audit.mddoc3,045 bytes
  • agent-workspace/domain-skills/vercel/observability.mddoc2,157 bytes
  • agent-workspace/domain-skills/vercel/vercel.mddoc7,497 bytes
  • agent-workspace/domain-skills/vinted/scraping.mddoc16,295 bytes
  • agent-workspace/domain-skills/walmart/scraping.mddoc18,974 bytes
  • agent-workspace/domain-skills/wayback-machine/scraping.mddoc10,863 bytes
  • agent-workspace/domain-skills/weather/scraping.mddoc16,925 bytes
  • agent-workspace/domain-skills/wehotel/hotels.mddoc10,273 bytes
  • agent-workspace/domain-skills/wellfound/scraping.mddoc21,318 bytes
  • agent-workspace/domain-skills/weread/read.mddoc9,066 bytes
  • agent-workspace/domain-skills/wikipedia/scraping.mddoc28,432 bytes
  • agent-workspace/domain-skills/world-bank/scraping.mddoc11,893 bytes
  • agent-workspace/domain-skills/x/article-source-recovery.mddoc2,019 bytes
  • agent-workspace/domain-skills/x/posting.mddoc2,796 bytes
  • agent-workspace/domain-skills/xiaohongshu/scraping.mddoc6,265 bytes
  • agent-workspace/domain-skills/yahoo-finance/scraping.mddoc18,419 bytes
  • agent-workspace/domain-skills/youtube/playback.mddoc4,305 bytes
  • agent-workspace/domain-skills/youtube/scraping.mddoc18,142 bytes
  • agent-workspace/domain-skills/zillow/scraping.mddoc21,268 bytes
  • agent-workspace/domain-skills/zoopla/scraping.mddoc26,188 bytes
  • browser-harnessruns939 bytes
  • docs/MCP.mddoc2,241 bytes
  • docs/allow-remote-debugging.pngasset192,627 bytes
  • docs/download-latest-20-x-videos.gifasset1,352,637 bytes
  • docs/setup-remote-debugging.pngasset50,720 bytes
  • docs/snap-linux-headless.mddoc2,061 bytes
  • install.mddoc4,054 bytes
  • interaction-skills/connection.mddoc1,979 bytes
  • interaction-skills/cookies.mddoc119 bytes
  • interaction-skills/cross-origin-iframes.mddoc165 bytes
  • interaction-skills/dialogs.mddoc2,328 bytes
  • interaction-skills/downloads.mddoc160 bytes
  • interaction-skills/drag-and-drop.mddoc168 bytes
  • interaction-skills/dropdowns.mddoc193 bytes
  • interaction-skills/iframes.mddoc168 bytes
  • interaction-skills/make-video.mddoc4,479 bytes
  • interaction-skills/network-requests.mddoc196 bytes
  • interaction-skills/print-as-pdf.mddoc171 bytes
  • interaction-skills/profile-sync.mddoc4,994 bytes
  • interaction-skills/screenshots.mddoc1,063 bytes
  • interaction-skills/scrolling.mddoc1,018 bytes
  • interaction-skills/shadow-dom.mddoc147 bytes
  • interaction-skills/tabs.mddoc2,488 bytes
  • interaction-skills/uploads.mddoc10 bytes
  • interaction-skills/viewport.mddoc529 bytes
  • pyproject.tomlasset1,525 bytes
  • src/mcp_server.pyruns8,500 bytes
  • tests/__init__.pyruns0 bytes
  • tests/conftest.pyruns293 bytes
  • tests/integration/__init__.pyruns0 bytes
  • tests/integration/test_js.pyruns6,443 bytes
  • tests/unit/__init__.pyruns0 bytes
  • tests/unit/test_admin.pyruns60,999 bytes
  • tests/unit/test_auth.pyruns1,072 bytes
  • tests/unit/test_brave_origin.pyruns2,647 bytes
  • tests/unit/test_daemon.pyruns32,144 bytes
  • tests/unit/test_helpers.pyruns28,367 bytes
  • tests/unit/test_ipc.pyruns5,232 bytes
  • tests/unit/test_macos.pyruns4,297 bytes
  • tests/unit/test_mcp_cli.pyruns604 bytes
  • tests/unit/test_mcp_server.pyruns1,104 bytes
  • tests/unit/test_recorder.pyruns3,345 bytes
  • tests/unit/test_run.pyruns14,128 bytes
  • tests/unit/test_skill.pyruns1,130 bytes
  • tests/unit/test_video_render.pyruns697 bytes
Read SKILL.md

# browser-harness

Direct browser control via CDP. For task-specific edits, use `agent-workspace/agent_helpers.py`. For setup, install, or connection problems, read https://github.com/browser-use/browser-harness/blob/main/install.md.

## When Not to Use

A basic fetch of public information needs no browser. If a plain HTTP request can read it — a public page, an API, docs — use `curl` or your fetch tool, and leave the browser alone. Use browser-harness when the task needs interaction (click, type, navigate), the user's logged-in session, JS rendering, or a bot-protected page. If a direct fetch fails or returns a shell page, then escalate to the browser.

Domain skills are off by default. Set `BH_DOMAIN_SKILLS=1` to enable them; see the bottom section.

**If `BH_DOMAIN_SKILLS=1` and the task is site-specific, read every file in the matching `$BH_AGENT_WORKSPACE/domain-skills/<site>/` directory before inventing an approach.**

## Usage
View the complete source on GitHub

Skills included

  • browser-harness
  • browser-harness
  • browser-harness

Repository facts

License
MIT
Created
Apr 17, 2026
Last pushed
Nov 6, 2026
Forks
1,865
Open issues
60
Project activity
Active

Rank over the last 12 weeks

Now #98 · best #90 · down 5 in 30 days

  1. #98 from Oct 28 to Oct 29
  2. #99 from Oct 30 to Oct 31
  3. #97 on Nov 1
  4. #98 on Nov 2
  5. #99 on Nov 3
  6. #98 since Nov 4
24 earlier periods
  1. #85 on Aug 2
  2. #89 on Aug 7
  3. #90 on Aug 8
  4. #89 on Aug 9
  5. #90 from Aug 10 to Aug 13
  6. #91 from Aug 14 to Aug 15
  7. #90 on Aug 16
  8. #91 from Aug 17 to Aug 21
  9. #90 on Aug 22
  10. #91 on Aug 23
  11. #90 from Aug 24 to Aug 25
  12. #91 from Aug 26 to Sep 17
  13. #92 on Sep 18
  14. #91 on Sep 19
  15. #92 from Sep 20 to Oct 3
  16. #93 from Oct 4 to Oct 5
  17. #92 on Oct 6
  18. #93 from Oct 7 to Oct 11
  19. #94 from Oct 12 to Oct 14
  20. #95 from Oct 15 to Oct 16
  21. #96 from Oct 17 to Oct 19
  22. #97 on Oct 20
  23. #98 from Oct 21 to Oct 24
  24. #99 on Oct 25

Before you install

Network or broad shell

Automated signals, not a guarantee

Checked Nov 3, 2026

Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.

Show 7 notes
  • SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • browser-harness:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • skills/browser-harness/SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • browser-harness:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • src/browser_harness/SKILL.md:1 Analysis incomplete: Referenced executable target unavailable; not analyzed
  • src/browser_harness/video-template.html:184 Analysis incomplete: physical or joined line exceeds character limit
  • src/browser_harness/video-template.html:183 Analysis incomplete: physical or joined line exceeds character limit
Show all 4,838 signals by file

.claude-plugin/marketplace.json

  • Network accessline 4
    "owner": {     "name": "Browser Use",     "url": "https://browser-use.com"
  • Network accessline 5
    "name": "Browser Use",     "url": "https://browser-use.com"   },
  • Network accessline 6
    "url": "https://browser-use.com"
  • Network accessline 12
    "category": "automation",       "source": ".",       "homepage": "https://github.com/browser-use/browser-harness",
  • Network accessline 13
    "source": ".",       "homepage": "https://github.com/browser-use/browser-harness",       "keywords": [
  • Network accessline 14
    "homepage": "https://github.com/browser-use/browser-harness",

.claude-plugin/plugin.json

  • Network accessline 5
    "author": {     "name": "Browser Use",     "url": "https://browser-use.com"
  • Network accessline 6
    "name": "Browser Use",     "url": "https://browser-use.com"   },
  • Network accessline 7
    "url": "https://browser-use.com"
  • Network accessline 8
    },   "homepage": "https://github.com/browser-use/browser-harness",   "repository": "https://github.com/browser-use/browser-harness",
  • Network accessline 9
    "homepage": "https://github.com/browser-use/browser-harness",
  • Network accessline 10
    "repository": "https://github.com/browser-use/browser-harness",

.env.example

  • Access to secretsline 1
    [Credential-related source omitted]
  • Access to secretsline 2
    [Credential-related source omitted]

.github/ISSUE_TEMPLATE/config.yml

  • Network accessline 2
    contact_links:   - name: Question or how-to     url: https://github.com/browser-use/browser-harness/discussions/categories/q-a
  • Network accessline 3
    - name: Question or how-to     url: https://github.com/browser-use/browser-harness/discussions/categories/q-a     about: Ask in Discussions Q&A, not Issues.
  • Network accessline 4
    url: https://github.com/browser-use/browser-harness/discussions/categories/q-a
  • Network accessline 5
    about: Ask in Discussions Q&A, not Issues.   - name: Install or setup troubleshooting     url: https://github.com/browser-use/browser-harness/blob/main/install.md
  • Network accessline 6
    - name: Install or setup troubleshooting     url: https://github.com/browser-use/browser-harness/blob/main/install.md     about: Most install and "DevTools not live" errors are covered here.
  • Network accessline 7
    url: https://github.com/browser-use/browser-harness/blob/main/install.md

.github/VOUCHED.td

  • Network accessline 1
    # Vouched (or denounced) users for browser-harness. # # See https://github.com/mitchellh/vouch for details.
  • Network accessline 2
    # # See https://github.com/mitchellh/vouch for details. #
  • Network accessline 3
    # See https://github.com/mitchellh/vouch for details.

.gitignore

  • Access to secretsline 4
    [Credential-related source omitted]

AGENTS.md

  • Access to secretsline 51
    [Credential-related source omitted]

README.md

  • Network accessline 1
    <img src="https://raw.githubusercontent.com/browser-use/media/main/browser-harness/banner-ink.svg" alt="Browser Harness" width="100%" />
  • Network accessline 7
    Try browser-harness in [Browser Use Cloud](https://cloud.browser-use.com/v4?utm_campaign=browser-harness-use-in-cloud&utm_source=github) or paste the setup prompt into your coding agent.
  • Network accessline 25
    [![Download my latest 20 X videos](docs/download-latest-20-x-videos.gif)](https://browser-use.com/showcase/videos/download-latest-20-x-videos.mp4)
  • Network accessline 32
    Install or upgrade browser-harness to the latest stable version with uv using Python 3.12, register the skill from `browser-harness skill`, and connect it to my browser. Ask whether I want local browser recordings enabled; default to no and
  • Network accessline 58
    Matched eval by Browser Use on 100 of the 200 public [BU Bench V2.1](https://github.com/browser-use/benchmark) tasks (bu2-001 to bu2-100; 101-200 not run). Measured 2026-10-14.
  • Network accessline 78
    Measured with Codex only. Claude Code, Cursor, Playwright CLI and Claude in Chrome were not measured. Method and per-task scores: [coding-agent-browser-tools.json](https://browser-use.com/benchmarks/coding-agent-browser-tools.json).
  • Network accessline 91
    Use your local browser for logged-in, personal work. When you want many browsers in parallel, with live previews, proxies, stealth, CAPTCHA solving, and more, scale with [Browser Use Cloud](https://cloud.browser-use.com/new-api-key).
  • Network accessline 102
    Add this to `.cursor/mcp.json` in your project, or to `~/.cursor/mcp.json` for every project. It needs [uv](https://docs.astral.sh/uv/).
  • Network accessline 103
    every project. It needs [uv](https://docs.astral.sh/uv/).
  • Network accessline 123
    [The Bitter Lesson of Agent Harnesses](https://browser-use.com/posts/bitter-lesson-agent-harnesses) · [Web Agents That Actually Learn](https://browser-use.com/posts/web-agents-that-actually-learn)

SKILL.md

  • Network accessline 1
    --- name: browser-harness description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those."
  • Network accessline 2
    name: browser-harness description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those." ---
  • Network accessline 3
    description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those."
  • Network accessline 8
    Direct browser control via CDP. For task-specific edits, use `agent-workspace/agent_helpers.py`. For setup, install, or connection problems, read https://github.com/browser-use/browser-harness/blob/main/install.md.
  • Access to secretsline 143
    [Credential-related source omitted]
  • Network accessline 150
    You can also direct the user to try the same agent behind Browser Harness, fully hosted, in Browser Use Cloud (it's called the v4 agent): https://cloud.browser-use.com?utm_source=skill&utm_medium=browser-use&utm_campaign=v4.
  • Access to secretsline 161
    [Credential-related source omitted]
  • Network accessline 171
    BU_NAME=r7k2 browser-harness <<'PY' new_tab("https://example.com")
  • Network accessline 172
    new_tab("https://example.com")
  • Network accessline 183
    Cloud profile cookie sync reference: https://github.com/browser-use/browser-harness/blob/main/interaction-skills/profile-sync.md.
  • Network accessline 223
    Use it only if timestamps and pages match; otherwise say the work was not captured. Never reenact a completed task. For a video, follow [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.m
  • Network accessline 224
    captured. Never reenact a completed task. For a video, follow [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.md). If sub-agents are available, they may handle post-production from the 
  • Network accessline 225
    [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.md).
  • Network accessline 231
    If you get stuck on a browser mechanic, check https://github.com/browser-use/browser-harness/tree/main/interaction-skills.

agent-workspace/agent_helpers.py

  • Executable scriptline 1
    Executable file

agent-workspace/domain-skills/BOSS-zhipin/chat.md

  • Network accessline 191
    "uid": 502838021,                # sender user ID         "name": "张女士",         "avatar": "https://img.bosszhipin.com/..."
  • Network accessline 192
    "name": "张女士",         "avatar": "https://img.bosszhipin.com/..."     },
  • Network accessline 193
    "avatar": "https://img.bosszhipin.com/..."
  • Network accessline 226
    "uid": 3872648,                 "name": "刘女士",                 "avatar": "https://img.bosszhipin.com/..."
  • Network accessline 227
    "name": "刘女士",                 "avatar": "https://img.bosszhipin.com/..."             },
  • Network accessline 228
    "avatar": "https://img.bosszhipin.com/..."
  • Network accessline 242
    (async function() {{         var url = '/wapi/zpchat/geek/historyMsg?bossId={boss_id}&maxMsgId=0&c={count}&page={page}&src=0';         var r = await fetch(url);
  • Network accessline 243
    var url = '/wapi/zpchat/geek/historyMsg?bossId={boss_id}&maxMsgId=0&c={count}&page={page}&src=0';         var r = await fetch(url);         var d = await r.json();
  • Network accessline 244
    var r = await fetch(url);
  • Network accessline 289
    raw = js(f"""         (async function() {{             var r = await fetch('/wapi/zpchat/geek/historyMsg?bossId={boss_id}&maxMsgId={max_msg_id}&c=20&page=1&src=0');
  • Network accessline 290
    (async function() {{             var r = await fetch('/wapi/zpchat/geek/historyMsg?bossId={boss_id}&maxMsgId={max_msg_id}&c=20&page=1&src=0');             var d = await r.json();
  • Network accessline 291
    var r = await fetch('/wapi/zpchat/geek/historyMsg?bossId={boss_id}&maxMsgId={max_msg_id}&c=20&page=1&src=0');

agent-workspace/domain-skills/BOSS-zhipin/job-search.md

  • Network accessline 13
    [Credential-related source omitted]
  • Access to secretsline 13
    [Credential-related source omitted]
  • Network accessline 24
    goto_url("https://www.zhipin.com/web/geek/jobs?ka=open_joblist")
  • Network accessline 28
    jobs = json.loads(js(""" (async function() {     var r = await fetch('/wapi/zpgeek/pc/recommend/job/list.json?page=1&pageSize=15&city=101020100');
  • Network accessline 29
    (async function() {     var r = await fetch('/wapi/zpgeek/pc/recommend/job/list.json?page=1&pageSize=15&city=101020100');     var d = await r.json();
  • Network accessline 30
    var r = await fetch('/wapi/zpgeek/pc/recommend/job/list.json?page=1&pageSize=15&city=101020100');
  • Network accessline 45
    | Resource | URL | |----------|-----| | Job search page | `https://www.zhipin.com/web/geek/jobs` |
  • Network accessline 46
    |----------|-----| | Job search page | `https://www.zhipin.com/web/geek/jobs` | | Job search (with prefs) | `https://www.zhipin.com/web/geek/jobs?ka=open_joblist` |
  • Network accessline 47
    | Job search page | `https://www.zhipin.com/web/geek/jobs` |
  • Network accessline 48
    | Job search (with prefs) | `https://www.zhipin.com/web/geek/jobs?ka=open_joblist` |
  • Network accessline 49
    | Job detail page | `https://www.zhipin.com/job_detail/{JOB_ID}.html` |
  • Network accessline 50
    | Company page | `https://www.zhipin.com/gongsi/{COMPANY_ID}~.html` |
  • Network accessline 101
    "bossTitle": "人事",     "bossOnline": false,     "bossAvatar": "https://img.bosszhipin.com/...",
  • Network accessline 102
    "bossOnline": false,     "bossAvatar": "https://img.bosszhipin.com/...",     "brandLogo": "https://img.bosszhipin.com/...",
  • Network accessline 103
    "bossAvatar": "https://img.bosszhipin.com/...",
  • Network accessline 104
    "brandLogo": "https://img.bosszhipin.com/...",
  • Network accessline 134
    raw = js(f"""     (async function() {{         var r = await fetch('/wapi/zpgeek/pc/recommend/job/list.json?{params}');
  • Network accessline 135
    (async function() {{         var r = await fetch('/wapi/zpgeek/pc/recommend/job/list.json?{params}');         var d = await r.json();
  • Network accessline 136
    var r = await fetch('/wapi/zpgeek/pc/recommend/job/list.json?{params}');
  • Network accessline 183
    raw = js(f"""     (async function() {{         var r = await fetch('/wapi/zpgeek/job/detail.json?securityId={security_id}');
  • Network accessline 184
    (async function() {{         var r = await fetch('/wapi/zpgeek/job/detail.json?securityId={security_id}');         var d = await r.json();
  • Network accessline 185
    var r = await fetch('/wapi/zpgeek/job/detail.json?securityId={security_id}');
  • Network accessline 232
    raw = js("""     (async function() {         var r = await fetch('/wapi/zpgeek/pc/all/filter/conditions.json');
  • Network accessline 233
    (async function() {         var r = await fetch('/wapi/zpgeek/pc/all/filter/conditions.json');         var d = await r.json();
  • Network accessline 234
    var r = await fetch('/wapi/zpgeek/pc/all/filter/conditions.json');
  • Network accessline 340
    - **Always prefer the API** — `salaryDesc` returns human-readable salary. DOM salary uses font-encoded PUA chars that require OCR or font-file reversal to decode. - **API needs browser session** — `/wapi/` endpoints require cookies from a r
  • Network accessline 341
    [Credential-related source omitted]
  • Access to secretsline 341
    [Credential-related source omitted]

agent-workspace/domain-skills/BOSS-zhipin/navigation.md

  • Network accessline 9
    | Page | URL | |------|-----| | Home (redirects to city) | `https://www.zhipin.com/` → `https://www.zhipin.com/{city}/` |
  • Network accessline 10
    |------|-----| | Home (redirects to city) | `https://www.zhipin.com/` → `https://www.zhipin.com/{city}/` | | Job search | `https://www.zhipin.com/web/geek/jobs` |
  • Network accessline 11
    | Home (redirects to city) | `https://www.zhipin.com/` → `https://www.zhipin.com/{city}/` |
  • Network accessline 12
    | Job search | `https://www.zhipin.com/web/geek/jobs` |
  • Network accessline 13
    | Company search | `https://www.zhipin.com/gongsi/` |
  • Network accessline 14
    | Messages / Chat | `https://www.zhipin.com/web/geek/chat` |
  • Network accessline 15
    | Personal center | `https://www.zhipin.com/web/geek/recommend` |
  • Network accessline 19
    | Page | URL | |------|-----| | Campus recruitment | `https://www.zhipin.com/school/` |
  • Network accessline 20
    |------|-----| | Campus recruitment | `https://www.zhipin.com/school/` | | Returnee / Overseas talent | `https://www.zhipin.com/returnee_jobs/` |
  • Network accessline 21
    | Campus recruitment | `https://www.zhipin.com/school/` |
  • Network accessline 22
    | Returnee / Overseas talent | `https://www.zhipin.com/returnee_jobs/` |
  • Network accessline 23
    | Overseas jobs | `https://www.zhipin.com/overseas/` |
  • Network accessline 24
    | Accessibility jobs | `https://www.zhipin.com/accessible_job/` |
  • Network accessline 25
    | Youle (career community) | `https://youle.zhipin.com/recommend/selected/` |

agent-workspace/domain-skills/aa/checkout.md

  • Network accessline 7
    | Step | URL | Title | | --- | --- | --- | | Home | `https://www.aa.com/` → redirects to `/homePage.do` | American Airlines … |
  • Network accessline 8
    | --- | --- | --- | | Home | `https://www.aa.com/` → redirects to `/homePage.do` | American Airlines … | | Search results (**deep link**) | `https://www.aa.com/booking/search/find-flights?locale=en_US&fareType=Lowest&pax=1&adult=1&type=OneW
  • Network accessline 9
    | Home | `https://www.aa.com/` → redirects to `/homePage.do` | American Airlines … |
  • Network accessline 10
    | Search results (**deep link**) | `https://www.aa.com/booking/search/find-flights?locale=en_US&fareType=Lowest&pax=1&adult=1&type=OneWay&searchType=Revenue&cabin=&carriers=ALL&travelType=personal&slices=<urlencoded JSON>` | Choose flights 
  • Network accessline 11
    | After fare select | `https://www.aa.com/booking/choose-flights/1?sid=…` | same |
  • Network accessline 12
    | Trip summary | `https://www.aa.com/booking/your-trip-summary?sid=…` | Your trip summary |
  • Network accessline 13
    | Passenger details (separate Angular app) | `https://www.aa.com/airfare-sales/ui/passenger-ui/?search-journey-id=…&cid=…&sid=…` | Passengers |
  • Network accessline 14
    | Seat map | `https://www.aa.com/booking/passengers/deeplink/airfare-booking/<journey-id>?journey-state-id=<journey-id>&shopping-cart=<cart-id>` | Choose your seat |
  • Network accessline 15
    | Trip extras | `https://www.aa.com/ancillaries/offers/storefront/2/<cart-id>` | Trip extras |
  • Network accessline 16
    | Checkout / payment | `https://www.aa.com/ecommerce/checkout-app/cart/<cart-id>` | American Airlines Checkout |

agent-workspace/domain-skills/agentlist/discovery.md

  • Network accessline 3
    `https://agentlist.com` — public directory of skills, agents, MCPs, configs, and paid services. Field-tested with browser-harness on 2026-05-03.
  • Network accessline 12
    listings = json.loads(http_get("https://agentlist.com/api/listings?category=skill&q=github&limit=10"))
  • Network accessline 26
    # Search everything items = json.loads(http_get("https://agentlist.com/api/listings?q=github&limit=10"))
  • Network accessline 27
    items = json.loads(http_get("https://agentlist.com/api/listings?q=github&limit=10"))
  • Network accessline 29
    # Filter by category skills = json.loads(http_get("https://agentlist.com/api/listings?category=skill&q=browser&limit=10"))
  • Network accessline 30
    skills = json.loads(http_get("https://agentlist.com/api/listings?category=skill&q=browser&limit=10"))
  • Network accessline 31
    agents = json.loads(http_get("https://agentlist.com/api/listings?category=agent&limit=10"))
  • Network accessline 32
    mcps = json.loads(http_get("https://agentlist.com/api/listings?category=mcp&limit=10"))
  • Network accessline 33
    configs = json.loads(http_get("https://agentlist.com/api/listings?category=config&limit=10"))
  • Network accessline 34
    paid = json.loads(http_get("https://agentlist.com/api/listings?category=paid&limit=10"))
  • Network accessline 36
    # Sort and paginate new_items = json.loads(http_get("https://agentlist.com/api/listings?sort=new&skip=0&limit=20"))
  • Network accessline 37
    new_items = json.loads(http_get("https://agentlist.com/api/listings?sort=new&skip=0&limit=20"))
  • Network accessline 38
    top_items = json.loads(http_get("https://agentlist.com/api/listings?sort=top&limit=20"))
  • Network accessline 39
    trending_items = json.loads(http_get("https://agentlist.com/api/listings?sort=trending&limit=20"))
  • Network accessline 41
    # Fetch one listing listing = json.loads(http_get("https://agentlist.com/api/listings/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2"))
  • Network accessline 42
    listing = json.loads(http_get("https://agentlist.com/api/listings/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2"))
  • Network accessline 57
    skill_md = http_get("https://agentlist.com/raw/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2")
  • Network accessline 63
    skill_md = http_get("https://skills.agentlist.com/skill/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2/SKILL.md")
  • Network accessline 69
    https://skills.agentlist.com/skill/{id}/
  • Network accessline 75
    new_tab("https://agentlist.com")
  • Network accessline 127
    """) wait(1) print(page_info())  # URL becomes https://agentlist.com/?q=github
  • Network accessline 129
    print(page_info())  # URL becomes https://agentlist.com/?q=github
  • Network accessline 137
    https://agentlist.com/listing/{id}
  • Network accessline 143
    new_tab("https://agentlist.com/listing/6ea8f4f2-83cf-4625-a3cd-98b49d49a7b2")
  • Network accessline 163
    https://agentlist.com/submit

agent-workspace/domain-skills/agoda/scraping.md

  • Network accessline 27
    def city_id(slug):     """slug like 'bangkok-th' or 'tokyo-jp' (the /city/<slug>.html landing page)."""     url = f"https://www.agoda.com/city/{slug}.html"
  • Network accessline 28
    """slug like 'bangkok-th' or 'tokyo-jp' (the /city/<slug>.html landing page)."""     url = f"https://www.agoda.com/city/{slug}.html"     deadline, delay = time.time() + 120, 5        # one deadline for every attempt and backoff
  • Network accessline 29
    url = f"https://www.agoda.com/city/{slug}.html"
  • Network accessline 31
    while True:         try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Language": "en-US"})
  • Network accessline 32
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Language": "en-US"})             with urllib.request.urlopen(req, timeout=max(1, min(30, deadline - time.time()))) as r:
  • Network accessline 33
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Language": "en-US"})
  • Network accessline 34
    with urllib.request.urlopen(req, timeout=max(1, min(30, deadline - time.time()))) as r:
  • Network accessline 71
    params = {"city": CITY_ID, "checkIn": check_in, "los": 2, "rooms": 1, "adults": 2,           "children": 0, "locale": "en-us", "currency": "USD"} SEARCH_URL = "https://www.agoda.com/search?" + urllib.parse.urlencode(params)
  • Network accessline 73
    SEARCH_URL = "https://www.agoda.com/search?" + urllib.parse.urlencode(params)
  • Dangerous shell operationline 89
    const rm = rev && ((rev.getAttribute('aria-label') || '') + ' ' + rev.innerText)
  • Dangerous shell operationline 98
    review_score: rm ? parseFloat(rm[1]) : null,
  • Dangerous shell operationline 99
    review_count: rm ? parseInt(rm[2].replace(/,/g, '')) : null,
  • Network accessline 265
    search: https://www.agoda.com/search?city=9395&checkIn=2026-11-23&los=2&rooms=1&adults=2&children=0&locale=en-us&currency=USD&ds=zr2H4S2qsZq8000i
  • Network accessline 268
    Page 3 of 75: 97 properties unique 293 duplicates dropped 0 {'hotel_id': '51238093', 'name': 'Maison Hotel Bangkok', 'stars': 5, 'review_score': 8.9, 'review_count': 9464, 'price': 72, 'currency': 'USD', 'sold_out': False, 'promoted': False
  • Network accessline 269
    unique 293 duplicates dropped 0 {'hotel_id': '51238093', 'name': 'Maison Hotel Bangkok', 'stars': 5, 'review_score': 8.9, 'review_count': 9464, 'price': 72, 'currency': 'USD', 'sold_out': False, 'promoted': False, 'area': 'Sukhumvit, Bangko
  • Network accessline 270
    {'hotel_id': '51238093', 'name': 'Maison Hotel Bangkok', 'stars': 5, 'review_score': 8.9, 'review_count': 9464, 'price': 72, 'currency': 'USD', 'sold_out': False, 'promoted': False, 'area': 'Sukhumvit, Bangkok - City center', 'url': 'https:
  • Network accessline 283
    HOTEL_URLS = [   # any `url` values from the search rows     "https://www.agoda.com/bless-residence/hotel/bangkok-th.html",
  • Network accessline 284
    "https://www.agoda.com/bless-residence/hotel/bangkok-th.html",
  • Network accessline 285
    "https://www.agoda.com/accom/property?propertyId=14654101",   # the other href form
  • Network accessline 286
    "https://www.agoda.com/accom/property?propertyId=14651963",   # had no rate for 2026-11-23 when tested; other dates may have one
  • Network accessline 364
    query = dict(urllib.parse.parse_qsl(u.query), **STAY)     target = u._replace(query=urllib.parse.urlencode(query)).geturl()     if current_tab()["url"].startswith("https://www.agoda.com/"):
  • Network accessline 365
    target = u._replace(query=urllib.parse.urlencode(query)).geturl()     if current_tab()["url"].startswith("https://www.agoda.com/"):         goto_url(target)                          # reuse this skill's own Agoda tab
  • Network accessline 366
    if current_tab()["url"].startswith("https://www.agoda.com/"):
  • Network accessline 410
    "jsonld_loaded": true,  "name": "The Bless Hotel & Residence",  "url": "https://www.agoda.com/bless-residence/hotel/bangkok-th.html",
  • Network accessline 411
    "name": "The Bless Hotel & Residence",  "url": "https://www.agoda.com/bless-residence/hotel/bangkok-th.html",  "stars": 4,
  • Network accessline 412
    "url": "https://www.agoda.com/bless-residence/hotel/bangkok-th.html",
  • Network accessline 447
    "Airport transfer"  ],  "image": "https://pix8.agoda.net/hotelImages/177997/-1/794165056d07deceb10d1f2d79f00e4c.jpg?ce=0&s=1024x768",
  • Network accessline 448
    ],  "image": "https://pix8.agoda.net/hotelImages/177997/-1/794165056d07deceb10d1f2d79f00e4c.jpg?ce=0&s=1024x768",  "description": "Experience Comfort and Convenience at The Bless Hotel & Residence, BangkokNestle..."
  • Network accessline 449
    "image": "https://pix8.agoda.net/hotelImages/177997/-1/794165056d07deceb10d1f2d79f00e4c.jpg?ce=0&s=1024x768",
  • Network accessline 454
    "jsonld_loaded": true,  "name": "Madison Bangkok",  "url": "https://www.agoda.com/accom/property?propertyId=14651963",
  • Network accessline 455
    "name": "Madison Bangkok",  "url": "https://www.agoda.com/accom/property?propertyId=14651963",  ...
  • Network accessline 456
    "url": "https://www.agoda.com/accom/property?propertyId=14651963",
  • Network accessline 478
    | `promoted` | card text `"Promoted"` (Agoda says it earns more commission on these) | `false` | | `area` | `[data-selenium="area-city-text"]` | `"Sukhumvit, Bangkok - City center"` | | `url` | `a[data-selenium="hotel-name"]` `href`, search
  • Network accessline 479
    | `area` | `[data-selenium="area-city-text"]` | `"Sukhumvit, Bangkok - City center"` | | `url` | `a[data-selenium="hotel-name"]` `href`, search parameters stripped | `https://www.agoda.com/bless-residence/hotel/bangkok-th.html` or `https://
  • Network accessline 480
    | `url` | `a[data-selenium="hotel-name"]` `href`, search parameters stripped | `https://www.agoda.com/bless-residence/hotel/bangkok-th.html` or `https://www.agoda.com/accom/property?propertyId=177997` |
  • Network accessline 499
    | `sold_out` | no "from" bar and an `h2` in `#property-room-grid-root` reading `"Sold out!"` or `"Unavailable on Agoda"` | `false` | | `top_amenities` | `[data-element-name="atf-top-amenities-item"]` | `["Free Wi-Fi", "Swimming pool", ...]`
  • Network accessline 500
    | `top_amenities` | `[data-element-name="atf-top-amenities-item"]` | `["Free Wi-Fi", "Swimming pool", ...]` | | `image` | JSON-LD `image` (protocol-relative, made absolute) | `https://pix8.agoda.net/hotelImages/...` | | `description` | JSON
  • Network accessline 501
    | `image` | JSON-LD `image` (protocol-relative, made absolute) | `https://pix8.agoda.net/hotelImages/...` |
  • Network accessline 513
    - **Review counts disagree.** JSON-LD `aggregateRating.reviewCount` lags the rendered count (12,409 vs 13,034 for the same hotel the same minute; 16,192 vs 17,767 for another). Use the rendered number if you want what users see. - **JSON-LD
  • Network accessline 514
    - **JSON-LD arrives late.** `script[data-selenium="bay-hotel-schema-json-ld"]` is in the DOM empty when the `h1` appears and is filled about 2 s later (0 then 23,163 characters). Reading too early returned `postal`, `lat`, `image` all `null
  • Network accessline 515
    - **JSON-LD `url` on `/accom/property` pages** is the bare `https://www.agoda.com/accom/property`, so block 3 rebuilds the URL with `propertyId` there.

agent-workspace/domain-skills/airbnb/monthly-search.md

  • Network accessline 6
    https://www.airbnb.com/s/San-Francisco--CA--United-States/homes?refinement_paths%5B%5D=%2Fhomes&checkin=2026-10-11&checkout=2026-11-11&adults=2&min_bedrooms=2&room_types%5B%5D=Entire%20home%2Fapt&ne_lat=37.812&ne_lng=-122.405&sw_lat=37.778&
  • Network accessline 45
    `https://www.airbnb.com/rooms/<id>?check_in=..&check_out=..&adults=2` — `document.body.innerText`

agent-workspace/domain-skills/alaska/checkout.md

  • Network accessline 7
    - **Results deep link (cash mode once toggled)**: `https://www.alaskaair.com/search/results?O={orig}&D={dest}&OD={YYYY-MM-DD}&A=1&C=0&L=0&RT=false`. The site sometimes lands in award/points mode. Flip via the `Money`/`Points` toggle (see se
  • Network accessline 8
    - **Cart**: `https://www.alaskaair.com/search/cart?...` — arrived via `Add to cart` from results.
  • Network accessline 9
    - **Guest info**: `https://www.alaskaair.com/book/guest-info` — arrived via `Continue as guest` from cart.
  • Network accessline 10
    - **Seat selection**: `https://www.alaskaair.com/book/seat-selection`.
  • Network accessline 11
    - **Review & pay**: `https://www.alaskaair.com/book/checkout` — the payment page, card fields live here.

agent-workspace/domain-skills/aliexpress/scraping.md

  • Network accessline 26
    import email.utils, gzip, http.client, json, re, time, urllib.error, urllib.parse, urllib.request
  • Network accessline 28
    # Truthful client User-Agent; it returned the full search page on 2026-10-23. HEADERS = {     "User-Agent": "browser-harness-skill/1.0 (+https://github.com/browser-use/browser-harness)",
  • Network accessline 29
    HEADERS = {     "User-Agent": "browser-harness-skill/1.0 (+https://github.com/browser-use/browser-harness)",     "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
  • Network accessline 30
    "User-Agent": "browser-harness-skill/1.0 (+https://github.com/browser-use/browser-harness)",
  • Network accessline 45
    slug = re.sub(r"[^a-z0-9]+", "-", query.lower()).strip("-")     params = {"SearchText": query, "page": page, **({"sortType": sort} if sort else {})}     return f"https://www.aliexpress.com/w/wholesale-{slug}.html?{urllib.parse.urlencode(par
  • Network accessline 47
    return f"https://www.aliexpress.com/w/wholesale-{slug}.html?{urllib.parse.urlencode(params)}"   # safe="": "/" -> %2F
  • Network accessline 61
    def fetch(url, attempts=4, timeout=30):
  • Network accessline 65
    for attempt in range(1, attempts + 1):         try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=timeout) as r:
  • Network accessline 66
    try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=timeout) as r:                 body = r.read()
  • Network accessline 67
    with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=timeout) as r:
  • Network accessline 74
    raise                         # 3xx loop / 4xx: retrying will not help             wait, err = retry_after_seconds(e.headers.get("Retry-After")) or delay, e         except (urllib.error.URLError, http.client.HTTPException, TimeoutError, Con
  • Network accessline 75
    wait, err = retry_after_seconds(e.headers.get("Retry-After")) or delay, e         except (urllib.error.URLError, http.client.HTTPException, TimeoutError, ConnectionError) as e:             wait, err = delay, e
  • Network accessline 76
    except (urllib.error.URLError, http.client.HTTPException, TimeoutError, ConnectionError) as e:
  • Network accessline 157
    "sponsored": "p4p" in c,             "image": img,             "url": f"https://www.aliexpress.com/item/{pid}.html" if pid else None,
  • Network accessline 158
    "image": img,             "url": f"https://www.aliexpress.com/item/{pid}.html" if pid else None,         })
  • Network accessline 159
    "url": f"https://www.aliexpress.com/item/{pid}.html" if pid else None,
  • Network accessline 167
    rows, report = {}, {"pages_read": 0, "stopped": None, "totalResults": None}     for page in range(1, max_pages + 1):         html = fetch(search_url(query, page, sort))
  • Network accessline 168
    for page in range(1, max_pages + 1):         html = fetch(search_url(query, page, sort))         data = parse_init_data(html)
  • Network accessline 169
    html = fetch(search_url(query, page, sort))
  • Network accessline 218
    price_source: {'card': 102, 'tracking': 64, None: 0} present: {'price': 166, 'original_price': 153, 'sold': 159, 'sold_count': 159, 'rating': 143, 'store_name': 66, 'image': 166} sponsored: 38 {"product_id": "3256813091598934", "title": "IN
  • Network accessline 219
    present: {'price': 166, 'original_price': 153, 'sold': 159, 'sold_count': 159, 'rating': 143, 'store_name': 66, 'image': 166} sponsored: 38 {"product_id": "3256813091598934", "title": "INS Korean Simple Blue Pink Bow Girl Mirror Cute Phone 
  • Network accessline 220
    {"product_id": "3256813091598934", "title": "INS Korean Simple Blue Pink Bow Girl Mirror Cute Phone Case For iPhone 17 16 15 Pro Max ...", "price": 1.09, "price_text": "US $1.09", "original_price": 3.73, "currency": "USD", "price_source": "
  • Network accessline 221
    {"product_id": "3256810401258185", "title": "Custom Matte Case For iPhone 17 16 15 14 13 12 11 Pro Max ...", "price": 1.09, "price_text": null, "original_price": 7.71, "currency": "USD", "price_source": "tracking", "welcome_deal": true, "so
  • Network accessline 234
    slug = re.sub(r"[^a-z0-9]+", "-", query.lower()).strip("-")     params = {"SearchText": query, "page": page, **({"sortType": sort} if sort else {})}     return f"https://www.aliexpress.com/w/wholesale-{slug}.html?{urllib.parse.urlencode(par
  • Network accessline 236
    return f"https://www.aliexpress.com/w/wholesale-{slug}.html?{urllib.parse.urlencode(params)}"
  • Network accessline 274
    rating: n(o(c.evaluation).starRating), store_name: store, sponsored: 'p4p' in c,         image: (typeof img === 'string' && img) ? (img.startsWith('//') ? 'https:' + img : img) : null,         url: pid ? 'https://www.aliexpress.com/item/' +
  • Network accessline 275
    image: (typeof img === 'string' && img) ? (img.startsWith('//') ? 'https:' + img : img) : null,         url: pid ? 'https://www.aliexpress.com/item/' + pid + '.html' : null};     })});
  • Network accessline 276
    url: pid ? 'https://www.aliexpress.com/item/' + pid + '.html' : null};
  • Network accessline 346
    163 unique products {'pages_read': 3, 'stopped': 'max_pages=3'} price_source: {'card': 110, 'tracking': 53, None: 0} {"product_id": "3256811701939685", "title": "Red Cherry Pattern Mirror Phone Case For iPhone 17 Pro Max ...", "price": 1.09
  • Network accessline 348
    {"product_id": "3256811701939685", "title": "Red Cherry Pattern Mirror Phone Case For iPhone 17 Pro Max ...", "price": 1.09, "price_text": null, "original_price": 3.54, "currency": "USD", "price_source": "tracking", "welcome_deal": true, "s
  • Network accessline 384
    pass     try:         goto_url(f"https://www.aliexpress.com/item/{product_id}.html")
  • Network accessline 385
    try:         goto_url(f"https://www.aliexpress.com/item/{product_id}.html")     except TimeoutError:                  # IPC timeout; the navigation may still be running
  • Network accessline 386
    goto_url(f"https://www.aliexpress.com/item/{product_id}.html")
  • Network accessline 509
    new_tab() ids = search_ids("https://www.aliexpress.com/w/wholesale-mechanical-keyboard.html?SearchText=mechanical+keyboard")
  • Network accessline 510
    ids = search_ids("https://www.aliexpress.com/w/wholesale-mechanical-keyboard.html?SearchText=mechanical+keyboard")
  • Network accessline 538
    "title": "AJAZZ AK820 and AK820PRO Mechanical Gaming Keyboard 75% Layout PBT OEM Keycap RGB Backlight Full Key Anti-Ghosting Type-C",  "rating": "4.9", "reviews": 5048, "sales_text": "This seller: 700+ sales | Total sales: 10,000+",  "store
  • Network accessline 539
    "rating": "4.9", "reviews": 5048, "sales_text": "This seller: 700+ sales | Total sales: 10,000+",  "store_name": "Stone's Store", "store_url": "https://www.aliexpress.com/store/1103576287",  "store_positive_rate": "100.0", "store_open_since
  • Network accessline 540
    "store_name": "Stone's Store", "store_url": "https://www.aliexpress.com/store/1103576287",
  • Network accessline 578
    | `store_name` | `trace.custom.p4pExtendParam` (JSON string) `.store_name` | `"Shop1105082514 Store"` | 66 of 166 | | `sponsored` | `"p4p" in card` | `true` | boolean, 38 of 166 true | | `image` | `image.imgUrl`, protocol-relative made `htt
  • Network accessline 579
    | `sponsored` | `"p4p" in card` | `true` | boolean, 38 of 166 true | | `image` | `image.imgUrl`, protocol-relative made `https:` | `https://ae-pic-a1.aliexpress-media.com/kf/...jpg` | 166 of 166 | | `url` | built from `productId` (`None` if
  • Network accessline 580
    | `image` | `image.imgUrl`, protocol-relative made `https:` | `https://ae-pic-a1.aliexpress-media.com/kf/...jpg` | 166 of 166 |
  • Network accessline 581
    | `url` | built from `productId` (`None` if no id) | `https://www.aliexpress.com/item/<id>.html` | 166 of 166 |
  • Network accessline 629
    [Credential-related source omitted]
  • Access to secretsline 629
    [Credential-related source omitted]

agent-workspace/domain-skills/amazon/order-history.md

  • Network accessline 28
    new_tab("https://www.amazon.co.uk/your-orders/orders?timeFilter=year-2025&startIndex=0")

agent-workspace/domain-skills/amazon/product-search.md

  • Network accessline 10
    goto_url("https://www.amazon.com/s?k=mechanical+keyboard")
  • Network accessline 17
    goto_url("https://www.amazon.com")
  • Network accessline 32
    # URL pattern: /dp/{ASIN}  or  /dp/{ASIN}?th=1 (Amazon may redirect to add ?th=1) goto_url("https://www.amazon.com/dp/B08Z6X4NK3")
  • Network accessline 33
    goto_url("https://www.amazon.com/dp/B08Z6X4NK3")
  • Network accessline 45
    tid = new_tab("https://www.amazon.com/s?k=mechanical+keyboard")
  • Network accessline 116
    URL: `https://www.amazon.com/Best-Sellers-{Category}/zgbs/{slug}/`
  • Network accessline 117
    e.g. `https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics/`
  • Network accessline 123
    goto_url("https://www.amazon.com/Best-Sellers-Electronics/zgbs/electronics/")
  • Network accessline 133
    title: container.querySelector('img[alt]')?.getAttribute('alt'),       price: container.querySelector('.p13n-sc-price, .a-size-base.a-color-price')?.innerText,       url: 'https://www.amazon.com/dp/' + el.getAttribute('data-asin')
  • Network accessline 134
    price: container.querySelector('.p13n-sc-price, .a-size-base.a-color-price')?.innerText,       url: 'https://www.amazon.com/dp/' + el.getAttribute('data-asin')     }
  • Network accessline 135
    url: 'https://www.amazon.com/dp/' + el.getAttribute('data-asin')
  • Network accessline 153
    # Or construct by page number goto_url("https://www.amazon.com/s?k=wireless+mouse&page=2")
  • Network accessline 154
    goto_url("https://www.amazon.com/s?k=wireless+mouse&page=2")

agent-workspace/domain-skills/apartments-com/scraping.md

  • Network accessline 12
    - Each card carries a `data-listing-share-lines` JSON array (street, city line, beds, baths, rent) plus a phone in `phone-data`. The code keeps the phone only for non-single-home tiers (see "Personal data"). Card amenities only exist on som
  • Network accessline 14
    - The CDN blocks the whole browser session after sustained crawling. Observed: about 40 page loads plus same-origin `fetch()` calls in 25 minutes, then every request (pages and fetch) returned "Access Denied". Keep at least 5 s between page
  • Network accessline 121
    listings, seen, repeats = [], set(), 0 url, page = f"https://www.apartments.com/{CITY}/", 1
  • Network accessline 122
    url, page = f"https://www.apartments.com/{CITY}/", 1
  • Network accessline 169
    Output observed on a fresh cloud browser (trimmed). The same code over `kerrville-tx` with `MAX_PAGES = 5` printed `complete: all 2 pages, 65 results` with address, beds, rent and url on 65/65; `alpine-tx` printed `(single page, no pager) 4
  • Network accessline 188
    "phone": "7372379124",   "amenities": "Pets Allowed, Fitness Center, Pool, Walk-In Closets, Clubhouse, Stainless Steel Appliances, Business Center",   "url": "https://www.apartments.com/ellwood-at-lake-travis-austin-tx/4v6169l/"
  • Network accessline 189
    "amenities": "Pets Allowed, Fitness Center, Pool, Walk-In Closets, Clubhouse, Stainless Steel Appliances, Business Center",   "url": "https://www.apartments.com/ellwood-at-lake-travis-austin-tx/4v6169l/"  }
  • Network accessline 190
    "url": "https://www.apartments.com/ellwood-at-lake-travis-austin-tx/4v6169l/"
  • Network accessline 255
    if not PROPERTY_URL:     open_page(f"https://www.apartments.com/{CITY}/", first=True)
  • Network accessline 256
    open_page(f"https://www.apartments.com/{CITY}/", first=True)
  • Network accessline 355
    {  "url": "https://www.apartments.com/ellwood-at-lake-travis-austin-tx/4v6169l/",
  • Network accessline 356
    "url": "https://www.apartments.com/ellwood-at-lake-travis-austin-tx/4v6169l/",
  • Network accessline 423
    - **CDN block (Akamai).** Plain HTTP is 403. In the browser, the session got "Access Denied" (title `Access Denied`, an `errors.edgesuite.net` reference) after sustained crawling, and same-origin `fetch()` from the page returned 403 too onc
  • Network accessline 424
    - **Rate limits.** 18 consecutive page navigations at about 4.5 s spacing worked. The block came later in the session after extra rapid `fetch()` calls at 2 s spacing. Keep at least 5 s between loads and keep total volume modest.
  • Network accessline 437
    - Plain HTTP (`http_get`, curl, requests) on any apartments.com URL, including `/robots.txt`: HTTP 403 "Access Denied" from the edge. - Paging past the cap: `/austin-tx/19/` redirects to `/austin-tx/`. - Continuing after a block: once "Acce
  • Network accessline 438
    - Paging past the cap: `/austin-tx/19/` redirects to `/austin-tx/`. - Continuing after a block: once "Access Denied" appeared, the next pages and in-page `fetch()` calls in the same session were also 403, and a single page load about 12 min
  • Network accessline 439
    - Continuing after a block: once "Access Denied" appeared, the next pages and in-page `fetch()` calls in the same session were also 403, and a single page load about 12 minutes later was still "Access Denied". On a block, stop and back off;
  • Network accessline 440
    - Bursts of same-origin `fetch()` calls for other search pages (2 s spacing) were followed shortly by the session block. Plain page navigation at about 4.5 s spacing held up for a full 18-page crawl, so the code above uses it.

agent-workspace/domain-skills/apollo/search-and-lists.md

  • Network accessline 5
    - Company search: `https://app.apollo.io/#/companies`; people search: `#/people`.

agent-workspace/domain-skills/apple-app-store/scraping.md

  • Network accessline 5
    robots.txt (checked 2026-10-23): itunes.apple.com disallows `/search*` for all user agents and has no rule that matches `/lookup` (its `/*/lookup?` rule needs a path segment before `lookup`), so it allows the Lookup API; apps.apple.com does
  • Network accessline 9
    - Use the public **iTunes Search/Lookup API** first. No key, no cookies, JSON out:   - `https://itunes.apple.com/search?term=...&entity=software&country=us&limit=200` - up to 200 apps per query.
  • Network accessline 10
    - `https://itunes.apple.com/search?term=...&entity=software&country=us&limit=200` - up to 200 apps per query.
  • Network accessline 11
    - `https://itunes.apple.com/lookup?id=ID1,ID2,...&country=us` - many app IDs per call (also `bundleId=` and developer `id=` + `entity=software`).
  • Network accessline 12
    - One API record already has name, developer, average rating, ratings count, price, category, size in bytes, current version, current-version release date and its release notes. - The app page (`https://apps.apple.com/us/app/id<ID>`) adds w
  • Network accessline 13
    - The app page (`https://apps.apple.com/us/app/id<ID>`) adds what the API lacks: 5-to-1 star histogram, top-chart rank, the new age rating (13+, 9+), and the **25 most recent versions** with dates and notes. It is server-rendered JSON in `<
  • Network accessline 44
    def fetch(url, retries=4):
  • Network accessline 47
    for attempt in range(retries):         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 48
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 49
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 50
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 66
    def itunes(path, params):     """GET https://itunes.apple.com/<path>?<params> and return the parsed JSON object."""     url = f"https://itunes.apple.com/{path}?" + urllib.parse.urlencode(params)  # quotes every value, '/' included
  • Network accessline 67
    """GET https://itunes.apple.com/<path>?<params> and return the parsed JSON object."""     url = f"https://itunes.apple.com/{path}?" + urllib.parse.urlencode(params)  # quotes every value, '/' included     body = fetch(url)
  • Network accessline 68
    url = f"https://itunes.apple.com/{path}?" + urllib.parse.urlencode(params)  # quotes every value, '/' included
  • Network accessline 69
    body = fetch(url)
  • Network accessline 154
    "first_release": "2012-07-18T07:00:00Z",  "bundle_id": "com.creditkarma.mobile",  "url": "https://apps.apple.com/us/app/intuit-credit-karma/id519817714"
  • Network accessline 155
    "bundle_id": "com.creditkarma.mobile",  "url": "https://apps.apple.com/us/app/intuit-credit-karma/id519817714" }
  • Network accessline 156
    "url": "https://apps.apple.com/us/app/intuit-credit-karma/id519817714"
  • Network accessline 180
    def fetch(url, retries=4):
  • Network accessline 181
    for attempt in range(retries):         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 182
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 183
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 184
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 200
    def itunes(path, params):     url = f"https://itunes.apple.com/{path}?" + urllib.parse.urlencode(params)
  • Network accessline 201
    url = f"https://itunes.apple.com/{path}?" + urllib.parse.urlencode(params)
  • Network accessline 202
    body = fetch(url)
  • Network accessline 289
    def fetch(url, retries=4):
  • Network accessline 290
    for attempt in range(retries):         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 291
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 292
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 293
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 315
    def app_page(app_id, country="us"):     """Extras only the web page has. None if the app does not exist (HTTP 404); raises on anything else odd."""     url = f"https://apps.apple.com/{country}/app/id{app_id}"
  • Network accessline 316
    """Extras only the web page has. None if the app does not exist (HTTP 404); raises on anything else odd."""     url = f"https://apps.apple.com/{country}/app/id{app_id}"     html = fetch(url)
  • Network accessline 317
    url = f"https://apps.apple.com/{country}/app/id{app_id}"     html = fetch(url)     if html is None:
  • Network accessline 318
    html = fetch(url)
  • Network accessline 388
    def open_app(app_id, first_tab, timeout=30):     """Navigate, then wait until location.href is the requested app and the document is complete."""     url = f"https://apps.apple.com/us/app/id{app_id}"
  • Network accessline 389
    """Navigate, then wait until location.href is the requested app and the document is complete."""     url = f"https://apps.apple.com/us/app/id{app_id}"     new_tab(url) if first_tab else goto_url(url)
  • Network accessline 390
    url = f"https://apps.apple.com/us/app/id{app_id}"
  • Network accessline 405
    EXTRACT = r"""(async (url, appId) => {   const res = await fetch(url, {credentials: 'omit'});
  • Network accessline 406
    const res = await fetch(url, {credentials: 'omit'});
  • Network accessline 427
    """Page extras for app_id via an in-page fetch. None on HTTP 404; retries 429/5xx and browser timeouts     with backoff (no sleep after the last try), then raises. 403 and other statuses raise at once."""     url, out = f"https://apps.apple
  • Network accessline 428
    with backoff (no sleep after the last try), then raises. 403 and other statuses raise at once."""     url, out = f"https://apps.apple.com/us/app/id{app_id}", None     for attempt in range(retries):
  • Network accessline 429
    url, out = f"https://apps.apple.com/us/app/id{app_id}", None
  • Network accessline 461
    310633997 https://apps.apple.com/us/app/whatsapp-messenger/id310633997 {"status": 200, "incomplete": false, "name": "WhatsApp Messenger", "rating": 4.7, "ratings_count": 18827914, "stars_5_to_1": [15891698, 1461031, 570089, 256170, 648926],
  • Network accessline 462
    1586435171 https://apps.apple.com/us/app/actions/id1586435171 {"status": 200, "incomplete": false, "name": "Actions", "rating": 4.8, "ratings_count": 515, "stars_5_to_1": [469, 20, 8, 1, 17], "chart_rank": null, "age_rating": "4+", "size": 
  • Network accessline 518
    - Version history dates on the page are JS `Date.toString()` strings ("Mon Oct 19 2026 12:27:02 GMT+0000 ..."), not ISO. The API's `currentVersionReleaseDate` is ISO. - Only the 25 most recent versions are embedded (all 5 apps tested had ex
  • Network accessline 519
    - Only the 25 most recent versions are embedded (all 5 apps tested had exactly 25). Older versions are not on the page, so 25 means "maybe more", not "all". - `https://apps.apple.com/us/app/id<ID>` works without the slug and redirects to th
  • Network accessline 520
    - `https://apps.apple.com/us/app/id<ID>` works without the slug and redirects to the slugged URL. Match the tab URL on `/id<ID>`, not on the exact URL you navigated to. - No consent banner or login wall appeared on US app pages. - Plain HTT
  • Network accessline 526
    - **Web search page** for scale: `https://apps.apple.com/us/iphone/search?term=...` rendered only **11** apps in the browser and scrolling 6 times loaded no more. A plain HTTP GET returns HTTP 200 (about 560 KB) whose `serialized-server-dat

agent-workspace/domain-skills/archive-org/scraping.md

  • Network accessline 3
    `https://archive.org` / `https://web.archive.org` — all public data, no auth required. Every workflow here is pure `http_get` — no browser needed.
  • Network accessline 12
    # Find snapshots of any URL — primary entry point for Wayback data r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 13
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=iana.org&output=json&limit=5"
  • Network accessline 14
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 21
    for row in rows[1:]:     ts, orig, status, mime, length = row     snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 22
    ts, orig, status, mime, length = row     snap_url = f"https://web.archive.org/web/{ts}/{orig}"     print(f"{ts}  {status}  {snap_url}")
  • Network accessline 23
    snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 30
    data = json.loads(http_get("https://archive.org/metadata/{identifier}", timeout=30.0))
  • Network accessline 40
    # CDX sort=closest returns the single snapshot nearest to the given timestamp r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 41
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=iana.org&output=json&limit=1"
  • Network accessline 42
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 49
    # rows[0] = header, rows[1] = closest snapshot ts, orig, status = rows[1] snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 50
    ts, orig, status = rows[1] snap_url = f"https://web.archive.org/web/{ts}/{orig}" # Result: ts='20230601114925', orig='https://www.iana.org/', status='200'
  • Network accessline 51
    snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 52
    # Result: ts='20230601114925', orig='https://www.iana.org/', status='200'
  • Network accessline 53
    # snap_url: https://web.archive.org/web/20230601114925/https://www.iana.org/
  • Network accessline 63
    r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 64
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 72
    # rows[0] = header ['timestamp', 'original'] # rows[1:] = one row per month: # ['20230101103807', 'https://www.iana.org/']
  • Network accessline 73
    # rows[1:] = one row per month: # ['20230101103807', 'https://www.iana.org/'] # ['20230201144829', 'https://www.iana.org/']
  • Network accessline 74
    # ['20230101103807', 'https://www.iana.org/']
  • Network accessline 75
    # ['20230201144829', 'https://www.iana.org/']
  • Network accessline 78
    for ts, orig in rows[1:]:     print(f"{ts[:4]}-{ts[4:6]}  https://web.archive.org/web/{ts}/{orig}")
  • Network accessline 79
    print(f"{ts[:4]}-{ts[4:6]}  https://web.archive.org/web/{ts}/{orig}")
  • Network accessline 90
    # matchType=domain captures all URLs under that domain r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 91
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=iana.org&matchType=domain&output=json"
  • Network accessline 92
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 99
    for row in rows[1:]:     print(row) # ['19971210061738', 'http://www.iana.org:80/', '200']
  • Network accessline 100
    print(row) # ['19971210061738', 'http://www.iana.org:80/', '200'] # ['19980211065537', 'http://www.iana.org:80/', '200']
  • Network accessline 101
    # ['19971210061738', 'http://www.iana.org:80/', '200']
  • Network accessline 102
    # ['19980211065537', 'http://www.iana.org:80/', '200']
  • Network accessline 113
    # All archived pages under /domains/ path r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 114
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=iana.org/domains/&matchType=prefix&output=json"
  • Network accessline 115
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 121
    for row in rows[1:]:     print(row) # ['20080509121811', 'http://www.iana.org/domains/', '200']
  • Network accessline 122
    print(row) # ['20080509121811', 'http://www.iana.org/domains/', '200'] # ['20080704174537', 'http://iana.org/domains/', '200']
  • Network accessline 123
    # ['20080509121811', 'http://www.iana.org/domains/', '200']
  • Network accessline 124
    # ['20080704174537', 'http://iana.org/domains/', '200']
  • Network accessline 134
    """Iterate all CDX records for a URL, yielding rows (excluding header)."""     base = (         f"https://web.archive.org/cdx/search/cdx"
  • Network accessline 135
    base = (         f"https://web.archive.org/cdx/search/cdx"         f"?url={quote(url, safe='')}&output=json"
  • Network accessline 136
    f"https://web.archive.org/cdx/search/cdx"
  • Network accessline 163
    # Direct snapshot URL: /web/{14-digit-timestamp}/{original-url} snap_url = "https://web.archive.org/web/19971210061738/http://www.iana.org:80/"
  • Network accessline 164
    snap_url = "https://web.archive.org/web/19971210061738/http://www.iana.org:80/"
  • Network accessline 169
    # The calendar view URL pattern (for browser navigation, not http_get): # https://web.archive.org/web/20230101000000*/python.org
  • Network accessline 170
    # https://web.archive.org/web/20230101000000*/python.org
  • Network accessline 180
    identifier = "HardWonWisdomTrailer" data = json.loads(http_get(f"https://archive.org/metadata/{identifier}", timeout=30.0))
  • Network accessline 181
    data = json.loads(http_get(f"https://archive.org/metadata/{identifier}", timeout=30.0))
  • Network accessline 216
    from urllib.parse import quote as urlquote # Form 1: direct storage server (fastest) url1 = f"https://{server}{dir_path}/{urlquote(fname)}"
  • Network accessline 217
    # Form 1: direct storage server (fastest) url1 = f"https://{server}{dir_path}/{urlquote(fname)}" # Form 2: standard redirect URL (always works, resolved by CDN)
  • Network accessline 218
    url1 = f"https://{server}{dir_path}/{urlquote(fname)}" # Form 2: standard redirect URL (always works, resolved by CDN) url2 = f"https://archive.org/download/{identifier}/{urlquote(fname)}"
  • Network accessline 219
    # Form 2: standard redirect URL (always works, resolved by CDN) url2 = f"https://archive.org/download/{identifier}/{urlquote(fname)}" # Both confirmed status 200, Content-Type: video/mp4
  • Network accessline 220
    url2 = f"https://archive.org/download/{identifier}/{urlquote(fname)}"
  • Network accessline 229
    # advancedsearch.php is the correct API — /search returns HTML r = http_get(     "https://archive.org/advancedsearch.php"
  • Network accessline 230
    r = http_get(     "https://archive.org/advancedsearch.php"     "?q=artificial+intelligence+AND+mediatype:texts"
  • Network accessline 231
    "https://archive.org/advancedsearch.php"
  • Network accessline 258
    r = http_get(     "https://archive.org/advancedsearch.php"
  • Network accessline 259
    "https://archive.org/advancedsearch.php"
  • Network accessline 295
    | `urlkey` | SURT-format URL (reversed domain, path in parens) | `org,iana)/` | | `timestamp` | Capture time, 14-digit `YYYYMMDDHHMMSS` | `19971210061738` | | `original` | Original crawled URL (exact, including port) | `http://www.iana.org:
  • Network accessline 296
    | `timestamp` | Capture time, 14-digit `YYYYMMDDHHMMSS` | `19971210061738` | | `original` | Original crawled URL (exact, including port) | `http://www.iana.org:80/` | | `mimetype` | Content-Type of the archived response | `text/html` |
  • Network accessline 297
    | `original` | Original crawled URL (exact, including port) | `http://www.iana.org:80/` |
  • Network accessline 327
    - **The `original` field preserves port numbers.** Old crawls captured `http://www.iana.org:80/` — the `:80` is part of the URL. When building a playback URL, use `original` verbatim: `f"https://web.archive.org/web/{ts}/{orig}"` works corre
  • Network accessline 329
    - **Metadata `{}` means the item doesn't exist or is private.** `http_get("https://archive.org/metadata/nonexistent")` returns `'{}'` (2-byte response) with HTTP 200. Always check `if not data` or `if not data.get('metadata')` before access

agent-workspace/domain-skills/articulate-rise/code-blocks.md

  • Network accessline 8
    authoring  https://rise.{instance}.articulate.com/authoring/{courseId}/lesson/{lessonId}
  • Network accessline 9
    preview    https://rise.{instance}.articulate.com/preview/{courseId}#/lessons/{lessonId}
  • Network accessline 135
    for (const rule of sheet.cssRules || []) {          if (rule instanceof CSSFontFaceRule && /YourFontName/i.test(rule.cssText)) {            console.log(rule.cssText);  // → src: url('https://articulateusercontent.eu/rise/fonts/...')
  • Network accessline 136
    if (rule instanceof CSSFontFaceRule && /YourFontName/i.test(rule.cssText)) {            console.log(rule.cssText);  // → src: url('https://articulateusercontent.eu/rise/fonts/...')          }
  • Network accessline 137
    console.log(rule.cssText);  // → src: url('https://articulateusercontent.eu/rise/fonts/...')
  • Network accessline 149
    @font-face {      font-family: 'YourFontName';      src: url('https://articulateusercontent.eu/rise/fonts/{hash}.woff') format('woff');
  • Network accessline 150
    font-family: 'YourFontName';      src: url('https://articulateusercontent.eu/rise/fonts/{hash}.woff') format('woff');      font-weight: 400;
  • Network accessline 151
    src: url('https://articulateusercontent.eu/rise/fonts/{hash}.woff') format('woff');

agent-workspace/domain-skills/arxiv-bulk/scraping.md

  • Network accessline 18
    https://oaipmh.arxiv.org/oai
  • Network accessline 21
    `https://export.arxiv.org/oai2` is the old URL — it 301-redirects to the new one. Use the new URL directly to avoid the extra round-trip.
  • Network accessline 29
    OAI_NS = {     'oai': 'http://www.openarchives.org/OAI/2.0/',
  • Network accessline 30
    'oai': 'http://www.openarchives.org/OAI/2.0/',
  • Network accessline 31
    'arXiv': 'http://arxiv.org/OAI/arXiv/',
  • Network accessline 72
    BASE = 'https://oaipmh.arxiv.org/oai'
  • Network accessline 142
    RAW_NS = {     'oai': 'http://www.openarchives.org/OAI/2.0/',
  • Network accessline 143
    'oai': 'http://www.openarchives.org/OAI/2.0/',
  • Network accessline 144
    'raw': 'http://arxiv.org/OAI/arXivRaw/',
  • Network accessline 147
    xml = http_get(     "https://oaipmh.arxiv.org/oai"
  • Network accessline 148
    "https://oaipmh.arxiv.org/oai"
  • Network accessline 175
    Base URL: `https://api.semanticscholar.org/graph/v1/`
  • Network accessline 183
    paper = json.loads(http_get(     "https://api.semanticscholar.org/graph/v1/paper/arXiv:1706.03762"
  • Network accessline 184
    "https://api.semanticscholar.org/graph/v1/paper/arXiv:1706.03762"
  • Network accessline 210
    body = json.dumps({"ids": ids}).encode() req = urllib.request.Request(
  • Network accessline 211
    req = urllib.request.Request(
  • Network accessline 212
    f"https://api.semanticscholar.org/graph/v1/paper/batch?fields={fields}",
  • Network accessline 215
    method="POST", ) with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 216
    ) with urllib.request.urlopen(req, timeout=20) as r:     results = json.loads(r.read())
  • Network accessline 217
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 228
    Note: `helpers.http_get` only does GET. For POST use `urllib.request.Request` directly as above.
  • Network accessline 236
    results = json.loads(http_get(     "https://api.semanticscholar.org/graph/v1/paper/search"
  • Network accessline 237
    "https://api.semanticscholar.org/graph/v1/paper/search"
  • Network accessline 282
    if 'v' not in arxiv_id.split('.')[-1] and version:         arxiv_id = f"{arxiv_id}v{version}"     url = f"https://arxiv.org/pdf/{arxiv_id}"
  • Network accessline 283
    arxiv_id = f"{arxiv_id}v{version}"     url = f"https://arxiv.org/pdf/{arxiv_id}"     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 284
    url = f"https://arxiv.org/pdf/{arxiv_id}"     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})     with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 285
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 286
    with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 300
    - **OAI-PMH endpoint moved.** `https://export.arxiv.org/oai2` 301-redirects to `https://oaipmh.arxiv.org/oai`. Use the new URL. `helpers.http_get` (which uses `urllib`) does NOT follow redirects — you'll get an empty string or error. Either
  • Network accessline 320
    - **`http_get` in helpers.py does NOT follow HTTP redirects.** If you must use it with the old OAI URL, you'll get an empty body. Either update the URL to the canonical one or use `urllib.request.urlopen` with a redirect handler.

agent-workspace/domain-skills/arxiv/scraping.md

  • Network accessline 3
    `https://arxiv.org` — open-access preprint server. **Never use the browser for ArXiv.** All data is reachable via `http_get` using the Atom API or HTML meta tags. No API key required.
  • Network accessline 13
    NS = {'atom': 'http://www.w3.org/2005/Atom', 'arxiv': 'http://arxiv.org/schemas/atom'}
  • Network accessline 15
    xml = http_get("http://export.arxiv.org/api/query?search_query=ti:transformer+AND+cat:cs.LG&max_results=5&sortBy=submittedDate&sortOrder=descending")
  • Network accessline 22
    Use `http_get` on `https://arxiv.org/abs/{id}` + regex for `citation_*` meta tags when you need the full abstract from an HTML page.
  • Network accessline 32
    NS = {'atom': 'http://www.w3.org/2005/Atom', 'arxiv': 'http://arxiv.org/schemas/atom'}
  • Network accessline 34
    xml = http_get(     "http://export.arxiv.org/api/query"
  • Network accessline 35
    "http://export.arxiv.org/api/query"
  • Network accessline 57
    # 2604.15259v1 2026-04-16 Stability and Generalization in Looped Transformers #   Authors: ['Asher Labovich'] #   PDF: https://arxiv.org/pdf/2604.15259v1
  • Network accessline 59
    #   PDF: https://arxiv.org/pdf/2604.15259v1
  • Network accessline 68
    NS = {'atom': 'http://www.w3.org/2005/Atom', 'arxiv': 'http://arxiv.org/schemas/atom'}
  • Network accessline 70
    xml = http_get("http://export.arxiv.org/api/query?id_list=1706.03762")
  • Network accessline 82
    # Title: Attention Is All You Need # Categories: ['cs.CL', 'cs.LG'] # PDF: https://arxiv.org/pdf/1706.03762v7
  • Network accessline 83
    # Categories: ['cs.CL', 'cs.LG'] # PDF: https://arxiv.org/pdf/1706.03762v7 # Abstract: The dominant sequence transduction models are based on complex recurrent...
  • Network accessline 84
    # PDF: https://arxiv.org/pdf/1706.03762v7
  • Network accessline 96
    NS = {'atom': 'http://www.w3.org/2005/Atom'}
  • Network accessline 98
    ids = ['1706.03762', '1810.04805', '2005.14165']  # Transformer, BERT, GPT-3 xml = http_get(f"http://export.arxiv.org/api/query?id_list={','.join(ids)}&max_results={len(ids)}")
  • Network accessline 99
    xml = http_get(f"http://export.arxiv.org/api/query?id_list={','.join(ids)}&max_results={len(ids)}")
  • Network accessline 114
    ### Parallel fetch (ThreadPoolExecutor for independent IDs)
  • Network accessline 123
    NS = {'atom': 'http://www.w3.org/2005/Atom'}
  • Network accessline 125
    def fetch_paper(arxiv_id):     xml = http_get(f"http://export.arxiv.org/api/query?id_list={arxiv_id}")
  • Network accessline 126
    xml = http_get(f"http://export.arxiv.org/api/query?id_list={arxiv_id}")
  • Network accessline 153
    html = http_get("https://arxiv.org/abs/1706.03762", headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 168
    # Confirmed output for 1706.03762: # Title: Attention Is All You Need # PDF: https://arxiv.org/pdf/1706.03762   (no version suffix — always latest)
  • Network accessline 169
    # Title: Attention Is All You Need # PDF: https://arxiv.org/pdf/1706.03762   (no version suffix — always latest) # Authors: ['Vaswani, Ashish', 'Shazeer, Noam', 'Parmar, Niki']
  • Network accessline 170
    # PDF: https://arxiv.org/pdf/1706.03762   (no version suffix — always latest)
  • Network accessline 191
    NS = {     'atom': 'http://www.w3.org/2005/Atom',
  • Network accessline 192
    'atom': 'http://www.w3.org/2005/Atom',
  • Network accessline 193
    'opensearch': 'http://a9.com/-/spec/opensearch/1.1/',
  • Network accessline 196
    # Page 1 xml = http_get(     "http://export.arxiv.org/api/query"
  • Network accessline 197
    xml = http_get(     "http://export.arxiv.org/api/query"     "?search_query=cat:cs.AI"
  • Network accessline 198
    "http://export.arxiv.org/api/query"
  • Network accessline 210
    # Page 2: increment start xml2 = http_get(     "http://export.arxiv.org/api/query"
  • Network accessline 211
    xml2 = http_get(     "http://export.arxiv.org/api/query"     "?search_query=cat:cs.AI"
  • Network accessline 212
    "http://export.arxiv.org/api/query"
  • Network accessline 223
    http://export.arxiv.org/api/query
  • Network accessline 226
    HTTPS also works: `https://export.arxiv.org/api/query`
  • Network accessline 259
    pdf_versioned   = f"https://arxiv.org/pdf/{arxiv_id}"   # specific version
  • Network accessline 260
    pdf_latest      = f"https://arxiv.org/pdf/{bare_id}"    # always redirects to latest
  • Network accessline 261
    abs_versioned   = f"https://arxiv.org/abs/{arxiv_id}"
  • Network accessline 262
    abs_latest      = f"https://arxiv.org/abs/{bare_id}"
  • Network accessline 281
    Full category taxonomy: https://arxiv.org/category_taxonomy
  • Network accessline 287
    - **Always define the namespace dict.** Without `NS = {'atom': 'http://www.w3.org/2005/Atom', 'arxiv': 'http://arxiv.org/schemas/atom'}`, `findall('atom:entry')` silently returns `[]`. All ArXiv Atom elements live in the `http://www.w3.org/
  • Network accessline 291
    - **`atom:id` contains a URL, not a bare ID.** The element text is `http://arxiv.org/abs/1706.03762v7` — always split on `/` and take `[-1]` to get the bare ID with version. Strip version with `re.sub(r'v\d+$', '', id)` if needed.

agent-workspace/domain-skills/atlas/overview.md

  • Network accessline 51
    POST `https://my.recruitwithatlas.com/graphql` using the tab's own cookies:
  • Network accessline 54
    js(""" fetch('/graphql', {
  • Network accessline 55
    fetch('/graphql', {

agent-workspace/domain-skills/bbb/scraping.md

  • Network accessline 54
    if not all(SLUG.match(p) for p in parts):         raise ValueError("slugs must be lowercase-hyphenated, e.g. 'san-francisco', 'plumber'")     url = "https://www.bbb.org/" + "/".join(parts) + ("/accredited" if accredited else "")
  • Network accessline 55
    raise ValueError("slugs must be lowercase-hyphenated, e.g. 'san-francisco', 'plumber'")     url = "https://www.bbb.org/" + "/".join(parts) + ("/accredited" if accredited else "")     if not bbb_open(url):
  • Network accessline 56
    url = "https://www.bbb.org/" + "/".join(parts) + ("/accredited" if accredited else "")
  • Network accessline 83
    "primary_category": r.get("tobText"),             "categories": [c["name"] for c in r.get("categories") or []],             "profile_url": "https://www.bbb.org" + r["reportUrl"],
  • Network accessline 84
    "categories": [c["name"] for c in r.get("categories") or []],             "profile_url": "https://www.bbb.org" + r["reportUrl"],         })
  • Network accessline 85
    "profile_url": "https://www.bbb.org" + r["reportUrl"],
  • Network accessline 146
    "Tankless Water Heaters"  ],  "profile_url": "https://www.bbb.org/us/ca/san-francisco/profile/plumber/atlas-plumbing-rooter-1116-116593"
  • Network accessline 147
    ],  "profile_url": "https://www.bbb.org/us/ca/san-francisco/profile/plumber/atlas-plumbing-rooter-1116-116593" }
  • Network accessline 148
    "profile_url": "https://www.bbb.org/us/ca/san-francisco/profile/plumber/atlas-plumbing-rooter-1116-116593"
  • Network accessline 186
    # Profile URLs end in <bbbId>-<businessId>; BBB redirects stale name/city/category slugs to the canonical URL. PROFILE = re.compile(r"^https://www\.bbb\.org/(?:us|ca)/[a-z]{2}/[a-z0-9-]+/profile/[a-z0-9-]+/[a-z0-9-]*-(\d{4}-\d+)/?$")
  • Network accessline 187
    PROFILE = re.compile(r"^https://www\.bbb\.org/(?:us|ca)/[a-z]{2}/[a-z0-9-]+/profile/[a-z0-9-]+/[a-z0-9-]*-(\d{4}-\d+)/?$")
  • Network accessline 252
    print(json.dumps(bbb_profile("https://www.bbb.org/us/ny/new-york/profile/telephones/verizon-communications-0011-1568"), indent=1))
  • Network accessline 253
    time.sleep(3) moved = bbb_profile("https://www.bbb.org/us/ca/oakland/profile/plumber/atlas-plumbing-rooter-1116-116593") print("redirected:", moved["requested_url"], "->", moved["profile_url"])
  • Network accessline 254
    moved = bbb_profile("https://www.bbb.org/us/ca/oakland/profile/plumber/atlas-plumbing-rooter-1116-116593")
  • Network accessline 261
    Atlas Plumbing & Rooter            A+  acc=True  complaints_3y=1 12m=0 reviews=1 site=https://www.atlasplumbingandrooter.com
  • Network accessline 262
    A G Quality Plumbing               A+  acc=True  complaints_3y=0 12m=0 reviews=1 site=https://www.agqualityplumbing.com/
  • Network accessline 263
    Jimenez Construction               A+  acc=True  complaints_3y=0 12m=0 reviews=1 site=https://jimenezconstructionsf.com/
  • Network accessline 264
    J. E. Brown Mechanical Co., Inc.   A+  acc=True  complaints_3y=0 12m=0 reviews=0 site=None Mr. Rooter Plumbing of San Francis A+  acc=True  complaints_3y=0 12m=0 reviews=0 site=https://www.mrrooter.com/san-francisco/ PARTIAL: enriched 5 of 
  • Network accessline 265
    Mr. Rooter Plumbing of San Francis A+  acc=True  complaints_3y=0 12m=0 reviews=0 site=https://www.mrrooter.com/san-francisco/
  • Network accessline 266
    PARTIAL: enriched 5 of 61 rows (LIMIT=5) {  "requested_url": "https://www.bbb.org/us/ny/new-york/profile/telephones/verizon-communications-0011-1568",
  • Network accessline 267
    {  "requested_url": "https://www.bbb.org/us/ny/new-york/profile/telephones/verizon-communications-0011-1568",  "profile_url": "https://www.bbb.org/us/ny/new-york/profile/telephones/verizon-communications-0011-1568",
  • Network accessline 268
    "requested_url": "https://www.bbb.org/us/ny/new-york/profile/telephones/verizon-communications-0011-1568",
  • Network accessline 269
    "profile_url": "https://www.bbb.org/us/ny/new-york/profile/telephones/verizon-communications-0011-1568",
  • Network accessline 275
    "reviews": 718,  "avg_stars": 1.1,  "website": "https://www.verizon.com/",
  • Network accessline 276
    "avg_stars": 1.1,  "website": "https://www.verizon.com/",  "phone": "(800) 779-4116",
  • Network accessline 277
    "website": "https://www.verizon.com/",
  • Network accessline 281
    "jsonld_accreditation": "Not BBB Accredited" } redirected: https://www.bbb.org/us/ca/oakland/profile/plumber/atlas-plumbing-rooter-1116-116593 -> https://www.bbb.org/us/ca/san-francisco/profile/plumber/atlas-plumbing-rooter-1116-116593
  • Network accessline 283
    redirected: https://www.bbb.org/us/ca/oakland/profile/plumber/atlas-plumbing-rooter-1116-116593 -> https://www.bbb.org/us/ca/san-francisco/profile/plumber/atlas-plumbing-rooter-1116-116593
  • Network accessline 291
    import http.client, re, time, urllib.error, urllib.request
  • Network accessline 296
    def fetch(url, tries=3):
  • Network accessline 300
    attempt += 1         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 301
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=min(WAIT_S, deadline - time.monotonic())) as r:
  • Network accessline 302
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 303
    with urllib.request.urlopen(req, timeout=min(WAIT_S, deadline - time.monotonic())) as r:
  • Network accessline 314
    raise RuntimeError(f"{url}: HTTP {e.code}; not retrying") from e             err = e  # 5xx: retry         except (OSError, http.client.HTTPException) as e:
  • Network accessline 315
    err = e  # 5xx: retry         except (OSError, http.client.HTTPException) as e:             err = e  # network error or timeout: retry; decode and other errors propagate at once
  • Network accessline 316
    except (OSError, http.client.HTTPException) as e:
  • Network accessline 324
    def state_category_slugs(state):     idx = fetch("https://www.bbb.org/sitemap-us-state-categories-index.xml")
  • Network accessline 325
    idx = fetch("https://www.bbb.org/sitemap-us-state-categories-index.xml")
  • Network accessline 329
    slugs, seen_state = [], False     for sm in files:         locs = re.findall(r"<loc>https://www\.bbb\.org/us/([a-z]{2})/category/([^<]+)</loc>", fetch(sm))
  • Network accessline 330
    for sm in files:         locs = re.findall(r"<loc>https://www\.bbb\.org/us/([a-z]{2})/category/([^<]+)</loc>", fetch(sm))         if not locs:
  • Network accessline 331
    locs = re.findall(r"<loc>https://www\.bbb\.org/us/([a-z]{2})/category/([^<]+)</loc>", fetch(sm))
  • Network accessline 368
    | `primary_category` | `tobText` | BBB's main "type of business" for the row | | `categories` | `categories[].name` | BBB "type of business" names | | `profile_url` | `reportUrl` | relative path, prefix `https://www.bbb.org`; required; dedu
  • Network accessline 369
    | `categories` | `categories[].name` | BBB "type of business" names | | `profile_url` | `reportUrl` | relative path, prefix `https://www.bbb.org`; required; dedupe key (the same profile appeared twice in one listing with different `id`s) | 
  • Network accessline 370
    | `profile_url` | `reportUrl` | relative path, prefix `https://www.bbb.org`; required; dedupe key (the same profile appeared twice in one listing with different `id`s) |

agent-workspace/domain-skills/best-buy/scraping.md

  • Dangerous shell operationline 37
    const rm = rnr.match(/rating,? ([\d.]+) out of 5 stars with ([\d,]+) review/i);
  • Dangerous shell operationline 54
    rating: rm ? parseFloat(rm[1]) : null,
  • Dangerous shell operationline 55
    review_count: rm ? parseInt(rm[2].replace(/,/g, ''), 10) : (/Not yet reviewed/i.test(card.innerText) ? 0 : null),
  • Network accessline 117
    if page not in ROBOTS_PAGES:         raise ValueError(f"page {page}: robots.txt disallows cp={page} for User-agent: *")     url = f"https://www.bestbuy.com/site/searchpage.jsp?st={quote_plus(query)}"
  • Network accessline 118
    raise ValueError(f"page {page}: robots.txt disallows cp={page} for User-agent: *")     url = f"https://www.bestbuy.com/site/searchpage.jsp?st={quote_plus(query)}"     return url if page == 1 else f"{url}&cp={page}"
  • Network accessline 119
    url = f"https://www.bestbuy.com/site/searchpage.jsp?st={quote_plus(query)}"
  • Network accessline 245
    112 unique products; Counter({'in_stock': 110, 'sold_out': 1, 'unavailable': 1}) {"sku": "6687893", "title": "HP - Googlebook 14\" 3K OLED Touchscreen - Snapdragon X Elite - 16GB Memory - 512GB SSD - Atmospheric Blue",  "url": "https://www.
  • Network accessline 246
    {"sku": "6687893", "title": "HP - Googlebook 14\" 3K OLED Touchscreen - Snapdragon X Elite - 16GB Memory - 512GB SSD - Atmospheric Blue",  "url": "https://www.bestbuy.com/product/hp-googlebook-14-3k-oled-touchscreen-snapdragon-x-elite-16gb-
  • Network accessline 247
    "url": "https://www.bestbuy.com/product/hp-googlebook-14-3k-oled-touchscreen-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893",
  • Network accessline 389
    def get_product(sku):     # /site/<sku>.p?skuId=<sku> redirects to the canonical /product/<slug>/<code> URL     nav(f"https://www.bestbuy.com/site/{sku}.p?skuId={sku}",
  • Network accessline 390
    # /site/<sku>.p?skuId=<sku> redirects to the canonical /product/<slug>/<code> URL     nav(f"https://www.bestbuy.com/site/{sku}.p?skuId={sku}",         lambda h: urlparse(h).netloc == "www.bestbuy.com" and urlparse(h).path.startswith("/produ
  • Network accessline 391
    nav(f"https://www.bestbuy.com/site/{sku}.p?skuId={sku}",
  • Network accessline 449
    ensure_visible() # Pick a SKU from a live search so this block does not depend on a hard-coded product. nav("https://www.bestbuy.com/site/searchpage.jsp?st=laptop",
  • Network accessline 450
    # Pick a SKU from a live search so this block does not depend on a hard-coded product. nav("https://www.bestbuy.com/site/searchpage.jsp?st=laptop",     lambda h: urlparse(h).path == "/site/searchpage.jsp" and parse_qs(urlparse(h).query).get
  • Network accessline 451
    nav("https://www.bestbuy.com/site/searchpage.jsp?st=laptop",
  • Network accessline 488
    "title": "HP - 14\" Laptop - Intel N150 Processor - 4GB Memory - 128GB Storage - Pale Rose Gold",  "brand": "HP", "model": "14-dq6105dx",  "url": "https://www.bestbuy.com/product/hp-14-laptop-intel-n150-processor-4gb-memory-128gb-storage-pa
  • Network accessline 489
    "brand": "HP", "model": "14-dq6105dx",  "url": "https://www.bestbuy.com/product/hp-14-laptop-intel-n150-processor-4gb-memory-128gb-storage-pale-rose-gold/JJGW3FGF9T",  "price": 209.99, "price_block_price": 209.99, "regular_price": 349.99, "
  • Network accessline 490
    "url": "https://www.bestbuy.com/product/hp-14-laptop-intel-n150-processor-4gb-memory-128gb-storage-pale-rose-gold/JJGW3FGF9T",
  • Network accessline 547
    - **Lazy price blocks.** One top-to-bottom scroll left some cards unpriced; scrolling each unpriced card into view filled them in (24 of 24 on pages 2 and 3). The retry includes "Unavailable" and "Sold Out" cards, which do get a price block
  • Network accessline 548
    - **Hydration order on product pages.** JSON-LD is there first; the main price block and `_BBY_DATA_.skus` arrive later (the `isPDP` entry took 12-18 s in one trace, and once did not appear within 20 s). A "See all specifications" click bef
  • Network accessline 549
    - **Card shells mean the product API is failing.** In 2 fresh cloud browsers on 2026-10-23, page 1 of `gaming laptop` loaded but 17 and 15 of its 24 cards stayed shells: an `h3` with no title, a link with no `href`, "Not Yet Reviewed", "See
  • Network accessline 560
    - `http_get`, curl or urllib against `www.bestbuy.com` search or product pages: no response before timeout, so plain HTTP is blocked; this skill uses a normal browser session.
  • Network accessline 561
    [Credential-related source omitted]

agent-workspace/domain-skills/bigbang-hr/checkout.md

  • Network accessline 7
    - Homepage: `https://www.bigbang.hr`
  • Network accessline 8
    - Product: `https://www.bigbang.hr/webshop/<slug>/<sku>`
  • Network accessline 9
    - Cart: `https://www.bigbang.hr/webshop/kosarica/`
  • Network accessline 10
    - Checkout: `https://www.bigbang.hr/webshop/kupac/` (all 3 steps live on this URL — SPA routing)

agent-workspace/domain-skills/bilbasen/search.md

  • Network accessline 7
    - **Plain HTTP is blocked.** `http_get` / `curl` with a full Chrome UA returns **HTTP 202 with an empty body** (JS bot challenge). Use the user's real browser. - **Search result pages embed every listing on the page as JSON** in `<script id
  • Network accessline 8
    - **Search result pages embed every listing on the page as JSON** in `<script id="__NEXT_DATA__">` (Next.js SSR). No need to scrape cards or scroll. - Search URL pattern: `https://www.bilbasen.dk/brugt/bil/<make>/<model>?pricefrom=<int>&pri
  • Network accessline 9
    - Search URL pattern: `https://www.bilbasen.dk/brugt/bil/<make>/<model>?pricefrom=<int>&priceto=<int>`. Make/model slugs are lowercase (`vw`, `id.4`). The site 302s to an internal model id (`/brugt/bil/vw/id2314`) and appends `includeengros
  • Network accessline 18
    import json new_tab("https://www.bilbasen.dk/brugt/bil/vw/id.4?pricefrom=150000&priceto=195000")
  • Network accessline 19
    new_tab("https://www.bilbasen.dk/brugt/bil/vw/id.4?pricefrom=150000&priceto=195000")
  • Network accessline 36
    |---|---|---| | `externalId` | `6999185` | listing id, also last path segment of `uri` | | `uri` | `https://www.bilbasen.dk/brugt/bil/vw/id4/52-pure-5d/6999185` | detail page |
  • Network accessline 37
    | `externalId` | `6999185` | listing id, also last path segment of `uri` | | `uri` | `https://www.bilbasen.dk/brugt/bil/vw/id4/52-pure-5d/6999185` | detail page | | `price.price` | `169900` | int DKK, use for math; `price.displayPrice` is f
  • Network accessline 38
    | `uri` | `https://www.bilbasen.dk/brugt/bil/vw/id4/52-pure-5d/6999185` | detail page |

agent-workspace/domain-skills/bilibili/navigation.md

  • Network accessline 12
    | Page | URL | |------|-----| | Home (recommended feed) | `https://www.bilibili.com/` |
  • Network accessline 13
    |------|-----| | Home (recommended feed) | `https://www.bilibili.com/` | | Dynamics (following feed) | `https://t.bilibili.com/` |
  • Network accessline 14
    | Home (recommended feed) | `https://www.bilibili.com/` |
  • Network accessline 15
    | Dynamics (following feed) | `https://t.bilibili.com/` |
  • Network accessline 16
    | Personal space | `https://space.bilibili.com/{UID}` |
  • Network accessline 17
    | Watch history | `https://www.bilibili.com/account/history` |
  • Network accessline 18
    | Watch later | `https://www.bilibili.com/watchlater/#/list` |
  • Network accessline 19
    | Messages | `https://message.bilibili.com/` |
  • Network accessline 20
    | Search | `https://search.bilibili.com/all?keyword={QUERY}` |
  • Network accessline 24
    | Page | URL | |------|-----| | Home (videos + favorites) | `https://space.bilibili.com/{UID}` |
  • Network accessline 25
    |------|-----| | Home (videos + favorites) | `https://space.bilibili.com/{UID}` | | Dynamics (user activity) | `https://space.bilibili.com/{UID}/dynamic` |
  • Network accessline 26
    | Home (videos + favorites) | `https://space.bilibili.com/{UID}` |
  • Network accessline 27
    | Dynamics (user activity) | `https://space.bilibili.com/{UID}/dynamic` |
  • Network accessline 28
    | Uploads | `https://space.bilibili.com/{UID}/upload` |
  • Network accessline 29
    | Collections & series | `https://space.bilibili.com/{UID}/lists` |
  • Network accessline 30
    | Favorites | `https://space.bilibili.com/{UID}/favlist` |
  • Network accessline 31
    | Bangumi tracking | `https://space.bilibili.com/{UID}/bangumi` |
  • Network accessline 32
    | Settings | `https://space.bilibili.com/{UID}/settings` |
  • Network accessline 36
    | Page | URL | |------|-----| | Popular / Hot | `https://www.bilibili.com/v/popular/all` |
  • Network accessline 37
    |------|-----| | Popular / Hot | `https://www.bilibili.com/v/popular/all` | | Weekly must-watch | `https://www.bilibili.com/v/popular/weekly?num={ISSUE}` |
  • Network accessline 38
    | Popular / Hot | `https://www.bilibili.com/v/popular/all` |
  • Network accessline 39
    | Weekly must-watch | `https://www.bilibili.com/v/popular/weekly?num={ISSUE}` |
  • Network accessline 40
    | All-time classics | `https://www.bilibili.com/v/popular/all` (入站必刷 tab) |
  • Network accessline 41
    | Ranking (all) | `https://www.bilibili.com/v/popular/rank/all` |
  • Network accessline 42
    | Topics | `https://www.bilibili.com/v/topic/` |
  • Network accessline 46
    | Aspect | Pattern | |--------|---------| | Watch URL | `https://www.bilibili.com/video/{BV_ID}` |
  • Network accessline 47
    |--------|---------| | Watch URL | `https://www.bilibili.com/video/{BV_ID}` | | BV format | `BV` prefix + 10 alphanumeric chars, e.g. `BV1HeRKBdEoX` |
  • Network accessline 48
    | Watch URL | `https://www.bilibili.com/video/{BV_ID}` |
  • Network accessline 54
    | Page | URL | |------|-----| | Anime | `https://www.bilibili.com/anime/` |
  • Network accessline 55
    |------|-----| | Anime | `https://www.bilibili.com/anime/` | | Movie | `https://www.bilibili.com/movie/` |
  • Network accessline 56
    | Anime | `https://www.bilibili.com/anime/` |
  • Network accessline 57
    | Movie | `https://www.bilibili.com/movie/` |
  • Network accessline 58
    | TV series | `https://www.bilibili.com/tv/` |
  • Network accessline 59
    | Documentary | `https://www.bilibili.com/documentary/` |
  • Network accessline 60
    | Variety show | `https://www.bilibili.com/variety/` |
  • Network accessline 61
    | Chinese animation | `https://www.bilibili.com/guochuang/` |
  • Network accessline 62
    | Read (articles/blogs) | `https://www.bilibili.com/read/home` |
  • Network accessline 63
    | Audio / Music | `https://www.bilibili.com/audio/home` |
  • Network accessline 64
    | Courses (课堂) | `https://www.bilibili.com/cheese/` |
  • Network accessline 65
    | Live | `https://live.bilibili.com/` |
  • Network accessline 66
    | Game center | `https://game.bilibili.com/platform` |
  • Network accessline 67
    | Manga (漫画) | `https://manga.bilibili.com/` |
  • Network accessline 68
    | Mall (会员购) | `https://show.bilibili.com/platform/home.html` |
  • Network accessline 69
    | Esports / Matches | `https://www.bilibili.com/match/home/` |
  • Network accessline 73
    | Page | URL | |------|-----| | Creator center | `https://member.bilibili.com/platform/home` |
  • Network accessline 74
    |------|-----| | Creator center | `https://member.bilibili.com/platform/home` | | Upload video | `https://member.bilibili.com/platform/upload/video/frame` |
  • Network accessline 75
    | Creator center | `https://member.bilibili.com/platform/home` |
  • Network accessline 76
    | Upload video | `https://member.bilibili.com/platform/upload/video/frame` |
  • Network accessline 80
    | Page | URL | |------|-----| | Premium (大会员) | `https://account.bilibili.com/big` |
  • Network accessline 81
    |------|-----| | Premium (大会员) | `https://account.bilibili.com/big` | | Blackroom (bans) | `https://www.bilibili.com/blackroom/ban` |
  • Network accessline 82
    | Premium (大会员) | `https://account.bilibili.com/big` |
  • Network accessline 83
    | Blackroom (bans) | `https://www.bilibili.com/blackroom/ban` |
  • Network accessline 126
    | 动态 | `t.bilibili.com` | Following feed — most important for daily use | | 收藏 | `space.bilibili.com/{UID}/favlist` | Favorite folders | | 历史 | `https://www.bilibili.com/account/history` | Watch history |
  • Network accessline 127
    | 收藏 | `space.bilibili.com/{UID}/favlist` | Favorite folders | | 历史 | `https://www.bilibili.com/account/history` | Watch history | | 创作中心 | `member.bilibili.com/platform/home` | Creator dashboard |
  • Network accessline 128
    | 历史 | `https://www.bilibili.com/account/history` | Watch history |

agent-workspace/domain-skills/bluesky/scraping.md

  • Network accessline 3
    Field-tested against bsky.app and public.api.bsky.app on 2026-10-31 using a Browser Use cloud browser (logged out; API calls made with `fetch()` from a bsky.app tab) and plain Python urllib.
  • Network accessline 9
    - **No scraping needed.** Logged out, bsky.app itself loads profiles and feeds from `https://public.api.bsky.app/xrpc/<method>` (seen in the tab's resource list: `app.bsky.actor.getProfile`, `app.bsky.feed.getAuthorFeed`, `com.atproto.ident
  • Network accessline 13
    - **Thread for a post URL** (`app.bsky.feed.getPostThread`): the post plus its replies; a handle works inside the `at://` URI. - **Post search does not work logged out.** `app.bsky.feed.searchPosts` returns HTTP 403 from the CDN (plain HTTP
  • Network accessline 15
    - Bluesky's docs (https://bsky.network/docs/rate-limits, fetched 2026-10-31) ask "public web" use cases to use the cached public.api.bsky.app host and call its limits "generous". The blocks pause 0.5 s between calls; about 100 calls today (
  • Network accessline 19
    All browser blocks share the same helpers: `on_bsky_tab()` attaches a bsky.app tab once (later blocks reuse it), and `xrpc()` runs `fetch()` in that tab. It returns parsed JSON on 200, raises `LookupError` on an XRPC 400 (`Profile not found
  • Network accessline 28
    API = "https://public.api.bsky.app/xrpc/"
  • Network accessline 43
    """Fetches run inside a logged-out bsky.app tab; reuse it if the attached tab is already there."""     try:         if js("location.origin") == "https://bsky.app":
  • Network accessline 44
    try:         if js("location.origin") == "https://bsky.app":             return
  • Network accessline 45
    if js("location.origin") == "https://bsky.app":
  • Network accessline 47
    except Exception:         pass     new_tab("https://bsky.app/")
  • Network accessline 48
    pass     new_tab("https://bsky.app/")     wait_for_load()
  • Network accessline 49
    new_tab("https://bsky.app/")
  • Network accessline 52
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 53
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 82
    def profile_row(p):     base = {"handle": p["handle"], "did": p["did"], "url": f"https://bsky.app/profile/{p['handle']}"}
  • Network accessline 83
    base = {"handle": p["handle"], "did": p["did"], "url": f"https://bsky.app/profile/{p['handle']}"}
  • Network accessline 123
    "handle": "bsky.app",   "did": "did:plc:z72i7hdynmk6r22z27h6tvur",   "url": "https://bsky.app/profile/bsky.app",
  • Network accessline 124
    "did": "did:plc:z72i7hdynmk6r22z27h6tvur",   "url": "https://bsky.app/profile/bsky.app",   "display_name": "Bluesky",
  • Network accessline 125
    "url": "https://bsky.app/profile/bsky.app",   "display_name": "Bluesky",   "bio": "official Bluesky account (check username👆)\n\nBugs, feature requests, feedback: [email]",
  • Network accessline 134
    "labels": [],   "pinned_post": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l",   "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsi
  • Network accessline 135
    "pinned_post": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3l6oveex3ii2l",   "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka"  },
  • Network accessline 136
    "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:z72i7hdynmk6r22z27h6tvur/bafkreihwihm6kpd6zuwhhlro75p5qks5qtrcu55jp3gddbfjsieiv7wuka"
  • Network accessline 139
    "handle": "atproto.com",   "did": "did:plc:ewvi7nxzyoun6zhxrhs64oiz",   "url": "https://bsky.app/profile/atproto.com",
  • Network accessline 140
    "did": "did:plc:ewvi7nxzyoun6zhxrhs64oiz",   "url": "https://bsky.app/profile/atproto.com",   "display_name": "AT Protocol Developers",
  • Network accessline 141
    "url": "https://bsky.app/profile/atproto.com",
  • Network accessline 150
    "labels": [],   "pinned_post": null,   "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:ewvi7nxzyoun6zhxrhs64oiz/bafkreiaihtwfr2d6mjfb6drzaze2gubqtst4ymiwxowqfxpsqxpnz2t33u"
  • Network accessline 151
    "pinned_post": null,   "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:ewvi7nxzyoun6zhxrhs64oiz/bafkreiaihtwfr2d6mjfb6drzaze2gubqtst4ymiwxowqfxpsqxpnz2t33u"  }
  • Network accessline 152
    "avatar": "https://cdn.bsky.app/img/avatar/plain/did:plc:ewvi7nxzyoun6zhxrhs64oiz/bafkreiaihtwfr2d6mjfb6drzaze2gubqtst4ymiwxowqfxpsqxpnz2t33u"
  • Network accessline 167
    API = "https://public.api.bsky.app/xrpc/"
  • Network accessline 183
    """Fetches run inside a logged-out bsky.app tab; reuse it if the attached tab is already there."""     try:         if js("location.origin") == "https://bsky.app":
  • Network accessline 184
    try:         if js("location.origin") == "https://bsky.app":             return
  • Network accessline 185
    if js("location.origin") == "https://bsky.app":
  • Network accessline 187
    except Exception:         pass     new_tab("https://bsky.app/")
  • Network accessline 188
    pass     new_tab("https://bsky.app/")     wait_for_load()
  • Network accessline 189
    new_tab("https://bsky.app/")
  • Network accessline 192
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 193
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 218
    def post_url(uri, handle):     """at://<did>/app.bsky.feed.post/<rkey> -> https://bsky.app/profile/<handle>/post/<rkey>"""
  • Network accessline 219
    """at://<did>/app.bsky.feed.post/<rkey> -> https://bsky.app/profile/<handle>/post/<rkey>"""
  • Network accessline 220
    return f"https://bsky.app/profile/{handle}/post/{uri.rsplit('/', 1)[-1]}"
  • Network accessline 294
    {   "kind": "post",   "url": "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o",
  • Network accessline 295
    "kind": "post",   "url": "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o",   "uri": "at://did:plc:ewvi7nxzyoun6zhxrhs64oiz/app.bsky.feed.post/3mz4m677rsc2o",
  • Network accessline 296
    "url": "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o",
  • Network accessline 334
    API = "https://public.api.bsky.app/xrpc/"
  • Network accessline 349
    """Fetches run inside a logged-out bsky.app tab; reuse it if the attached tab is already there."""     try:         if js("location.origin") == "https://bsky.app":
  • Network accessline 350
    try:         if js("location.origin") == "https://bsky.app":             return
  • Network accessline 351
    if js("location.origin") == "https://bsky.app":
  • Network accessline 353
    except Exception:         pass     new_tab("https://bsky.app/")
  • Network accessline 354
    pass     new_tab("https://bsky.app/")     wait_for_load()
  • Network accessline 355
    new_tab("https://bsky.app/")
  • Network accessline 358
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 359
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 401
    "verified": (a.get("verification") or {}).get("verifiedStatus") == "valid",             "labels": sorted({l["val"] for l in a.get("labels", [])}),             "url": f"https://bsky.app/profile/{a['handle']}",
  • Network accessline 402
    "labels": sorted({l["val"] for l in a.get("labels", [])}),             "url": f"https://bsky.app/profile/{a['handle']}",         })
  • Network accessline 403
    "url": f"https://bsky.app/profile/{a['handle']}",
  • Network accessline 429
    "verified": true,   "labels": [],   "url": "https://bsky.app/profile/atproto.com"
  • Network accessline 430
    "labels": [],   "url": "https://bsky.app/profile/atproto.com"  },
  • Network accessline 431
    "url": "https://bsky.app/profile/atproto.com"
  • Network accessline 439
    "verified": false,   "labels": [],   "url": "https://bsky.app/profile/microcosm.blue"
  • Network accessline 440
    "labels": [],   "url": "https://bsky.app/profile/microcosm.blue"  },
  • Network accessline 441
    "url": "https://bsky.app/profile/microcosm.blue"
  • Network accessline 454
    POST_URL = "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o"
  • Network accessline 458
    API = "https://public.api.bsky.app/xrpc/"
  • Network accessline 473
    """Fetches run inside a logged-out bsky.app tab; reuse it if the attached tab is already there."""     try:         if js("location.origin") == "https://bsky.app":
  • Network accessline 474
    try:         if js("location.origin") == "https://bsky.app":             return
  • Network accessline 475
    if js("location.origin") == "https://bsky.app":
  • Network accessline 477
    except Exception:         pass     new_tab("https://bsky.app/")
  • Network accessline 478
    pass     new_tab("https://bsky.app/")     wait_for_load()
  • Network accessline 479
    new_tab("https://bsky.app/")
  • Network accessline 482
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 483
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, body: await r.text()}; }
  • Network accessline 508
    def to_at_uri(url):     """https://bsky.app/profile/<handle-or-did>/post/<rkey> -> at://<handle-or-did>/app.bsky.feed.post/<rkey>
  • Network accessline 509
    """https://bsky.app/profile/<handle-or-did>/post/<rkey> -> at://<handle-or-did>/app.bsky.feed.post/<rkey>
  • Network accessline 510
    (the AppView resolves a handle in the URI itself)."""     m = re.match(r"https://bsky\.app/profile/([^/]+)/post/([^/?#]+)", url)     if not m:
  • Network accessline 511
    m = re.match(r"https://bsky\.app/profile/([^/]+)/post/([^/?#]+)", url)
  • Network accessline 517
    rec = post["record"]     return {         "url": f"https://bsky.app/profile/{post['author']['handle']}/post/{post['uri'].rsplit('/', 1)[-1]}",
  • Network accessline 518
    return {         "url": f"https://bsky.app/profile/{post['author']['handle']}/post/{post['uri'].rsplit('/', 1)[-1]}",         "author": post["author"]["handle"],
  • Network accessline 519
    "url": f"https://bsky.app/profile/{post['author']['handle']}/post/{post['uri'].rsplit('/', 1)[-1]}",
  • Network accessline 555
    {  "post": {   "url": "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o",
  • Network accessline 556
    "post": {   "url": "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o",   "author": "atproto.com",
  • Network accessline 557
    "url": "https://bsky.app/profile/atproto.com/post/3mz4m677rsc2o",
  • Network accessline 568
    "replies": [   {    "url": "https://bsky.app/profile/atproto.com/post/3mz4m67ahbs2o",
  • Network accessline 569
    {    "url": "https://bsky.app/profile/atproto.com/post/3mz4m67ahbs2o",    "author": "atproto.com",
  • Network accessline 570
    "url": "https://bsky.app/profile/atproto.com/post/3mz4m67ahbs2o",
  • Dangerous shell operationline 573
    "text": "Self-hosters can force an immediate Caddy update with:\n\n  sudo pdsadmin update \n\nFor additional confidence, you can disable mptcp system-wide with:\n\n sudo sysctl -w net.mptcp.enabled=0\n\nWe recommend upgrading your system ke
  • Network accessline 578
    },   {    "url": "https://bsky.app/profile/<handle>/post/3mz4yxxldg22n",
  • Network accessline 579
    {    "url": "https://bsky.app/profile/<handle>/post/3mz4yxxldg22n",    "author": "<handle>",
  • Network accessline 580
    "url": "https://bsky.app/profile/<handle>/post/3mz4yxxldg22n",
  • Network accessline 588
    },   {    "url": "https://bsky.app/profile/<handle>/post/3mz4mei4scs2p",
  • Network accessline 589
    {    "url": "https://bsky.app/profile/<handle>/post/3mz4mei4scs2p",    "author": "<handle>",
  • Network accessline 590
    "url": "https://bsky.app/profile/<handle>/post/3mz4mei4scs2p",
  • Network accessline 613
    API = "https://public.api.bsky.app/xrpc/" UA = "browser-harness-skill/1.0 (Python urllib)"   # truthful client UA
  • Network accessline 620
    for attempt in range(tries):         try:             with urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": UA}), timeout=30) as r:
  • Network accessline 621
    try:             with urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": UA}), timeout=30) as r:                 time.sleep(PAUSE)
  • Network accessline 622
    with urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": UA}), timeout=30) as r:
  • Network accessline 676
    | `pinned_post` | `pinnedPost.uri` | `at://` URI or null | | `kind` (block 2) | `reason.$type` (`#reasonRepost`, `#reasonPin`), `record.reply`, `post.embed.$type` | `post`, `reply`, `quote`, `repost`, `pin` | | `url` | built from `post.auth
  • Network accessline 677
    | `kind` (block 2) | `reason.$type` (`#reasonRepost`, `#reasonPin`), `record.reply`, `post.embed.$type` | `post`, `reply`, `quote`, `repost`, `pin` | | `url` | built from `post.author.handle` + rkey (last part of `post.uri`) | `https://bsky
  • Network accessline 678
    | `url` | built from `post.author.handle` + rkey (last part of `post.uri`) | `https://bsky.app/profile/<handle>/post/<rkey>`; for a repost it is the original post |
  • Network accessline 695
    - **Handles work inside `at://` URIs** for getPostThread; the error message shows the resolved DID. - **Logged-out visibility.** Accounts can self-label `!no-unauthenticated` to ask not to be shown to logged-out viewers. The blocks skip tho
  • Network accessline 696
    - **Logged-out visibility.** Accounts can self-label `!no-unauthenticated` to ask not to be shown to logged-out viewers. The blocks skip those accounts and replies. None turned up in today's runs, so that branch is untested. - **Failed CORS
  • Network accessline 697
    - **Failed CORS looks like status 0.** The 403 on searchPosts has no CORS header, so `fetch()` in the tab throws `TypeError: Failed to fetch` instead of showing 403. `xrpc()` retries status 0 once, then raises.
  • Network accessline 703
    - **Post search logged out.** `GET https://public.api.bsky.app/xrpc/app.bsky.feed.searchPosts?q=atproto&limit=2` returned HTTP 403 with a plain BunnyCDN "403 Forbidden" HTML page (plain HTTP and in-tab `fetch()`; block 5 shows it). `searchA

agent-workspace/domain-skills/booking-com/scraping.md

  • Access to secretsline 14
    [Credential-related source omitted]
  • Network accessline 17
    - Enumerate hotel/city/region URLs from XML sitemaps (Googlebot UA required). - Read `robots.txt` for URL pattern documentation. - Query the GraphQL endpoint `https://www.booking.com/dml/graphql` for schema
  • Network accessline 18
    - Read `robots.txt` for URL pattern documentation. - Query the GraphQL endpoint `https://www.booking.com/dml/graphql` for schema   exploration (no auth = internal errors, but validation errors reveal the
  • Network accessline 19
    - Query the GraphQL endpoint `https://www.booking.com/dml/graphql` for schema
  • Network accessline 34
    <script src="https://www.booking.com/__challenge_{KEY}/{HASH}/challenge.js"></script>
  • Network accessline 40
    **Variant B (~8,410 bytes) — with AJAX error reporting:** Same AWS WAF SDK, plus an `XMLHttpRequest`-based error reporter that POSTs to `https://reports.booking.com/chal_report`. This variant is more common on
  • Network accessline 41
    Same AWS WAF SDK, plus an `XMLHttpRequest`-based error reporter that POSTs to `https://reports.booking.com/chal_report`. This variant is more common on non-browser UA strings.
  • Network accessline 42
    `https://reports.booking.com/chal_report`. This variant is more common on
  • Network accessline 85
    GOOGLEBOT = {"User-Agent": "Googlebot/2.1 (+http://www.google.com/bot.html)"}
  • Network accessline 88
    """Returns list of child sitemap URLs from an index sitemap."""     xml = http_get(url, headers=GOOGLEBOT)     return re.findall(r'<loc>(https://[^<]+)</loc>', xml)
  • Network accessline 90
    return re.findall(r'<loc>(https://[^<]+)</loc>', xml)
  • Network accessline 92
    def fetch_sitemap_gz(gz_url: str) -> list[str]:     """Decompresses a gzipped sitemap and returns all <loc> URLs."""     req = urllib.request.Request(gz_url, headers=GOOGLEBOT)
  • Network accessline 93
    """Decompresses a gzipped sitemap and returns all <loc> URLs."""     req = urllib.request.Request(gz_url, headers=GOOGLEBOT)     with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 94
    req = urllib.request.Request(gz_url, headers=GOOGLEBOT)
  • Network accessline 95
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 97
    return re.findall(r'<loc>(https://[^<]+)</loc>', data.decode())
  • Network accessline 99
    # Example: get all en-gb hotel URLs hotel_idx = http_get(     "https://www.booking.com/sitembk-hotel-index.xml",
  • Network accessline 100
    hotel_idx = http_get(     "https://www.booking.com/sitembk-hotel-index.xml",     headers=GOOGLEBOT
  • Network accessline 101
    "https://www.booking.com/sitembk-hotel-index.xml",
  • Network accessline 104
    # 74 shards for en-gb; each shard has ~45,000-50,000 property URLs en_gb_shards = re.findall(     r'<loc>(https://www\.booking\.com/sitembk-hotel-en-gb\.\d+\.xml\.gz)</loc>',
  • Network accessline 105
    en_gb_shards = re.findall(     r'<loc>(https://www\.booking\.com/sitembk-hotel-en-gb\.\d+\.xml\.gz)</loc>',     hotel_idx
  • Network accessline 106
    r'<loc>(https://www\.booking\.com/sitembk-hotel-en-gb\.\d+\.xml\.gz)</loc>',
  • Network accessline 127
    robots = http_get("https://www.booking.com/robots.txt", headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 136
    The endpoint `https://www.booking.com/dml/graphql` is **not WAF-protected**. It accepts POST requests and returns JSON. Without a session, most queries
  • Network accessline 144
    GQL_URL = "https://www.booking.com/dml/graphql?lang=en-gb"
  • Network accessline 147
    "Accept": "application/json",     "Content-Type": "application/json",     "Origin": "https://www.booking.com",
  • Network accessline 148
    "Content-Type": "application/json",     "Origin": "https://www.booking.com",     "Referer": "https://www.booking.com/searchresults.html",
  • Network accessline 149
    "Origin": "https://www.booking.com",
  • Network accessline 150
    "Referer": "https://www.booking.com/searchresults.html",
  • Network accessline 158
    if variables:         payload["variables"] = variables     req = urllib.request.Request(
  • Network accessline 159
    payload["variables"] = variables     req = urllib.request.Request(         GQL_URL,
  • Network accessline 160
    req = urllib.request.Request(
  • Network accessline 164
    method="POST"     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 165
    )     with urllib.request.urlopen(req, timeout=20) as r:         data = r.read()
  • Network accessline 166
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 222
    ### Search Results `https://www.booking.com/searchresults.html`
  • Network accessline 223
    `https://www.booking.com/searchresults.html`
  • Network accessline 253
    ### Property Pages `https://www.booking.com/hotel/{country_code}/{hotel_slug}.html`
  • Network accessline 254
    `https://www.booking.com/hotel/{country_code}/{hotel_slug}.html`
  • Network accessline 258
    https://www.booking.com/hotel/{cc}/{slug}.html
  • Network accessline 259
    https://www.booking.com/hotel/{cc}/{slug}.en-gb.html
  • Network accessline 260
    https://www.booking.com/hotel/{cc}/{slug}.{lang}.html
  • Network accessline 268
    https://www.booking.com/city/{cc}/{city-slug}.html
  • Network accessline 269
    https://www.booking.com/region/{cc}/{region-slug}.html
  • Network accessline 270
    https://www.booking.com/country/{cc}.html
  • Network accessline 283
    # Always use new_tab() for the first Booking.com load in a session tid = new_tab("https://www.booking.com/searchresults.html?ss=Paris&checkin=2026-05-01&checkout=2026-05-03&group_adults=2&no_rooms=1&selected_currency=USD")
  • Network accessline 284
    tid = new_tab("https://www.booking.com/searchresults.html?ss=Paris&checkin=2026-05-01&checkout=2026-05-03&group_adults=2&no_rooms=1&selected_currency=USD")
  • Network accessline 505
    # Use after goto_url(): goto_url("https://www.booking.com/searchresults.html?ss=London&checkin=2026-06-01&checkout=2026-06-03&group_adults=2&no_rooms=1")
  • Network accessline 506
    goto_url("https://www.booking.com/searchresults.html?ss=London&checkin=2026-06-01&checkout=2026-06-03&group_adults=2&no_rooms=1")
  • Network accessline 522
    GOOGLEBOT = {"User-Agent": "Googlebot/2.1 (+http://www.google.com/bot.html)"}
  • Network accessline 524
    def get_hotel_urls_for_country(cc: str, lang: str = "en-gb", max_shards: int = 2) -> list[str]:     """Returns property page URLs for a country from sitemaps. No browser needed."""     idx_url = f"https://www.booking.com/sitembk-hotel-index
  • Network accessline 525
    """Returns property page URLs for a country from sitemaps. No browser needed."""     idx_url = f"https://www.booking.com/sitembk-hotel-index.xml"     idx = http_get(idx_url, headers=GOOGLEBOT)
  • Network accessline 526
    idx_url = f"https://www.booking.com/sitembk-hotel-index.xml"
  • Network accessline 527
    idx = http_get(idx_url, headers=GOOGLEBOT)     pattern = rf'<loc>(https://www\.booking\.com/sitembk-hotel-{lang}\.\d+\.xml\.gz)</loc>'     shards = re.findall(pattern, idx)[:max_shards]
  • Network accessline 528
    pattern = rf'<loc>(https://www\.booking\.com/sitembk-hotel-{lang}\.\d+\.xml\.gz)</loc>'
  • Network accessline 531
    urls = []     for shard_url in shards:         req = urllib.request.Request(shard_url, headers=GOOGLEBOT)
  • Network accessline 532
    for shard_url in shards:         req = urllib.request.Request(shard_url, headers=GOOGLEBOT)         with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 533
    req = urllib.request.Request(shard_url, headers=GOOGLEBOT)
  • Network accessline 534
    with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 535
    xml = gzip.decompress(r.read()).decode()         all_urls = re.findall(r'<loc>(https://[^<]+)</loc>', xml)         # Filter by country code
  • Network accessline 536
    all_urls = re.findall(r'<loc>(https://[^<]+)</loc>', xml)

agent-workspace/domain-skills/browser-use-cloud/cleanup-zombies.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 8
    [Credential-related source omitted]
  • Access to secretsline 11
    [Credential-related source omitted]
  • Access to secretsline 14
    [Credential-related source omitted]
  • Network accessline 33
    API = "https://api.browser-use.com/api/v3"
  • Access to secretsline 37
    [Credential-related source omitted]
  • Access to secretsline 39
    [Credential-related source omitted]
  • Network accessline 47
    def _call(method: str, path: str, body: dict | None = None, timeout: float = 30.0) -> dict:     req = urllib.request.Request(
  • Network accessline 48
    req = urllib.request.Request(
  • Network accessline 52
    headers=_headers(),     )     with urllib.request.urlopen(req, timeout=timeout) as resp:
  • Network accessline 53
    )     with urllib.request.urlopen(req, timeout=timeout) as resp:         return json.loads(resp.read() or b"{}")
  • Network accessline 54
    with urllib.request.urlopen(req, timeout=timeout) as resp:

agent-workspace/domain-skills/browser-use-cloud/cloud.md

  • Network accessline 3
    `https://api.browser-use.com/api/v3` (REST). All five endpoints below were
  • Access to secretsline 4
    [Credential-related source omitted]
  • Access to secretsline 22
    [Credential-related source omitted]
  • Network accessline 32
    All paths are under `https://api.browser-use.com/api/v3`. Verified status
  • Access to secretsline 116
    [Credential-related source omitted]
  • Access to secretsline 119
    [Credential-related source omitted]
  • Network accessline 152
    cookies = cdp("Network.getCookies", urls=["https://cloud.browser-use.com"])
  • Network accessline 179
    (large profile sync) need their own polling. - **`profile-use` CLI is a separate install**:   `curl -fsSL https://browser-use.com/profile.sh | sh`.
  • Network accessline 180
    - **`profile-use` CLI is a separate install**:   `curl -fsSL https://browser-use.com/profile.sh | sh`. - **`pageSize` caps at 100** silently — paginate via `pageNumber`.
  • Dangerous shell operationline 181
    `curl -fsSL https://browser-use.com/profile.sh | sh`.
  • Network accessline 181
    `curl -fsSL https://browser-use.com/profile.sh | sh`.
  • Network accessline 199
    Live-tested 2026-05-05 against `https://api.browser-use.com/api/v3`:

agent-workspace/domain-skills/capterra/scraping.md

  • Network accessline 17
    # Works everywhere: html = http_get(     "https://www.capterra.com/p/135003/Slack/reviews/",
  • Network accessline 18
    html = http_get(     "https://www.capterra.com/p/135003/Slack/reviews/",     headers={"User-Agent": "ClaudeBot"}
  • Network accessline 19
    "https://www.capterra.com/p/135003/Slack/reviews/",
  • Network accessline 42
    slug: URL slug (e.g. 'Slack')     """     url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/"
  • Network accessline 43
    """     url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/"     html = http_get(url, headers={"User-Agent": "ClaudeBot"})
  • Network accessline 44
    url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/"
  • Network accessline 106
    Total pages = ceil(review_count / 25).     """     url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/?page={page}"
  • Network accessline 107
    """     url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/?page={page}"     html = http_get(url, headers={"User-Agent": "ClaudeBot"})
  • Network accessline 108
    url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/?page={page}"
  • Dangerous shell operationline 139
    rm = re.search(r"\n\n([\d.]+)\n\n", block)
  • Network accessline 186
    def _fetch_page(args):     product_id, slug, page = args     url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/?page={page}"
  • Network accessline 187
    product_id, slug, page = args     url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/?page={page}"     html = http_get(url, headers=UA)
  • Network accessline 188
    url = f"https://www.capterra.com/p/{product_id}/{slug}/reviews/?page={page}"
  • Dangerous shell operationline 198
    rm = re.search(r"\n\n([\d.]+)\n\n", block)
  • Network accessline 211
    # First: get total pages     summary_html = http_get(         f"https://www.capterra.com/p/{product_id}/{slug}/reviews/",
  • Network accessline 212
    summary_html = http_get(         f"https://www.capterra.com/p/{product_id}/{slug}/reviews/",         headers=UA
  • Network accessline 213
    f"https://www.capterra.com/p/{product_id}/{slug}/reviews/",
  • Network accessline 240
    def get_product_overview(product_id, slug):     """Rating breakdown, sentiment, starting price from the product page."""     url = f"https://www.capterra.com/p/{product_id}/{slug}/"
  • Network accessline 241
    """Rating breakdown, sentiment, starting price from the product page."""     url = f"https://www.capterra.com/p/{product_id}/{slug}/"     html = http_get(url, headers={"User-Agent": "ClaudeBot"})
  • Network accessline 242
    url = f"https://www.capterra.com/p/{product_id}/{slug}/"
  • Network accessline 270
    # Categories ("What is X used for?" links)     cats = re.findall(r'\[([^\]]+)\]\(https://www\.capterra\.com/([a-z-]+-software)/\)', html[:3000])
  • Network accessline 271
    cats = re.findall(r'\[([^\]]+)\]\(https://www\.capterra\.com/([a-z-]+-software)/\)', html[:3000])
  • Network accessline 312
    List products in a Capterra category.     category_slug examples: 'project-management-software', 'crm-software', 'accounting-software'     Full list: https://www.capterra.com/categories/
  • Network accessline 313
    category_slug examples: 'project-management-software', 'crm-software', 'accounting-software'     Full list: https://www.capterra.com/categories/     """
  • Network accessline 314
    Full list: https://www.capterra.com/categories/
  • Network accessline 315
    """     url = f"https://www.capterra.com/{category_slug}/"     if page > 1:
  • Network accessline 316
    url = f"https://www.capterra.com/{category_slug}/"
  • Network accessline 317
    if page > 1:         url = f"https://www.capterra.com/{category_slug}/?page={page}"     html = http_get(url, headers={"User-Agent": "ClaudeBot"})
  • Network accessline 318
    url = f"https://www.capterra.com/{category_slug}/?page={page}"
  • Network accessline 321
    # Ratings: [4.6 (5732)](https://www.capterra.com/p/147657/monday-com/reviews/)
  • Network accessline 322
    raw = re.findall(         r'\[([\d.]+)\s+\(([\d,]+)\)\]\(https://www\.capterra\.com/p/(\d+)/([^/]+)/reviews/\)',         html
  • Network accessline 323
    r'\[([\d.]+)\s+\(([\d,]+)\)\]\(https://www\.capterra\.com/p/(\d+)/([^/]+)/reviews/\)',
  • Network accessline 326
    # Product names from "Learn more about X" links     names = {pid: name for name, pid in re.findall(         r'\[Learn more about ([^\]]+)\]\(https://www\.capterra\.com/p/(\d+)/[^/]+/\)', html
  • Network accessline 327
    names = {pid: name for name, pid in re.findall(         r'\[Learn more about ([^\]]+)\]\(https://www\.capterra\.com/p/(\d+)/[^/]+/\)', html     )}
  • Network accessline 328
    r'\[Learn more about ([^\]]+)\]\(https://www\.capterra\.com/p/(\d+)/[^/]+/\)', html
  • Network accessline 339
    "overall_rating": float(rating),                 "review_count": int(review_count.replace(",", "")),                 "product_url": f"https://www.capterra.com/p/{pid}/{slug}/",
  • Network accessline 340
    "review_count": int(review_count.replace(",", "")),                 "product_url": f"https://www.capterra.com/p/{pid}/{slug}/",                 "reviews_url": f"https://www.capterra.com/p/{pid}/{slug}/reviews/",
  • Network accessline 341
    "product_url": f"https://www.capterra.com/p/{pid}/{slug}/",
  • Network accessline 342
    "reviews_url": f"https://www.capterra.com/p/{pid}/{slug}/reviews/",
  • Network accessline 360
    def get_all_categories():     """Returns list of {name, slug} for all ~1003 Capterra software categories."""     html = http_get("https://www.capterra.com/categories/", headers={"User-Agent": "ClaudeBot"})
  • Network accessline 361
    """Returns list of {name, slug} for all ~1003 Capterra software categories."""     html = http_get("https://www.capterra.com/categories/", headers={"User-Agent": "ClaudeBot"})     cats = re.findall(r'\[([^\]]+)\]\(https://www\.capterra\.com
  • Network accessline 362
    html = http_get("https://www.capterra.com/categories/", headers={"User-Agent": "ClaudeBot"})
  • Network accessline 363
    cats = re.findall(r'\[([^\]]+)\]\(https://www\.capterra\.com/([a-z-]+-software)/\)', html)
  • Network accessline 377
    | Page type | URL pattern | |-----------|-------------| | Product overview | `https://www.capterra.com/p/{id}/{Slug}/` |
  • Network accessline 378
    |-----------|-------------| | Product overview | `https://www.capterra.com/p/{id}/{Slug}/` | | Product reviews | `https://www.capterra.com/p/{id}/{Slug}/reviews/` |
  • Network accessline 379
    | Product overview | `https://www.capterra.com/p/{id}/{Slug}/` |
  • Network accessline 380
    | Product reviews | `https://www.capterra.com/p/{id}/{Slug}/reviews/` |
  • Network accessline 381
    | Reviews page N | `https://www.capterra.com/p/{id}/{Slug}/reviews/?page={N}` |
  • Network accessline 382
    | Reviews (alt) | `https://www.capterra.com/reviews/{id}/{Slug}/` |
  • Network accessline 383
    | Category listing | `https://www.capterra.com/{category}-software/` |
  • Network accessline 384
    | Category page N | `https://www.capterra.com/{category}-software/?page={N}` |
  • Network accessline 385
    | All categories | `https://www.capterra.com/categories/` |
  • Network accessline 386
    | Product pricing | `https://www.capterra.com/p/{id}/{Slug}/pricing/` |
  • Network accessline 387
    | Product alternatives | `https://www.capterra.com/p/{id}/{Slug}/alternatives/` |
  • Network accessline 388
    | Compare A vs B | `https://www.capterra.com/compare/{id_a}-{id_b}/{Slug_a}-vs-{Slug_b}` |
  • Network accessline 390
    **Finding a product's ID:** Look in the URL of any product listing in a category page. The pattern `https://www.capterra.com/p/{id}/{Slug}/reviews/` appears in every category listing as the link target for each rating badge. The slug is cas
  • Network accessline 412
    - **Old Capterra product IDs may be invalid.** The URL `https://www.capterra.com/p/56703/Slack/` (ID 56703) returns 404 even with ClaudeBot — this is a stale or merged product ID. Slack's current ID is 135003, found in the team-communicatio

agent-workspace/domain-skills/centilebrain/generate-estimates.md

  • Network accessline 3
    URL: `https://centilebrain.org/#/model`
  • Network accessline 12
    - The `/#/model` page is a thin wrapper around per-modality/sex **Shiny   iframes** at `https://centilebrain-app.shinyapps.io/{SV|CT|SA}-{MALE|FEMALE}/`.
  • Network accessline 13
    iframes** at `https://centilebrain-app.shinyapps.io/{SV|CT|SA}-{MALE|FEMALE}/`.
  • Network accessline 51
    new_tab("https://centilebrain.org/#/model")

agent-workspace/domain-skills/chess-com/scraping.md

  • Network accessline 3
    Field-tested against api.chess.com on 2026-11-01 using a Browser Use cloud browser, logged out. Every call is a same-origin `fetch()` from an api.chess.com tab. No CAPTCHA, 403 or 429 across about 40 calls.
  • Network accessline 5
    robots.txt (fetched 2026-11-01): api.chess.com is `User-agent: *` / `Disallow: /`; this skill uses it only under the official-API exception, because Chess.com documents these `/pub/...` endpoints as its public Published-Data API (https://ww
  • Network accessline 9
    - **No scraping.** Three public JSON endpoints and one PGN endpoint cover the task. No key, no cookies, `access-control-allow-origin: *`:   - `https://api.chess.com/pub/player/<user>` - profile: `player_id`, title, status, name, country, jo
  • Network accessline 10
    - `https://api.chess.com/pub/player/<user>` - profile: `player_id`, title, status, name, country, joined, last online, followers.
  • Network accessline 11
    - `https://api.chess.com/pub/player/<user>/stats` - ratings per game type (`chess_blitz`, `chess_bullet`, `chess_rapid`, `chess_daily`, `chess960_daily`) with current, best and W/L/D, plus `fide`, `tactics`, `puzzle_rush`.
  • Network accessline 12
    - `https://api.chess.com/pub/player/<user>/games/archives` - every month with games, as URLs, oldest first.   - `https://api.chess.com/pub/player/<user>/games/<YYYY>/<MM>` (JSON, one object per game incl. its PGN) and `.../<YYYY>/<MM>/pgn` 
  • Network accessline 13
    - `https://api.chess.com/pub/player/<user>/games/<YYYY>/<MM>` (JSON, one object per game incl. its PGN) and `.../<YYYY>/<MM>/pgn` (one multi-game PGN file). - **Serial calls only.** Chess.com's docs: "Your serial access rate is unlimited", 
  • Network accessline 20
    All blocks share the same helpers: `on_api_tab()` opens `https://api.chess.com/robots.txt` once (a tiny page on the API host, so `fetch()` is same-origin) and later blocks reuse it. `get(path)` fetches `https://api.chess.com/pub/<path>`, ke
  • Network accessline 30
    API = "https://api.chess.com/pub/"
  • Network accessline 35
    def on_api_tab():     """All calls run as same-origin fetch() in a logged-out api.chess.com tab; reuse it if already there."""
  • Network accessline 36
    """All calls run as same-origin fetch() in a logged-out api.chess.com tab; reuse it if already there."""
  • Network accessline 37
    try:         if js("location.origin") == "https://api.chess.com":             return
  • Network accessline 38
    if js("location.origin") == "https://api.chess.com":
  • Network accessline 40
    except Exception:         pass     new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host
  • Network accessline 41
    pass     new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host     wait_for_load()
  • Network accessline 42
    new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host
  • Network accessline 45
    FETCH_JS = """(async () => {   try {     const r = await fetch(%s, {credentials: 'omit'});
  • Network accessline 46
    try {     const r = await fetch(%s, {credentials: 'omit'});     window.__cc = await r.text();
  • Network accessline 47
    const r = await fetch(%s, {credentials: 'omit'});
  • Network accessline 134
    {  "username": "hikaru",  "url": "https://www.chess.com/member/Hikaru",
  • Network accessline 135
    "username": "hikaru",  "url": "https://www.chess.com/member/Hikaru",  "player_id": 15448422,
  • Network accessline 136
    "url": "https://www.chess.com/member/Hikaru",
  • Network accessline 153
    "best": 2464,    "best_on": "2014-04-10T13:32Z",    "best_game": "https://www.chess.com/game/daily/84604826",
  • Network accessline 154
    "best_on": "2014-04-10T13:32Z",    "best_game": "https://www.chess.com/game/daily/84604826",    "win": 73,
  • Network accessline 155
    "best_game": "https://www.chess.com/game/daily/84604826",
  • Network accessline 164
    "best": 1489,    "best_on": "2014-04-09T19:50Z",    "best_game": "https://www.chess.com/game/daily/87191830",
  • Network accessline 165
    "best_on": "2014-04-09T19:50Z",    "best_game": "https://www.chess.com/game/daily/87191830",    "win": 1,
  • Network accessline 166
    "best_game": "https://www.chess.com/game/daily/87191830",
  • Network accessline 175
    "best": 2927,    "best_on": "2022-02-26T19:08Z",    "best_game": "https://www.chess.com/game/live/141332265952",
  • Network accessline 176
    "best_on": "2022-02-26T19:08Z",    "best_game": "https://www.chess.com/game/live/141332265952",    "win": 205,
  • Network accessline 177
    "best_game": "https://www.chess.com/game/live/141332265952",
  • Network accessline 186
    "best": 3570,    "best_on": "2020-11-11T23:07Z",    "best_game": "https://www.chess.com/game/live/5710095242",
  • Network accessline 187
    "best_on": "2020-11-11T23:07Z",    "best_game": "https://www.chess.com/game/live/5710095242",    "win": 17232,
  • Network accessline 188
    "best_game": "https://www.chess.com/game/live/5710095242",
  • Network accessline 197
    "best": 3503,    "best_on": "2026-10-06T16:21Z",    "best_game": "https://www.chess.com/game/live/184580310677",
  • Network accessline 198
    "best_on": "2026-10-06T16:21Z",    "best_game": "https://www.chess.com/game/live/184580310677",    "win": 36083,
  • Network accessline 199
    "best_game": "https://www.chess.com/game/live/184580310677",
  • Network accessline 218
    API = "https://api.chess.com/pub/"
  • Network accessline 223
    def on_api_tab():     """All calls run as same-origin fetch() in a logged-out api.chess.com tab; reuse it if already there."""
  • Network accessline 224
    """All calls run as same-origin fetch() in a logged-out api.chess.com tab; reuse it if already there."""
  • Network accessline 225
    try:         if js("location.origin") == "https://api.chess.com":             return
  • Network accessline 226
    if js("location.origin") == "https://api.chess.com":
  • Network accessline 228
    except Exception:         pass     new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host
  • Network accessline 229
    pass     new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host     wait_for_load()
  • Network accessline 230
    new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host
  • Network accessline 233
    FETCH_JS = """(async () => {   try {     const r = await fetch(%s, {credentials: 'omit'});
  • Network accessline 234
    try {     const r = await fetch(%s, {credentials: 'omit'});     window.__cc = await r.text();
  • Network accessline 235
    const r = await fetch(%s, {credentials: 'omit'});
  • Network accessline 339
    2026/10: 583 games {"blitz": {"games": 549, "win": 473, "draw": 41, "loss": 35}, "bullet": {"games": 543, "win": 412, "draw": 45, "loss": 86}} {"url": "https://www.chess.com/game/live/186299800014", "end": "2026-10-31T19:39Z", "time_class":
  • Network accessline 340
    {"blitz": {"games": 549, "win": 473, "draw": 41, "loss": 35}, "bullet": {"games": 543, "win": 412, "draw": 45, "loss": 86}} {"url": "https://www.chess.com/game/live/186299800014", "end": "2026-10-31T19:39Z", "time_class": "blitz", "time_con
  • Network accessline 341
    {"url": "https://www.chess.com/game/live/186299800014", "end": "2026-10-31T19:39Z", "time_class": "blitz", "time_control": "180", "rules": "chess", "rated": true, "color": "white", "rating": 3453, "opponent": "Sina-Movahed", "opp_rating": 3
  • Network accessline 350
    [Timezone "UTC"] [ECO "B51"] [ECOUrl "https://www.chess.com/openings/Sicilian-Defense-Canal-Attack...10.h3-Bh5-11.g4-Bg6-12.Nh4"]
  • Network accessline 351
    [ECO "B51"] [ECOUrl "https://www.chess.com/openings/Sicilian-Defense-Canal-Attack...10.h3-Bh5-11.g4-Bg6-12.Nh4"] [UTCDate "2026.10.31"]
  • Network accessline 352
    [ECOUrl "https://www.chess.com/openings/Sicilian-Defense-Canal-Attack...10.h3-Bh5-11.g4-Bg6-12.Nh4"]
  • Network accessline 371
    API = "https://api.chess.com/pub/"
  • Network accessline 376
    def on_api_tab():     """All calls run as same-origin fetch() in a logged-out api.chess.com tab; reuse it if already there."""
  • Network accessline 377
    """All calls run as same-origin fetch() in a logged-out api.chess.com tab; reuse it if already there."""
  • Network accessline 378
    try:         if js("location.origin") == "https://api.chess.com":             return
  • Network accessline 379
    if js("location.origin") == "https://api.chess.com":
  • Network accessline 381
    except Exception:         pass     new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host
  • Network accessline 382
    pass     new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host     wait_for_load()
  • Network accessline 383
    new_tab("https://api.chess.com/robots.txt")   # tiny page on the API host
  • Network accessline 386
    FETCH_JS = """(async () => {   try {     const r = await fetch(%s, {credentials: 'omit'});
  • Network accessline 387
    try {     const r = await fetch(%s, {credentials: 'omit'});     window.__cc = await r.text();
  • Network accessline 388
    const r = await fetch(%s, {credentials: 'omit'});
  • Network accessline 475
    [EndDate "2009.10.31"] [EndTime "17:53:17"] [Link "https://www.chess.com/game/daily/28103371"]
  • Network accessline 477
    [Link "https://www.chess.com/game/daily/28103371"]
  • Network accessline 515
    - **`rating` in a game row is the rating after that game**, not before it. - **Parallel requests:** not tested on purpose. The docs warn they may get 429 and that suspicious traffic can be blocked; keep calls serial. - **Browser User-Agent:
  • Network accessline 516
    - **Parallel requests:** not tested on purpose. The docs warn they may get 429 and that suspicious traffic can be blocked; keep calls serial. - **Browser User-Agent:** the docs ask apps to send a recognizable User-Agent with contact info so
  • Network accessline 517
    - **Browser User-Agent:** the docs ask apps to send a recognizable User-Agent with contact info so Chess.com can reach you before blocking. In-tab `fetch()` cannot set it; the browser's own UA goes out unchanged. Do not spoof it.

agent-workspace/domain-skills/claude-ai/extract-share-transcript.py

  • Executable scriptline 1
    Executable file
  • Network accessline 3
    Usage (run inside browser-harness):     CLAUDE_SHARE_URL=https://claude.ai/share/<uuid> \
  • Network accessline 4
    CLAUDE_SHARE_URL=https://claude.ai/share/<uuid> \
  • Access to secretsline 17
    [Credential-related source omitted]
  • Access to secretsline 18
    [Credential-related source omitted]

agent-workspace/domain-skills/claude-ai/share-export.md

  • Network accessline 3
    URL pattern: `https://claude.ai/share/<uuid>`
  • Network accessline 51
    CLAUDE_SHARE_URL=https://claude.ai/share/<uuid> \

agent-workspace/domain-skills/claude/custom-connectors.md

  • Network accessline 5
    - Organization connectors are managed at `https://claude.ai/admin-settings/connectors`. Check the organization selector before changing settings.

agent-workspace/domain-skills/claude/skills.md

  • Network accessline 5
    - `https://claude.ai/customize/skills` opens Skills > Yours.

agent-workspace/domain-skills/clinicaltrials-gov/scraping.md

  • Network accessline 9
    - **Use the official API.** `GET https://clinicaltrials.gov/api/v2/studies` with `query.cond` (condition), `filter.overallStatus` (status list) and either `filter.geo=distance(lat,lon,25mi)` (radius) or `query.locn` (location text). `GET /a
  • Network accessline 24
    API = "https://clinicaltrials.gov/api/v2"   # official public API; robots.txt disallows /api/ (official-API exception) UA = "browser-harness-clinicaltrials-skill/1.0 Python-urllib"   # truthful client name, no browser UA
  • Network accessline 34
    _last[0] = time.time()         try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json"})
  • Network accessline 35
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json"})             with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 36
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json"})
  • Network accessline 37
    with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 136
    "site_statuses": {s: sum(1 for l in locs if l.get("status") == s) for s in sorted({l.get("status") for l in locs if l.get("status")})},         "has_results": d.get("hasResults"), "last_update": st.get("lastUpdatePostDateStruct", {}).get("d
  • Network accessline 137
    "has_results": d.get("hasResults"), "last_update": st.get("lastUpdatePostDateStruct", {}).get("date"),         "url": f"https://clinicaltrials.gov/study/{idm['nctId']}",     }
  • Network accessline 138
    "url": f"https://clinicaltrials.gov/study/{idm['nctId']}",
  • Network accessline 201
    COMPLETED              151   TERMINATED             22 {"nct": "NCT06919354", "title": "A Study of GNTI-122 in Adults Recently Diagnosed With T1D", "official_title": "POLARIS: A Phase 1, Single Dose, Open-label Study of GNTI-122 in Adults W
  • Network accessline 202
    TERMINATED             22 {"nct": "NCT06919354", "title": "A Study of GNTI-122 in Adults Recently Diagnosed With T1D", "official_title": "POLARIS: A Phase 1, Single Dose, Open-label Study of GNTI-122 in Adults With Recently Diagnosed Type 1
  • Network accessline 203
    {"nct": "NCT06919354", "title": "A Study of GNTI-122 in Adults Recently Diagnosed With T1D", "official_title": "POLARIS: A Phase 1, Single Dose, Open-label Study of GNTI-122 in Adults With Recently Diagnosed Type 1 Diabetes (T1D)", "status"
  • Network accessline 204
    {"nct": "NCT04368728", "title": "Study to Describe the Safety, Tolerability, Immunogenicity, and Efficacy of RNA Vaccine Candidates Against COVID-19 in Healthy Individuals", "official_title": "A PHASE 1/2/3, PLACEBO-CONTROLLED, RANDOMIZED, 
  • Network accessline 206
    bad status -> HTTP 400 'Invalid value in parameter `overallStatus`: `OPEN`' on https://clinica
  • Network accessline 218
    SITE = "https://clinicaltrials.gov"
  • Network accessline 256
    .find(n => n.includes('/api/int/studies/' + nct));   if (!src) return {pending: true};   const r = await fetch(src);
  • Network accessline 257
    if (!src) return {pending: true};   const r = await fetch(src);   if (r.status === 404) return {missing: true, src};
  • Network accessline 258
    const r = await fetch(src);
  • Network accessline 328
    robots: /study/NCT06919354 True | /api/int/studies/NCT06919354 True | /api/v2/studies False | /search?cond=x False {"src": "https://clinicaltrials.gov/api/int/studies/NCT06919354?history=true", "nct": "NCT06919354", "title": "A Study of GNT
  • Network accessline 329
    {"src": "https://clinicaltrials.gov/api/int/studies/NCT06919354?history=true", "nct": "NCT06919354", "title": "A Study of GNTI-122 in Adults Recently Diagnosed With T1D", "status": "RECRUITING", "phases": ["PHASE1"], "type": "INTERVENTIONAL
  • Network accessline 330
    {"src": "https://clinicaltrials.gov/api/int/studies/NCT04368728?history=true", "nct": "NCT04368728", "title": "Study to Describe the Safety, Tolerability, Immunogenicity, and Efficacy of RNA Vaccine Candidates Against COVID-19 in Healthy In

agent-workspace/domain-skills/coingecko/scraping.md

  • Network accessline 3
    `https://api.coingecko.com/api/v3` — no API key needed for free tier. Pure JSON REST API, no browser required.
  • Network accessline 10
    import json data = json.loads(http_get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"))
  • Network accessline 11
    data = json.loads(http_get("https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd"))
  • Network accessline 54
    # Resolve symbol to id coins_list = json.loads(http_get("https://api.coingecko.com/api/v3/coins/list"))
  • Network accessline 55
    coins_list = json.loads(http_get("https://api.coingecko.com/api/v3/coins/list"))
  • Network accessline 67
    import json data = json.loads(http_get(     "https://api.coingecko.com/api/v3/simple/price"
  • Network accessline 68
    data = json.loads(http_get(     "https://api.coingecko.com/api/v3/simple/price"     "?ids=bitcoin,ethereum,solana"
  • Network accessline 69
    "https://api.coingecko.com/api/v3/simple/price"
  • Network accessline 88
    import json data = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/markets"
  • Network accessline 89
    data = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/markets"     "?vs_currency=usd"
  • Network accessline 90
    "https://api.coingecko.com/api/v3/coins/markets"
  • Network accessline 113
    import json data = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/bitcoin"
  • Network accessline 114
    data = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/bitcoin"     "?localization=false"    # skip 40+ language translations
  • Network accessline 115
    "https://api.coingecko.com/api/v3/coins/bitcoin"
  • Network accessline 143
    # 1d = 30-min candles, 7d = 4-hr candles, 14d+ = daily candles data = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/ethereum/ohlc?vs_currency=usd&days=7"
  • Network accessline 144
    data = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/ethereum/ohlc?vs_currency=usd&days=7" ))
  • Network accessline 145
    "https://api.coingecko.com/api/v3/coins/ethereum/ohlc?vs_currency=usd&days=7"
  • Network accessline 163
    # interval='daily' gives one point per day; omit for auto (hourly for <=90 days) chart = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart"
  • Network accessline 164
    chart = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart"     "?vs_currency=usd&days=7&interval=daily"
  • Network accessline 165
    "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart"
  • Network accessline 180
    thirty_days_ago = now - 30 * 86400 chart = json.loads(http_get(     f"https://api.coingecko.com/api/v3/coins/bitcoin/market_chart/range"
  • Network accessline 181
    chart = json.loads(http_get(     f"https://api.coingecko.com/api/v3/coins/bitcoin/market_chart/range"     f"?vs_currency=usd&from={thirty_days_ago}&to={now}"
  • Network accessline 182
    f"https://api.coingecko.com/api/v3/coins/bitcoin/market_chart/range"
  • Network accessline 192
    import json results = json.loads(http_get("https://api.coingecko.com/api/v3/search?query=solana"))
  • Network accessline 193
    results = json.loads(http_get("https://api.coingecko.com/api/v3/search?query=solana"))
  • Network accessline 206
    import json trending = json.loads(http_get("https://api.coingecko.com/api/v3/search/trending"))
  • Network accessline 207
    trending = json.loads(http_get("https://api.coingecko.com/api/v3/search/trending"))
  • Network accessline 221
    import json global_data = json.loads(http_get("https://api.coingecko.com/api/v3/global"))
  • Network accessline 222
    global_data = json.loads(http_get("https://api.coingecko.com/api/v3/global"))
  • Network accessline 234
    import json cats = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/categories?order=market_cap_desc"
  • Network accessline 235
    cats = json.loads(http_get(     "https://api.coingecko.com/api/v3/coins/categories?order=market_cap_desc" ))
  • Network accessline 236
    "https://api.coingecko.com/api/v3/coins/categories?order=market_cap_desc"
  • Network accessline 252
    [Credential-related source omitted]
  • Network accessline 253
    [Credential-related source omitted]
  • Network accessline 254
    "https://api.coingecko.com/api/v3/simple/token_price/ethereum"
  • Network accessline 275
    currencies = json.loads(http_get("https://api.coingecko.com/api/v3/simple/supported_vs_currencies"))
  • Network accessline 292
    import json ping = json.loads(http_get("https://api.coingecko.com/api/v3/ping"))
  • Network accessline 293
    ping = json.loads(http_get("https://api.coingecko.com/api/v3/ping"))

agent-workspace/domain-skills/coinmarketcap/scraping.md

  • Network accessline 3
    `https://coinmarketcap.com` — crypto market data. Three access paths tested: internal JSON API (fastest, no auth required), `__NEXT_DATA__` from HTML pages, and browser DOM. All real-money price data confirmed accurate against displayed UI 
  • Network accessline 31
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/listing"
  • Network accessline 32
    "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/listing"
  • Network accessline 109
    # Look up by CMC coin ID (BTC=1, ETH=1027, XRP=52, SOL=5426, BNB=1839) resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/detail?id=1"
  • Network accessline 110
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/detail?id=1" ))
  • Network accessline 111
    "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/detail?id=1"
  • Network accessline 172
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/global-metrics/quotes/latest"
  • Network accessline 173
    "https://api.coinmarketcap.com/data-api/v3/global-metrics/quotes/latest"
  • Network accessline 206
    # Daily candles for BTC over last 7 days resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/historical"
  • Network accessline 207
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/historical"     f"?id=1&convertId=2781&timeStart={now - 7*86400}&timeEnd={now}&interval=daily"
  • Network accessline 208
    "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/historical"
  • Network accessline 236
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/market-pairs/latest"
  • Network accessline 237
    "https://api.coinmarketcap.com/data-api/v3/cryptocurrency/market-pairs/latest"
  • Network accessline 259
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/exchange/listing"
  • Network accessline 260
    "https://api.coinmarketcap.com/data-api/v3/exchange/listing"
  • Network accessline 277
    # Convert 1 BTC → USD resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/tools/price-conversion"
  • Network accessline 278
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/tools/price-conversion"     "?amount=1&id=1&convert_id=2781"
  • Network accessline 279
    "https://api.coinmarketcap.com/data-api/v3/tools/price-conversion"
  • Network accessline 286
    # Convert ETH → BTC resp2 = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/tools/price-conversion"
  • Network accessline 287
    resp2 = json.loads(http_get(     "https://api.coinmarketcap.com/data-api/v3/tools/price-conversion"     "?amount=1&id=1027&convert_id=1"
  • Network accessline 288
    "https://api.coinmarketcap.com/data-api/v3/tools/price-conversion"
  • Network accessline 304
    # News for a specific coin resp = json.loads(http_get(     "https://api.coinmarketcap.com/content/v3/news?coins=1&limit=10"
  • Network accessline 305
    resp = json.loads(http_get(     "https://api.coinmarketcap.com/content/v3/news?coins=1&limit=10" ))
  • Network accessline 306
    "https://api.coinmarketcap.com/content/v3/news?coins=1&limit=10"
  • Network accessline 329
    html = http_get("https://coinmarketcap.com/")
  • Network accessline 384
    html = http_get("https://coinmarketcap.com/currencies/bitcoin/")
  • Access to secretsline 441
    [Credential-related source omitted]

agent-workspace/domain-skills/costco/scraping.md

  • Network accessline 9
    - **Search results are not in the HTML.** `GET https://www.costco.com/s?keyword=...` from plain Python returned 200 (2.4 MB) with zero product ids and no JSON-LD. The grid is filled client-side by `POST https://gdx-api.costco.com/catalog/se
  • Network accessline 10
    - **A normal browser session works.** Open the search page in a browser, record the response of the page's own search call, and move to the next page with the site's pager URL (`&currentPage=2`). Each response has 24 results (title, brands,
  • Network accessline 11
    - **Product pages work with plain HTTP.** `GET https://www.costco.com/p/-/<slug>/<product_id>` returned 200 (about 2.7 MB) with a schema.org `Product` JSON-LD block (name, item number as `sku`, brand, rating, review count, price) and a `Bre
  • Network accessline 27
    if n > 1:         params["currentPage"] = n     return "https://www.costco.com/s?" + urllib.parse.urlencode(params)
  • Network accessline 29
    return "https://www.costco.com/s?" + urllib.parse.urlencode(params)
  • Network accessline 77
    url = js_retry("location.href") or ""         q = urllib.parse.parse_qs(urllib.parse.urlsplit(url).query)         if url.startswith("https://www.costco.com/s?") and q.get("keyword") == [QUERY]:
  • Network accessline 78
    q = urllib.parse.parse_qs(urllib.parse.urlsplit(url).query)         if url.startswith("https://www.costco.com/s?") and q.get("keyword") == [QUERY]:             seen = js_retry("(window.__costcoSearch || []).map((c, i) => ({i, status: c.stat
  • Network accessline 79
    if url.startswith("https://www.costco.com/s?") and q.get("keyword") == [QUERY]:
  • Network accessline 181
    "rating": 4.66,   "review_count": 2706,   "url": "https://www.costco.com/p/-/ninja-crispi-5-in-1-portable-glass-air-fry-cooking-system-3-containers--cover/4000376434",
  • Network accessline 182
    "review_count": 2706,   "url": "https://www.costco.com/p/-/ninja-crispi-5-in-1-portable-glass-air-fry-cooking-system-3-containers--cover/4000376434",   "category": "Appliances > Small Kitchen Appliances > Air Fryers",
  • Network accessline 183
    "url": "https://www.costco.com/p/-/ninja-crispi-5-in-1-portable-glass-air-fry-cooking-system-3-containers--cover/4000376434",
  • Network accessline 195
    "rating": 4.4,   "review_count": 5,   "url": "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",
  • Network accessline 196
    "review_count": 5,   "url": "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",   "category": "Appliances > Small Kitchen Appliances > Air Fryers",
  • Network accessline 197
    "url": "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",
  • Network accessline 211
    import email.utils, html, http.client, json, re, sys, time, urllib.error, urllib.request
  • Network accessline 214
    # Product URLs from the search rows (url field). Any https://www.costco.com/p/-/<slug>/<product_id>
  • Network accessline 215
    # or <slug>.product.<product_id>.html URL works. URLS = [     "https://www.costco.com/p/-/t-fal-dual-window-infrared-air-fryer-73qt-dual-heating/4000430818",
  • Network accessline 216
    URLS = [     "https://www.costco.com/p/-/t-fal-dual-window-infrared-air-fryer-73qt-dual-heating/4000430818",     "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",
  • Network accessline 217
    "https://www.costco.com/p/-/t-fal-dual-window-infrared-air-fryer-73qt-dual-heating/4000430818",
  • Network accessline 218
    "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",
  • Network accessline 219
    "https://www.costco.com/p/-/cuisinart-extra-large-26l-10-in-1-digital-air-fryer-oven/4000398962",
  • Network accessline 246
    wait = None         try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r:
  • Network accessline 247
    try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r:                 return r.status, r.read().decode("utf-8", "replace")
  • Network accessline 248
    with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r:
  • Network accessline 254
    raise RuntimeError(f"{url}: HTTP {e.code}; stopping")   # e.g. 403 = blocked: stop, do not work around it             wait, last = retry_after_seconds(e.headers.get("Retry-After")), f"HTTP {e.code}"         except (urllib.error.URLError, ht
  • Network accessline 255
    wait, last = retry_after_seconds(e.headers.get("Retry-After")), f"HTTP {e.code}"         except (urllib.error.URLError, http.client.IncompleteRead, TimeoutError, ConnectionError) as e:             last = repr(e)
  • Network accessline 256
    except (urllib.error.URLError, http.client.IncompleteRead, TimeoutError, ConnectionError) as e:
  • Network accessline 347
    {  "url": "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",
  • Network accessline 348
    "url": "https://www.costco.com/p/-/gourmia-9-qt-digital-air-fryer-with-ceramic-coating/4201032285",
  • Network accessline 360
    "specs": {"Brand": "Gourmia", "Capacity": "9 qt.", "Color": "Black", "Cord Length": "31.5 in.", "Dimensions - Depth": "16.2 in."},  "description": "Gourmia 9-Qt Digital Air Fryer with Ceramic Coating, Ceramic-Coated Basket and Crisper Tray,
  • Network accessline 361
    "description": "Gourmia 9-Qt Digital Air Fryer with Ceramic Coating, Ceramic-Coated Basket and Crisper Tray, 9 Cooking Presets Plus 3 Cu",  "image": "https://gdx-assets.costco.com/adobe/assets/urn:aaid:aem:859d2718-.../as/4201032285-847__1.
  • Network accessline 362
    "image": "https://gdx-assets.costco.com/adobe/assets/urn:aaid:aem:859d2718-.../as/4201032285-847__1.avif"
  • Network accessline 380
    | rating | `p.rating.averageRating`, rounded to 2 places | `4.4` | | review_count | `p.rating.ratingCount` | `5` | | url | `p.uri` | `https://www.costco.com/p/-/<slug>/<product_id>`; the tiles link to the equivalent `<slug>.product.<product
  • Network accessline 381
    | review_count | `p.rating.ratingCount` | `5` | | url | `p.uri` | `https://www.costco.com/p/-/<slug>/<product_id>`; the tiles link to the equivalent `<slug>.product.<product_id>.html` | | category | `p.categories[-1]` | `"Appliances > Small
  • Network accessline 382
    | url | `p.uri` | `https://www.costco.com/p/-/<slug>/<product_id>`; the tiles link to the equivalent `<slug>.product.<product_id>.html` |
  • Network accessline 431
    - **Plain HTTP search**: `https://www.costco.com/s?keyword=air+fryer` returned 200 but no product ids, ratings or prices in the HTML; results load client-side.

agent-workspace/domain-skills/coursera/scraping.md

  • Network accessline 24
    resp = http_get(     "https://api.coursera.org/api/courses.v1"
  • Network accessline 25
    "https://api.coursera.org/api/courses.v1"
  • Network accessline 44
    {"domainId": "business",         "subdomainId": "marketing"}   ],   "photoUrl": "https://d3njjcbhbojbot.cloudfront.net/api/utilities/v1/imageproxy/https://coursera-course-photos.s3.amazonaws.com/...",
  • Network accessline 45
    ],   "photoUrl": "https://d3njjcbhbojbot.cloudfront.net/api/utilities/v1/imageproxy/https://coursera-course-photos.s3.amazonaws.com/...",   "id":             "69Bku0KoEeWZtA4u62x6lQ",
  • Network accessline 46
    "photoUrl": "https://d3njjcbhbojbot.cloudfront.net/api/utilities/v1/imageproxy/https://coursera-course-photos.s3.amazonaws.com/...",
  • Network accessline 59
    Field notes: - `id` — opaque base64-ish string, stable identifier. Use for batch lookups and linking. - `slug` — URL-safe identifier. Course page: `https://www.coursera.org/learn/{slug}`
  • Network accessline 60
    - `id` — opaque base64-ish string, stable identifier. Use for batch lookups and linking. - `slug` — URL-safe identifier. Course page: `https://www.coursera.org/learn/{slug}` - `courseType` — always `"v2.ondemand"` for self-paced courses in 
  • Network accessline 61
    - `slug` — URL-safe identifier. Course page: `https://www.coursera.org/learn/{slug}`
  • Network accessline 82
    while True:         url = (             f"https://api.coursera.org/api/courses.v1"
  • Network accessline 83
    url = (             f"https://api.coursera.org/api/courses.v1"             f"?fields={base_fields}&limit={page_size}&start={start}"
  • Network accessline 84
    f"https://api.coursera.org/api/courses.v1"
  • Network accessline 106
    resp = http_get(     "https://api.coursera.org/api/partners.v1"
  • Network accessline 107
    "https://api.coursera.org/api/partners.v1"
  • Network accessline 121
    "shortName":   "penn",   "description": "The University of Pennsylvania (commonly referred to as Penn)...",   "squareLogo":  "http://coursera-university-assets.s3.amazonaws.com/.../logo.png"
  • Network accessline 122
    "description": "The University of Pennsylvania (commonly referred to as Penn)...",   "squareLogo":  "http://coursera-university-assets.s3.amazonaws.com/.../logo.png" }
  • Network accessline 123
    "squareLogo":  "http://coursera-university-assets.s3.amazonaws.com/.../logo.png"
  • Network accessline 130
    resp = http_get(     "https://api.coursera.org/api/partners.v1"
  • Network accessline 131
    "https://api.coursera.org/api/partners.v1"
  • Network accessline 144
    resp = http_get(     "https://api.coursera.org/api/onDemandSpecializations.v1"
  • Network accessline 145
    "https://api.coursera.org/api/onDemandSpecializations.v1"
  • Network accessline 176
    # Lookup specific instructors by ID resp = http_get(     "https://api.coursera.org/api/instructors.v1"
  • Network accessline 177
    resp = http_get(     "https://api.coursera.org/api/instructors.v1"     "?ids=226710&fields=fullName,bio,department,title,photo"
  • Network accessline 178
    "https://api.coursera.org/api/instructors.v1"
  • Network accessline 192
    "department": "Legal Studies and Business Ethics",   "bio":        "Kevin Werbach is professor of Legal Studies...",   "photo":      "https://d3njjcbhbojbot.cloudfront.net/api/utilities/v1/imageproxy/..."
  • Network accessline 193
    "bio":        "Kevin Werbach is professor of Legal Studies...",   "photo":      "https://d3njjcbhbojbot.cloudfront.net/api/utilities/v1/imageproxy/..." }
  • Network accessline 194
    "photo":      "https://d3njjcbhbojbot.cloudfront.net/api/utilities/v1/imageproxy/..."
  • Network accessline 205
    ids = ",".join(["69Bku0KoEeWZtA4u62x6lQ", "hOzhxVNuEfCW8Q55q1kSNQ", "0HiU7Oe4EeWTAQ4yevf_oQ"]) resp = http_get(     f"https://api.coursera.org/api/courses.v1"
  • Network accessline 206
    resp = http_get(     f"https://api.coursera.org/api/courses.v1"     f"?ids={ids}&fields=name,slug,description,primaryLanguages,workload,partnerIds"
  • Network accessline 207
    f"https://api.coursera.org/api/courses.v1"
  • Network accessline 233
    new_tab("https://www.coursera.org/search?query=machine+learning")
  • Network accessline 248
    html = http_get("https://www.coursera.org/learn/machine-learning")
  • Network accessline 281
    # Get course data from slug (need ID first — get it from catalog or search) # Pattern: enumerate catalog, match by slug resp = http_get("https://api.coursera.org/api/courses.v1?fields=name,slug,description&limit=100&start=0")
  • Network accessline 282
    # Pattern: enumerate catalog, match by slug resp = http_get("https://api.coursera.org/api/courses.v1?fields=name,slug,description&limit=100&start=0") data = json.loads(resp)
  • Network accessline 283
    resp = http_get("https://api.coursera.org/api/courses.v1?fields=name,slug,description&limit=100&start=0")

agent-workspace/domain-skills/craigslist/scraping.md

  • Network accessline 25
    https://{city}.craigslist.org/search/{category_code}?query=...
  • Network accessline 94
    # For-sale keyword search "https://sfbay.craigslist.org/search/sss?query=macbook&sort=rel"
  • Network accessline 95
    "https://sfbay.craigslist.org/search/sss?query=macbook&sort=rel"
  • Network accessline 97
    # Price-filtered electronics "https://sfbay.craigslist.org/search/ela?query=iphone&min_price=100&max_price=500"
  • Network accessline 98
    "https://sfbay.craigslist.org/search/ela?query=iphone&min_price=100&max_price=500"
  • Network accessline 100
    # Apartments, 2 bedrooms, price range "https://sfbay.craigslist.org/search/apa?bedrooms=2&min_price=1000&max_price=2500"
  • Network accessline 101
    "https://sfbay.craigslist.org/search/apa?bedrooms=2&min_price=1000&max_price=2500"
  • Network accessline 103
    # Cars by owner, Toyota "https://sfbay.craigslist.org/search/cto?auto_make_model=toyota"
  • Network accessline 104
    "https://sfbay.craigslist.org/search/cto?auto_make_model=toyota"
  • Network accessline 106
    # Jobs in another city "https://chicago.craigslist.org/search/jjj?query=python+developer"
  • Network accessline 107
    "https://chicago.craigslist.org/search/jjj?query=python+developer"
  • Network accessline 115
    <li class="cl-static-search-result" title="MacBook Air M2 256GB 8GB RAM">   <a href="https://sfbay.craigslist.org/sby/ele/d/san-jose-macbook-air-m2/7928508295.html">
  • Network accessline 116
    <a href="https://sfbay.craigslist.org/sby/ele/d/san-jose-macbook-air-m2/7928508295.html">
  • Network accessline 133
    URL pattern: `https://{city}.craigslist.org/{area}/{category_code}/d/{slug}/{post_id}.html`
  • Network accessline 143
    if min_price: params += f"&min_price={min_price}"     if max_price: params += f"&max_price={max_price}"     url = f"https://{city}.craigslist.org/search/{category}?{params}"
  • Network accessline 144
    if max_price: params += f"&max_price={max_price}"     url = f"https://{city}.craigslist.org/search/{category}?{params}"     headers = {"User-Agent": "Mozilla/5.0"}
  • Network accessline 145
    url = f"https://{city}.craigslist.org/search/{category}?{params}"
  • Network accessline 228
    # Images     images = re.findall(r'https://images\.craigslist\.org/[^\s"\']+_600x450\.jpg', html)
  • Network accessline 229
    images = re.findall(r'https://images\.craigslist\.org/[^\s"\']+_600x450\.jpg', html)
  • Network accessline 258
    "posted":   "2026-02-24T16:08:38-0800",     "body":     "I bought a new phone. These are brand new! Plz lmk if you are interested.",     "images":   ["https://images.craigslist.org/00e0e_xxx_600x450.jpg"],
  • Network accessline 259
    "body":     "I bought a new phone. These are brand new! Plz lmk if you are interested.",     "images":   ["https://images.craigslist.org/00e0e_xxx_600x450.jpg"],     "attrs":    {"condition": "like new", "make / manufacturer": "Apple", "mod
  • Network accessline 260
    "images":   ["https://images.craigslist.org/00e0e_xxx_600x450.jpg"],
  • Network accessline 289
    html = http_get("https://sfbay.craigslist.org/search/sss?query=laptop", headers={"User-Agent": "Mozilla/5.0"})

agent-workspace/domain-skills/crossref/scraping.md

  • Network accessline 3
    `https://api.crossref.org` — scholarly DOI and citation metadata. **Never use the browser for CrossRef.** Completely free, no auth required. All workflows use `http_get`.
  • Network accessline 15
    # Single DOI lookup — fastest way to get metadata for a known paper data = json.loads(http_get(f"https://api.crossref.org/works/10.1038/s41586-021-03819-2?{MAILTO}"))
  • Network accessline 16
    data = json.loads(http_get(f"https://api.crossref.org/works/10.1038/s41586-021-03819-2?{MAILTO}"))
  • Network accessline 32
    def fetch_work(doi):     data = json.loads(http_get(f"https://api.crossref.org/works/{doi}?{MAILTO}"))
  • Network accessline 33
    data = json.loads(http_get(f"https://api.crossref.org/works/{doi}?{MAILTO}"))
  • Network accessline 78
    MAILTO = "mailto=your@email.com" data = json.loads(http_get(f"https://api.crossref.org/works/10.1038/s41586-021-03819-2?{MAILTO}"))
  • Network accessline 79
    data = json.loads(http_get(f"https://api.crossref.org/works/10.1038/s41586-021-03819-2?{MAILTO}"))
  • Network accessline 83
    name = f"{a.get('given', '')} {a.get('family', '')}".strip()     # ORCID is a full URL, not a bare ID — strip the prefix     orcid_url = a.get('ORCID')  # e.g. 'https://orcid.org/0000-0001-6169-6580'
  • Network accessline 84
    # ORCID is a full URL, not a bare ID — strip the prefix     orcid_url = a.get('ORCID')  # e.g. 'https://orcid.org/0000-0001-6169-6580'     orcid_id = orcid_url.replace('https://orcid.org/', '') if orcid_url else None
  • Network accessline 85
    orcid_url = a.get('ORCID')  # e.g. 'https://orcid.org/0000-0001-6169-6580'
  • Network accessline 86
    orcid_id = orcid_url.replace('https://orcid.org/', '') if orcid_url else None
  • Network accessline 105
    def fetch_work(doi):     try:         data = json.loads(http_get(f"https://api.crossref.org/works/{doi}?{MAILTO}"))
  • Network accessline 106
    try:         data = json.loads(http_get(f"https://api.crossref.org/works/{doi}?{MAILTO}"))         msg = data['message']
  • Network accessline 107
    data = json.loads(http_get(f"https://api.crossref.org/works/{doi}?{MAILTO}"))
  • Network accessline 149
    # Broad keyword search data = json.loads(http_get(     f"https://api.crossref.org/works?query=machine+learning&rows=5&{MAILTO}"
  • Network accessline 150
    data = json.loads(http_get(     f"https://api.crossref.org/works?query=machine+learning&rows=5&{MAILTO}" ))
  • Network accessline 151
    f"https://api.crossref.org/works?query=machine+learning&rows=5&{MAILTO}"
  • Network accessline 172
    data = json.loads(http_get(     f"https://api.crossref.org/works?query.author=Lecun&query.title=deep+learning&rows=5&{MAILTO}"
  • Network accessline 173
    f"https://api.crossref.org/works?query.author=Lecun&query.title=deep+learning&rows=5&{MAILTO}"
  • Network accessline 196
    data = json.loads(http_get(     f"https://api.crossref.org/works"
  • Network accessline 197
    f"https://api.crossref.org/works"
  • Network accessline 221
    # Only return works that have an abstract (useful since ~30-70% do not) data = json.loads(http_get(     f"https://api.crossref.org/works"
  • Network accessline 222
    data = json.loads(http_get(     f"https://api.crossref.org/works"     f"?filter=from-pub-date:2023-01-01,until-pub-date:2023-12-31"
  • Network accessline 223
    f"https://api.crossref.org/works"
  • Network accessline 248
    # First page: cursor=* data = json.loads(http_get(     f"https://api.crossref.org/works?query=covid&rows=100&cursor=*&{MAILTO}"
  • Network accessline 249
    data = json.loads(http_get(     f"https://api.crossref.org/works?query=covid&rows=100&cursor=*&{MAILTO}" ))
  • Network accessline 250
    f"https://api.crossref.org/works?query=covid&rows=100&cursor=*&{MAILTO}"
  • Network accessline 258
    while next_cursor and items:     data = json.loads(http_get(         f"https://api.crossref.org/works?query=covid&rows=100"
  • Network accessline 259
    data = json.loads(http_get(         f"https://api.crossref.org/works?query=covid&rows=100"         f"&cursor={quote(next_cursor)}&{MAILTO}"
  • Network accessline 260
    f"https://api.crossref.org/works?query=covid&rows=100"
  • Network accessline 280
    data = json.loads(http_get(     f"https://api.crossref.org/works?query=cancer&rows=5"
  • Network accessline 281
    f"https://api.crossref.org/works?query=cancer&rows=5"
  • Network accessline 298
    data = json.loads(http_get(     f"https://api.crossref.org/works?query=machine+learning&rows=0"
  • Network accessline 299
    f"https://api.crossref.org/works?query=machine+learning&rows=0"
  • Network accessline 322
    # Nature (ISSN 0028-0836) data = json.loads(http_get(f"https://api.crossref.org/journals/0028-0836?{MAILTO}"))
  • Network accessline 323
    data = json.loads(http_get(f"https://api.crossref.org/journals/0028-0836?{MAILTO}"))
  • Network accessline 331
    # Search journals by name data2 = json.loads(http_get(f"https://api.crossref.org/journals?query=nature&rows=3&{MAILTO}"))
  • Network accessline 332
    data2 = json.loads(http_get(f"https://api.crossref.org/journals?query=nature&rows=3&{MAILTO}"))
  • Network accessline 348
    data = json.loads(http_get(     f"https://api.crossref.org/funders?query=national+science+foundation&rows=3&{MAILTO}"
  • Network accessline 349
    f"https://api.crossref.org/funders?query=national+science+foundation&rows=3&{MAILTO}"
  • Network accessline 369
    def doi_to_csl(doi):     """Fetch CSL-JSON via DOI content negotiation. Same data as CrossRef API."""     req = urllib.request.Request(
  • Network accessline 370
    """Fetch CSL-JSON via DOI content negotiation. Same data as CrossRef API."""     req = urllib.request.Request(         f"https://doi.org/{doi}",
  • Network accessline 371
    req = urllib.request.Request(
  • Network accessline 372
    f"https://doi.org/{doi}",
  • Network accessline 374
    "User-Agent": "Mozilla/5.0"}     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 375
    )     with urllib.request.urlopen(req, timeout=20) as r:         return json.loads(r.read().decode())
  • Network accessline 376
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 379
    def doi_to_bibtex(doi):     """Fetch BibTeX via DOI content negotiation."""     req = urllib.request.Request(
  • Network accessline 380
    """Fetch BibTeX via DOI content negotiation."""     req = urllib.request.Request(         f"https://doi.org/{doi}",
  • Network accessline 381
    req = urllib.request.Request(
  • Network accessline 382
    f"https://doi.org/{doi}",
  • Network accessline 383
    headers={"Accept": "application/x-bibtex", "User-Agent": "Mozilla/5.0"}     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 384
    )     with urllib.request.urlopen(req, timeout=20) as r:         return r.read().decode()
  • Network accessline 385
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 404
    |---|---|---| | `DOI` (R) | string | e.g. `"10.1038/s41586-021-03819-2"` | | `URL` (R) | string | `"https://doi.org/10.1038/s41586-021-03819-2"` |
  • Network accessline 405
    | `DOI` (R) | string | e.g. `"10.1038/s41586-021-03819-2"` | | `URL` (R) | string | `"https://doi.org/10.1038/s41586-021-03819-2"` | | `title` (R) | list[str] | Always a list; access `title[0]` |
  • Network accessline 406
    | `URL` (R) | string | `"https://doi.org/10.1038/s41586-021-03819-2"` |
  • Network accessline 447
    | `sequence` | `"first"` or `"additional"` | | `affiliation` | list of `{name, place}` — usually `[]` | | `ORCID` | Full URL `"https://orcid.org/0000-0001-..."` — strip prefix to get bare ID |
  • Network accessline 448
    | `affiliation` | list of `{name, place}` — usually `[]` | | `ORCID` | Full URL `"https://orcid.org/0000-0001-..."` — strip prefix to get bare ID | | `authenticated-orcid` | `true` = verified via ORCID OAuth; `false` = self-reported |
  • Network accessline 449
    | `ORCID` | Full URL `"https://orcid.org/0000-0001-..."` — strip prefix to get bare ID |
  • Network accessline 546
    - **ORCID is a full URL, not just the ID.** `a['ORCID']` = `"https://orcid.org/0000-0001-6169-6580"`. Strip with `.replace('https://orcid.org/', '')` to get the bare ID. `authenticated-orcid: false` means self-asserted (not verified via OAu

agent-workspace/domain-skills/ctrip/hotels.md

  • Network accessline 15
    - Once on a valid list page, prices render as `¥<original> ¥<current> 起`   pairs. No `¥?` placeholders and no `请登录` interstitial. - Detail URL `https://hotels.ctrip.com/hotel/<hotelId>.html?checkin=...` works
  • Network accessline 16
    pairs. No `¥?` placeholders and no `请登录` interstitial. - Detail URL `https://hotels.ctrip.com/hotel/<hotelId>.html?checkin=...` works   pre-login and shows full room-rate breakdown.
  • Network accessline 17
    - Detail URL `https://hotels.ctrip.com/hotel/<hotelId>.html?checkin=...` works
  • Network accessline 27
    List page (canonical, anonymous-friendly):   https://hotels.ctrip.com/hotels/list
  • Network accessline 28
    https://hotels.ctrip.com/hotels/list
  • Network accessline 37
    Hotel detail (canonical):   https://hotels.ctrip.com/hotel/<hotelId>.html?checkin=...&checkout=...
  • Network accessline 38
    https://hotels.ctrip.com/hotel/<hotelId>.html?checkin=...&checkout=...
  • Network accessline 41
    Login page (when reached unintentionally):   https://passport.ctrip.com/user/login?backurl=<url-encoded-target>
  • Network accessline 42
    https://passport.ctrip.com/user/login?backurl=<url-encoded-target>
  • Network accessline 45
    **Critical:** the *simplified* form `https://hotels.ctrip.com/hotels/list?city=2&checkin=...&checkout=...`
  • Network accessline 59
    import time url = (     "https://hotels.ctrip.com/hotels/list"
  • Network accessline 60
    url = (     "https://hotels.ctrip.com/hotels/list"     "?flexType=1&cityId=2&provinceId=0&districtId=0&countryId=1"
  • Network accessline 61
    "https://hotels.ctrip.com/hotels/list"
  • Network accessline 80
    new_tab("https://hotels.ctrip.com/")
  • Network accessline 160
    https://hotels.ctrip.com/hotel/<hotelId>.html?checkin=YYYY-MM-DD&checkout=YYYY-MM-DD
  • Network accessline 182
    https://passport.ctrip.com/user/login?backurl=...
  • Network accessline 260
    url = (     "https://hotels.ctrip.com/hotels/list"
  • Network accessline 261
    "https://hotels.ctrip.com/hotels/list"

agent-workspace/domain-skills/dev-to/scraping.md

  • Network accessline 3
    `https://dev.to` — developer blogging platform. Everything useful is available via a public REST API with no auth required. No browser needed for any read task.
  • Network accessline 10
    import json articles = json.loads(http_get("https://dev.to/api/articles?per_page=10&tag=python"))
  • Network accessline 11
    articles = json.loads(http_get("https://dev.to/api/articles?per_page=10&tag=python"))
  • Network accessline 30
    "Accept": "application/vnd.forem.api-v1+json",     }     with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=20) as r:
  • Network accessline 31
    }     with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=20) as r:         data = r.read()
  • Network accessline 32
    with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=20) as r:
  • Network accessline 38
    articles = json.loads(dev_get("https://dev.to/api/articles?per_page=10&tag=python"))
  • Network accessline 50
    import json articles = json.loads(http_get("https://dev.to/api/articles?per_page=10&tag=python"))
  • Network accessline 51
    articles = json.loads(http_get("https://dev.to/api/articles?per_page=10&tag=python"))
  • Network accessline 62
    import json # top=N means "top articles from the last N days" top_day   = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=1"))
  • Network accessline 63
    # top=N means "top articles from the last N days" top_day   = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=1")) top_week  = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=7"))
  • Network accessline 64
    top_day   = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=1"))
  • Network accessline 65
    top_week  = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=7"))
  • Network accessline 66
    top_month = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=30"))
  • Network accessline 67
    top_year  = json.loads(http_get("https://dev.to/api/articles?per_page=10&top=365"))
  • Network accessline 73
    import json articles = json.loads(http_get("https://dev.to/api/articles?per_page=10&username=ben"))
  • Network accessline 74
    articles = json.loads(http_get("https://dev.to/api/articles?per_page=10&username=ben"))
  • Network accessline 81
    import json fresh  = json.loads(http_get("https://dev.to/api/articles?per_page=10&state=fresh"))   # very new
  • Network accessline 82
    fresh  = json.loads(http_get("https://dev.to/api/articles?per_page=10&state=fresh"))   # very new
  • Network accessline 83
    rising = json.loads(http_get("https://dev.to/api/articles?per_page=10&state=rising"))  # gaining traction
  • Network accessline 90
    import json article = json.loads(http_get("https://dev.to/api/articles/3442047"))
  • Network accessline 91
    article = json.loads(http_get("https://dev.to/api/articles/3442047"))
  • Network accessline 101
    import json # path field from list response is "/username/slug" article = json.loads(http_get("https://dev.to/api/articles/ben/some-article-slug"))
  • Network accessline 103
    article = json.loads(http_get("https://dev.to/api/articles/ben/some-article-slug"))
  • Network accessline 109
    import json tags = json.loads(http_get("https://dev.to/api/tags?per_page=10"))
  • Network accessline 110
    tags = json.loads(http_get("https://dev.to/api/tags?per_page=10"))
  • Network accessline 123
    import json user = json.loads(http_get("https://dev.to/api/users/by_username?url=ben"))
  • Network accessline 124
    user = json.loads(http_get("https://dev.to/api/users/by_username?url=ben"))
  • Network accessline 136
    import json comments = json.loads(http_get("https://dev.to/api/comments?a_id=3442047"))
  • Network accessline 137
    comments = json.loads(http_get("https://dev.to/api/comments?a_id=3442047"))
  • Network accessline 150
    import json comment = json.loads(http_get("https://dev.to/api/comments/36lnc"))
  • Network accessline 151
    comment = json.loads(http_get("https://dev.to/api/comments/36lnc"))
  • Network accessline 155
    ### Bulk tag fetch (parallel)
  • Network accessline 164
    def fetch_tag(tag):     data = json.loads(http_get(f"https://dev.to/api/articles?per_page=5&tag={tag}"))
  • Network accessline 165
    data = json.loads(http_get(f"https://dev.to/api/articles?per_page=5&tag={tag}"))
  • Network accessline 201
    for page in range(1, max_pages + 1):         batch = json.loads(http_get(             f"https://dev.to/api/articles?per_page=30&tag={tag}&page={page}"
  • Network accessline 202
    batch = json.loads(http_get(             f"https://dev.to/api/articles?per_page=30&tag={tag}&page={page}"         ))
  • Network accessline 203
    f"https://dev.to/api/articles?per_page=30&tag={tag}&page={page}"
  • Access to secretsline 264
    [Credential-related source omitted]
  • Network accessline 283
    urls = [     f"https://dev.to/api/articles?per_page=10&tag={tag}"
  • Network accessline 284
    f"https://dev.to/api/articles?per_page=10&tag={tag}"

agent-workspace/domain-skills/dexscreener/scraping.md

  • Network accessline 3
    Field-tested against dexscreener.com and api.dexscreener.com on 2026-11-02 using a Browser Use cloud browser, logged out. API calls are `fetch()` from an api.dexscreener.com tab; New Pairs is read from the dexscreener.com page. No CAPTCHA, 
  • Network accessline 5
    robots.txt (fetched 2026-11-02 in the browser): dexscreener.com is `User-agent: *` / `Allow: /`; api.dexscreener.com has no robots.txt (HTTP 404) and is used under the official-API exception: it is DEX Screener's documented public API (http
  • Network accessline 13
    - `/latest/dex/pairs/<chainId>/<pair1>,<pair2>,...` - fresh numbers for known pairs; 30 per call worked. (300/min)   - `/token-boosts/latest/v1` and `/token-boosts/top/v1` - 30 rows each. (60/min) - **New pairs have no API endpoint.** Read 
  • Network accessline 14
    - `/token-boosts/latest/v1` and `/token-boosts/top/v1` - 30 rows each. (60/min) - **New pairs have no API endpoint.** Read the site's table at `https://dexscreener.com/new-pairs?rankBy=pairAge&order=asc` (what its "Newest" button sets): 100
  • Network accessline 15
    - **New pairs have no API endpoint.** Read the site's table at `https://dexscreener.com/new-pairs?rankBy=pairAge&order=asc` (what its "Newest" button sets): 100 rows per page, `/new-pairs/page-2?...` for more, `/new-pairs/<chainId>?...` for
  • Network accessline 21
    API blocks share the same helpers: `on_api_tab()` opens a tiny JSON answer on api.dexscreener.com once (later blocks reuse it), `get(path)` starts `fetch()` in that tab and polls for the result (big answers can take longer than `js()`'s 5 s
  • Network accessline 31
    API = "https://api.dexscreener.com" PER_MIN = {"slow": 60, "fast": 300}   # documented limits, requests per minute per endpoint group
  • Network accessline 38
    def on_api_tab():     """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 39
    """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 44
    pass     # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 45
    # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".     new_tab(API + "/token-pairs/v1/solana/x")
  • Network accessline 46
    # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 50
    START_JS = """(() => { window.__dx = null;   fetch(%s, {credentials: 'omit'})
  • Network accessline 51
    fetch(%s, {credentials: 'omit'})
  • Network accessline 143
    ],  "pair": "0xA43fe16908251ee70EF74718545e4FE6C5cCEc9f",  "url": "https://dexscreener.com/ethereum/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f",
  • Network accessline 144
    "pair": "0xA43fe16908251ee70EF74718545e4FE6C5cCEc9f",  "url": "https://dexscreener.com/ethereum/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f",  "base": "PEPE",
  • Network accessline 145
    "url": "https://dexscreener.com/ethereum/0xa43fe16908251ee70ef74718545e4fe6c5ccec9f",
  • Network accessline 179
    API = "https://api.dexscreener.com" PER_MIN = {"slow": 60, "fast": 300}   # documented limits, requests per minute per endpoint group
  • Network accessline 186
    def on_api_tab():     """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 187
    """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 192
    pass     # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 193
    # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".     new_tab(API + "/token-pairs/v1/solana/x")
  • Network accessline 194
    # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 198
    START_JS = """(() => { window.__dx = null;   fetch(%s, {credentials: 'omit'})
  • Network accessline 199
    fetch(%s, {credentials: 'omit'})
  • Network accessline 308
    ],  "pair": "C1MgLojNLWBKADvu9BHdtgzz1oZX4dZ5zGdGcgvvW8Wz",  "url": "https://dexscreener.com/solana/c1mglojnlwbkadvu9bhdtgzz1ozx4dz5zgdgcgvvw8wz",
  • Network accessline 309
    "pair": "C1MgLojNLWBKADvu9BHdtgzz1oZX4dZ5zGdGcgvvW8Wz",  "url": "https://dexscreener.com/solana/c1mglojnlwbkadvu9bhdtgzz1ozx4dz5zgdgcgvvw8wz",  "base": "JUP",
  • Network accessline 310
    "url": "https://dexscreener.com/solana/c1mglojnlwbkadvu9bhdtgzz1ozx4dz5zgdgcgvvw8wz",
  • Network accessline 340
    SITE = "https://dexscreener.com"
  • Network accessline 398
    API = "https://api.dexscreener.com" PER_MIN = {"slow": 60, "fast": 300}   # documented limits, requests per minute per endpoint group
  • Network accessline 405
    def on_api_tab():     """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 406
    """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 411
    pass     # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 412
    # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".     new_tab(API + "/token-pairs/v1/solana/x")
  • Network accessline 413
    # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 417
    START_JS = """(() => { window.__dx = null;   fetch(%s, {credentials: 'omit'})
  • Network accessline 418
    fetch(%s, {credentials: 'omit'})
  • Network accessline 543
    API = "https://api.dexscreener.com" PER_MIN = {"slow": 60, "fast": 300}   # documented limits, requests per minute per endpoint group
  • Network accessline 550
    def on_api_tab():     """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 551
    """All API calls run as same-origin fetch() in a logged-out api.dexscreener.com tab; reuse it if already there."""
  • Network accessline 556
    pass     # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 557
    # A tiny JSON answer ("[]"). Not the host root: its 'Cannot GET /' 404 page sends CSP default-src 'none',     # which makes every fetch() from that tab fail with "Failed to fetch".     new_tab(API + "/token-pairs/v1/solana/x")
  • Network accessline 558
    # which makes every fetch() from that tab fail with "Failed to fetch".
  • Network accessline 562
    START_JS = """(() => { window.__dx = null;   fetch(%s, {credentials: 'omit'})
  • Network accessline 563
    fetch(%s, {credentials: 'omit'})
  • Network accessline 694
    [Credential-related source omitted]
  • Network accessline 695
    [Credential-related source omitted]
  • Network accessline 696
    "url": "https://dexscreener.com/solana/8s4bnqezth1jp7mku747umr7ackcqdiv47fdqyndpump",
  • Network accessline 705
    "market_cap": 1042595,  "pair_created": "2026-11-01T22:28Z",  "pair_url": "https://dexscreener.com/solana/hcgpz2exv8sfcmvq9fjpbd71brljvzutd2avvv86gwbk",
  • Network accessline 706
    "pair_created": "2026-11-01T22:28Z",  "pair_url": "https://dexscreener.com/solana/hcgpz2exv8sfcmvq9fjpbd71brljvzutd2avvv86gwbk",  "links": [
  • Network accessline 707
    "pair_url": "https://dexscreener.com/solana/hcgpz2exv8sfcmvq9fjpbd71brljvzutd2avvv86gwbk",
  • Network accessline 708
    "links": [   "https://anakin.meme",   "https://x.com/AnakinMemeCoin"
  • Network accessline 709
    "https://anakin.meme",
  • Network accessline 710
    "https://x.com/AnakinMemeCoin"
  • Network accessline 741
    - **30-row caps.** Search, token-pairs and both boost lists returned exactly 30 rows for busy inputs (PEPE, JUP, SOL). There is no page parameter; do not reshape queries to get around it. Use `/tokens/v1` or `/latest/dex/pairs` when you alr
  • Network accessline 742
    - **Unknown inputs are not errors.** Unknown search text gives `{"pairs": []}`, an unknown token `[]`, an unknown pair `{"pairs": null, "pair": null}`, all HTTP 200. - **Do not open the API host root as the fetch tab.** `https://api.dexscre
  • Network accessline 743
    - **Do not open the API host root as the fetch tab.** `https://api.dexscreener.com/` is an HTTP 404 page with `Content-Security-Policy: default-src 'none'`, so every `fetch()` from it fails with `TypeError: Failed to fetch`. `on_api_tab()` 
  • Network accessline 747
    - **Plain HTTP:** `curl` to api.dexscreener.com answered 200 today; dexscreener.com answered `curl` with a Cloudflare "Just a moment..." 403, so the New Pairs page needs the browser. If the browser gets a challenge page, `open_site()` stops
  • Network accessline 749
    - **API terms** (https://docs.dexscreener.com/api/api-terms-and-conditions) forbid using the API to build a product that competes directly with DEX Screener.
  • Network accessline 753
    - **New pairs via the API:** no documented endpoint lists new pairs; this skill reads the robots-allowed `/new-pairs` page and only enriches its rows through the API. - **More than 30 search or token-pairs results:** not available from the 
  • Network accessline 755
    - **Untested:** `/token-profiles/latest/v1`, `/token-profiles/recent-updates/v1`, `/community-takeovers/latest/v1`, `/ads/latest/v1`, `/metas/*` and `/orders/v1/<chainId>/<tokenAddress>` are documented at 60/min but were not exercised here;

agent-workspace/domain-skills/dice/scraping.md

  • Network accessline 23
    import http.client, json, re, time, urllib.error, urllib.parse, urllib.request
  • Network accessline 25
    UA = "dice-jobs-research/1.0 (python-urllib; personal job search script)" BASE = "https://www.dice.com"
  • Network accessline 26
    BASE = "https://www.dice.com" MAX_PAGE = 25          # Dice's cap: pages past 25 come back as page 25. Hard stop. PAUSE_S = 2.0          # polite gap between page requests
  • Network accessline 27
    MAX_PAGE = 25          # Dice's cap: pages past 25 come back as page 25. Hard stop. PAUSE_S = 2.0          # polite gap between page requests DEADLINE_S = 120       # one budget per fetch(), across all attempts and backoff
  • Network accessline 28
    PAUSE_S = 2.0          # polite gap between page requests DEADLINE_S = 120       # one budget per fetch(), across all attempts and backoff DELAYS = (5, 15, 40)   # backoff between attempts, never after the last one
  • Network accessline 29
    DEADLINE_S = 120       # one budget per fetch(), across all attempts and backoff
  • Network accessline 52
    def fetch(url, attempts=4, deadline_s=DEADLINE_S):
  • Network accessline 64
    raise TimeoutError(f"{deadline_s}s deadline used up for {url}")         try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})
  • Network accessline 65
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})             with urllib.request.urlopen(req, timeout=min(30, left)) as r:
  • Network accessline 66
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})
  • Network accessline 67
    with urllib.request.urlopen(req, timeout=min(30, left)) as r:
  • Network accessline 71
    raise             err = f"HTTP {e.code}"         except (urllib.error.URLError, TimeoutError, ConnectionError, http.client.HTTPException) as e:
  • Network accessline 72
    err = f"HTTP {e.code}"         except (urllib.error.URLError, TimeoutError, ConnectionError, http.client.HTTPException) as e:             if i == attempts - 1:
  • Network accessline 73
    except (urllib.error.URLError, TimeoutError, ConnectionError, http.client.HTTPException) as e:
  • Network accessline 132
    if page > 1:             time.sleep(PAUSE_S)         jl = parse_joblist(fetch(search_url(keyword, location, page, filters)))
  • Network accessline 133
    time.sleep(PAUSE_S)         jl = parse_joblist(fetch(search_url(keyword, location, page, filters)))         meta = jl["meta"]
  • Network accessline 134
    jl = parse_joblist(fetch(search_url(keyword, location, page, filters)))
  • Network accessline 184
    {'status': 'partial', 'reason': 'max_pages=3 reached', 'total': 132, 'page_count': 7, 'pages_fetched': 3, 'collected': 60} {"title": "Python Developer - Houston, TX (Locals only)", "company": "Source Mantra Inc", "location": "Houston, Texas
  • Network accessline 185
    {"title": "Python Developer - Houston, TX (Locals only)", "company": "Source Mantra Inc", "location": "Houston, Texas, USA", "workplace": "On-Site", "employment_type": "Third Party, Contract", "posted": "2026-10-23T19:05:49Z", "salary": "$$
  • Network accessline 217
    if not parts:         raise ValueError("need a keyword or a location")     url = "https://www.dice.com/jobs/" + "-".join(parts) + "-jobs"
  • Network accessline 218
    raise ValueError("need a keyword or a location")     url = "https://www.dice.com/jobs/" + "-".join(parts) + "-jobs"     return url if page == 1 else f"{url}?page={page}"
  • Network accessline 219
    url = "https://www.dice.com/jobs/" + "-".join(parts) + "-jobs"
  • Network accessline 310
    {'status': 'partial', 'reason': 'max_pages=2 reached', 'total': 1588, 'pages_fetched': 2, 'collected': 40} {"title": "DevOps Engineer", "company": "Dexian DISYS", "location": "Charlotte, North Carolina, USA", "employment_type": "Contract", 
  • Network accessline 311
    {"title": "DevOps Engineer", "company": "Dexian DISYS", "location": "Charlotte, North Carolina, USA", "employment_type": "Contract", "posted": "2026-10-15T20:11:32Z", "url": "https://www.dice.com/job-detail/be07b58c-3595-4790-a5c4-fed0892f9
  • Network accessline 324
    import http.client, json, re, time, urllib.error, urllib.request
  • Network accessline 332
    def fetch(url, attempts=4, deadline_s=120):
  • Network accessline 340
    raise TimeoutError(f"{deadline_s}s deadline used up for {url}")         try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})
  • Network accessline 341
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})             with urllib.request.urlopen(req, timeout=min(30, left)) as r:
  • Network accessline 342
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "text/html"})
  • Network accessline 343
    with urllib.request.urlopen(req, timeout=min(30, left)) as r:
  • Network accessline 346
    if e.code not in (429, 500, 502, 503, 504) or i == attempts - 1:                 raise         except (urllib.error.URLError, TimeoutError, ConnectionError, http.client.HTTPException):
  • Network accessline 347
    raise         except (urllib.error.URLError, TimeoutError, ConnectionError, http.client.HTTPException):             if i == attempts - 1:
  • Network accessline 348
    except (urllib.error.URLError, TimeoutError, ConnectionError, http.client.HTTPException):
  • Network accessline 361
    def job_detail(detail_url):     html = fetch(detail_url)
  • Network accessline 362
    html = fetch(detail_url)
  • Network accessline 374
    # Take a fresh URL from a search page so this does not depend on one posting staying live. first = re.search(r'href="(/job-detail/[0-9a-f-]{36})"', fetch("https://www.dice.com/jobs/q-Python+Developer-jobs"))
  • Network accessline 375
    first = re.search(r'href="(/job-detail/[0-9a-f-]{36})"', fetch("https://www.dice.com/jobs/q-Python+Developer-jobs"))
  • Network accessline 376
    if not first:     raise RuntimeError("no job-detail link on the search page") jp = job_detail("https://www.dice.com" + first.group(1))
  • Network accessline 377
    raise RuntimeError("no job-detail link on the search page") jp = job_detail("https://www.dice.com" + first.group(1)) if jp is None:
  • Network accessline 378
    jp = job_detail("https://www.dice.com" + first.group(1))
  • Network accessline 387
    print(job_detail("https://www.dice.com/job-detail/00000000-0000-0000-0000-000000000000"))  # unknown guid
  • Network accessline 411
    | `postedDate` | `"2026-10-23T19:05:49Z"` | ISO 8601 UTC; `modifiedDate` also present | | `salary` | `"Depends on Experience"` | free text, key missing on some jobs | | `detailsPageUrl` | `"https://www.dice.com/job-detail/<guid>"` | absolut
  • Network accessline 412
    | `salary` | `"Depends on Experience"` | free text, key missing on some jobs | | `detailsPageUrl` | `"https://www.dice.com/job-detail/<guid>"` | absolute URL | | `guid` / `id` | UUID / 32-hex | `guid` is the detail-page id; use it to de-dup
  • Network accessline 413
    | `detailsPageUrl` | `"https://www.dice.com/job-detail/<guid>"` | absolute URL |

agent-workspace/domain-skills/discogs/scraping.md

  • Network accessline 9
    - **Use the official API first:** `https://api.discogs.com/releases/<id>`, `/masters/<id>`, `/masters/<id>/versions`, `/artists/<id>`, `/artists/<id>/releases`. JSON, no key. One release call has tracklist, labels + catalog numbers, formats
  • Network accessline 22
    API = "https://api.discogs.com" UA = f"browser-harness-discogs-skill/1.0 Python-urllib/{sys.version_info.major}.{sys.version_info.minor}"  # truthful, names the client
  • Network accessline 26
    def _robots_rules(base):     """Rules of the `User-agent: *` group, Google-style wildcards."""     txt = urllib.request.urlopen(urllib.request.Request(base + "/robots.txt", headers={"User-Agent": UA}), timeout=20).read().decode()
  • Network accessline 27
    """Rules of the `User-agent: *` group, Google-style wildcards."""     txt = urllib.request.urlopen(urllib.request.Request(base + "/robots.txt", headers={"User-Agent": UA}), timeout=20).read().decode()     rules, in_star, prev_ua = [], False
  • Network accessline 28
    txt = urllib.request.urlopen(urllib.request.Request(base + "/robots.txt", headers={"User-Agent": UA}), timeout=20).read().decode()
  • Network accessline 64
    _last[0] = time.time()         try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/vnd.discogs.v2.discogs+json"})
  • Network accessline 65
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/vnd.discogs.v2.discogs+json"})             with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 66
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/vnd.discogs.v2.discogs+json"})
  • Network accessline 67
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 167
    {"id": 249504, "artist": "Rick Astley", "title": "Never Gonna Give You Up", "year": 1987, "released": "1987-07-00", "country": "UK", "labels": [["RCA", "PB 41447", 895]], "formats": [{"name": "Vinyl", "qty": "1", "descriptions": ["7\"", "45
  • Network accessline 169
    {'pos': 'A', 'type': 'track', 'title': 'Never Gonna Give You Up', 'duration': '3:32'}     {'pos': 'B', 'type': 'track', 'title': 'Never Gonna Give You Up (Instrumental)', 'duration': '3:30'} {"id": 10398494, "artist": "Pink Floyd", "title":
  • Network accessline 170
    {'pos': 'B', 'type': 'track', 'title': 'Never Gonna Give You Up (Instrumental)', 'duration': '3:30'} {"id": 10398494, "artist": "Pink Floyd", "title": "Pink Floyd", "year": 1988, "released": "1988", "country": "Australia", "labels": [["EMI"
  • Network accessline 171
    {"id": 10398494, "artist": "Pink Floyd", "title": "Pink Floyd", "year": 1988, "released": "1988", "country": "Australia", "labels": [["EMI", "PFB1", 26126]], "formats": [{"name": "Vinyl", "qty": "12", "descriptions": ["LP"], "text": null}, 
  • Network accessline 199
    WWW = "https://www.discogs.com"
  • Network accessline 274
    if any(s in low for s in ("just a moment", "verify you are human", "access denied", "attention required")):             raise SystemExit(f"challenge on {href}: stop and back off, do not retry")         final = re.sub(r"^https://www\.discogs
  • Network accessline 275
    raise SystemExit(f"challenge on {href}: stop and back off, do not retry")         final = re.sub(r"^https://www\.discogs\.com", "", href)         if not robots_allowed(rules, final):
  • Network accessline 276
    final = re.sub(r"^https://www\.discogs\.com", "", href)
  • Network accessline 314
    robots: /release/249504 True | /release/add False | /release/stats/249504 False | /artist2 False {"id": 249504, "title": "Never Gonna Give You Up", "artists": [["Rick Astley", "", 72872]], "year": 1987, "released": "1987-07-00", "country": 
  • Network accessline 315
    {"id": 249504, "title": "Never Gonna Give You Up", "artists": [["Rick Astley", "", 72872]], "year": 1987, "released": "1987-07-00", "country": "UK", "labels": [["RCA", "PB 41447", 895]], "formats": [{"name": "Vinyl", "qty": "1", "descriptio
  • Network accessline 317
    {'pos': 'A', 'type': 'track', 'title': 'Never Gonna Give You Up', 'seconds': 212}     {'pos': 'B', 'type': 'track', 'title': 'Never Gonna Give You Up (Instrumental)', 'seconds': 210} {"id": 10398494, "title": "Pink Floyd", "artists": [["Pin
  • Network accessline 318
    {'pos': 'B', 'type': 'track', 'title': 'Never Gonna Give You Up (Instrumental)', 'seconds': 210} {"id": 10398494, "title": "Pink Floyd", "artists": [["Pink Floyd", "", 45467]], "year": 1988, "released": "1988", "country": "Australia", "labe
  • Network accessline 319
    {"id": 10398494, "title": "Pink Floyd", "artists": [["Pink Floyd", "", 45467]], "year": 1988, "released": "1988", "country": "Australia", "labels": [["EMI", "PFB1", 26126]], "formats": [{"name": "Vinyl", "qty": "12", "descriptions": ["LP"],
  • Network accessline 366
    - Community counts can differ by a few between the API and the page (`want` 388 vs 385 for 10398494 in the same hour); they are cached separately. - `api.discogs.com/database/search?q=...` answered HTTP 200 without a token on 2026-11-01 (59
  • Network accessline 367
    [Credential-related source omitted]
  • Network accessline 368
    - In-page `fetch("https://api.discogs.com/...")` from a www.discogs.com tab worked (CORS, HTTP 200), but the rate-limit headers are not readable cross-origin. Prefer block 1.

agent-workspace/domain-skills/doordash/search-and-product-pages.md

  • Network accessline 3
    The contributor tested `doordash.com` on 2026-09-26 through browser-harness with a logged-in desktop Chrome session. The contributor reports approximately 600 searches and 100 product pages. Each request uses in-page `fetch()` from an open 
  • Network accessline 4
    The contributor reports approximately 600 searches and 100 product pages. Each request uses in-page `fetch()` from an open `doordash.com` tab. The requests use the existing session and delivery address.
  • Network accessline 5
    Each request uses in-page `fetch()` from an open `doordash.com` tab.
  • Network accessline 118
    - `https://www.doordash.com/convenience/store/<store_id>/product/<item_id>` → redirects to
  • Network accessline 119
    `/convenience/store/<store_id>?product_id=<item_id>` and opens that product's modal at that store. - `https://www.doordash.com/browse/products/<dd_sic>` → `/products/<slug>/<dd_sic>`, the cross-store page. - `/convenience/store/<store_id>/i
  • Network accessline 120
    - `https://www.doordash.com/browse/products/<dd_sic>` → `/products/<slug>/<dd_sic>`, the cross-store page.

agent-workspace/domain-skills/duckduckgo/scraping.md

  • Network accessline 3
    `https://api.duckduckgo.com` — completely public, no auth, no API key. Returns Wikipedia-sourced abstracts, infoboxes, and instant answers for well-known entities, calculations, and utility queries. Not a search engine — it does not return 
  • Network accessline 27
    q = urllib.parse.quote(query)     raw = http_get(         f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&skip_disambig=1"
  • Network accessline 28
    raw = http_get(         f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&skip_disambig=1"     )
  • Network accessline 29
    f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&skip_disambig=1"
  • Network accessline 36
    print(data['Heading'])        # 'OpenAI' print(data['AbstractText'])   # 'OpenAI is an American artificial intelligence research...' print(data['AbstractURL'])    # 'https://en.wikipedia.org/wiki/OpenAI'
  • Network accessline 37
    print(data['AbstractText'])   # 'OpenAI is an American artificial intelligence research...' print(data['AbstractURL'])    # 'https://en.wikipedia.org/wiki/OpenAI' print(data['OfficialWebsite'])# 'https://openai.com/'
  • Network accessline 38
    print(data['AbstractURL'])    # 'https://en.wikipedia.org/wiki/OpenAI'
  • Network accessline 39
    print(data['OfficialWebsite'])# 'https://openai.com/'
  • Network accessline 44
    print(data['Type'])           # 'A' (was 'D' without skip_disambig) print(data['AbstractText'][:100])  # 'Elon Reeve Musk is a businessman...' print(data['Image'])          # '/i/be2a8644.jpg' — prepend https://duckduckgo.com
  • Network accessline 46
    print(data['Image'])          # '/i/be2a8644.jpg' — prepend https://duckduckgo.com
  • Network accessline 48
    # Full image URL img_url = f"https://duckduckgo.com{data['Image']}" if data['Image'] else None
  • Network accessline 49
    img_url = f"https://duckduckgo.com{data['Image']}" if data['Image'] else None
  • Network accessline 62
    q = urllib.parse.quote(query)     raw = http_get(         f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&no_redirect=1"
  • Network accessline 63
    raw = http_get(         f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&no_redirect=1"     )
  • Network accessline 64
    f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&no_redirect=1"
  • Network accessline 122
    Entity           # entity type: "company", "programming language", "person", etc. Heading          # entity display name Image            # relative path e.g. "/i/4d83768732377cf3.png" — prepend https://duckduckgo.com
  • Network accessline 123
    Heading          # entity display name Image            # relative path e.g. "/i/4d83768732377cf3.png" — prepend https://duckduckgo.com ImageHeight      # int or "" when no image
  • Network accessline 124
    Image            # relative path e.g. "/i/4d83768732377cf3.png" — prepend https://duckduckgo.com
  • Network accessline 128
    Infobox          # dict with "content" and "meta" lists, or "" if no infobox OfficialDomain   # e.g. "openai.com" — only for entities with a known website OfficialWebsite  # e.g. "https://openai.com/" — only when DDG knows it
  • Network accessline 129
    OfficialDomain   # e.g. "openai.com" — only for entities with a known website OfficialWebsite  # e.g. "https://openai.com/" — only when DDG knows it Redirect         # target URL when query is a bang (e.g. !g python) with no_redirect=1
  • Network accessline 130
    OfficialWebsite  # e.g. "https://openai.com/" — only when DDG knows it
  • Network accessline 144
    {     "FirstURL": "https://duckduckgo.com/Deep_learning",
  • Network accessline 145
    "FirstURL": "https://duckduckgo.com/Deep_learning",
  • Network accessline 163
    For A-type results, `RelatedTopics` are Wikipedia category links (e.g. `"American aerospace engineers"` pointing to `https://duckduckgo.com/c/...`). These are not web search results — they are DDG topic pages.
  • Network accessline 169
    {     "FirstURL": "https://www.apple.com/",
  • Network accessline 170
    "FirstURL": "https://www.apple.com/",
  • Network accessline 171
    "Icon": {"Height": 16, "URL": "/i/apple.com.ico", "Width": 16},     "Result": "<a href=\"https://www.apple.com/\">Official site</a>...",     "Text": "Official site"
  • Network accessline 172
    "Result": "<a href=\"https://www.apple.com/\">Official site</a>...",
  • Network accessline 176
    Icon URLs in `Results` are relative — prepend `https://duckduckgo.com`.
  • Network accessline 265
    **Image and Icon URLs are relative.** `data['Image']` is `/i/abc123.png`. Prepend `https://duckduckgo.com` to make it absolute. Same for Icon URLs in `RelatedTopics` and `Results`.
  • Network accessline 300
    q = urllib.parse.quote(query)     raw = http_get(         f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&skip_disambig=1"
  • Network accessline 301
    raw = http_get(         f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&skip_disambig=1"     )
  • Network accessline 302
    f"https://api.duckduckgo.com/?q={q}&format=json&no_html=1&skip_disambig=1"
  • Network accessline 313
    'entity': data['Entity'],         'official_website': data['OfficialWebsite'],         'image': f"https://duckduckgo.com{data['Image']}" if data['Image'] else None,
  • Network accessline 314
    'official_website': data['OfficialWebsite'],         'image': f"https://duckduckgo.com{data['Image']}" if data['Image'] else None,         'answer': data['Answer'] if isinstance(data['Answer'], str) else None,
  • Network accessline 315
    'image': f"https://duckduckgo.com{data['Image']}" if data['Image'] else None,
  • Network accessline 337
    # r['abstract'][:50]   == 'OpenAI is an American artificial intelligence res' # r['entity']          == 'company' # r['official_website']== 'https://openai.com/'
  • Network accessline 338
    # r['entity']          == 'company' # r['official_website']== 'https://openai.com/' # r['image']           == 'https://duckduckgo.com/i/fb410946942ab334.png'
  • Network accessline 339
    # r['official_website']== 'https://openai.com/'
  • Network accessline 340
    # r['image']           == 'https://duckduckgo.com/i/fb410946942ab334.png'
  • Network accessline 345
    # r['type']            == 'A' # r['entity']          == 'programming language' # r['official_website']== 'https://www.python.org/'
  • Network accessline 346
    # r['entity']          == 'programming language' # r['official_website']== 'https://www.python.org/' # r['infobox']['Paradigm'] == 'Multi-paradigm: object-oriented,...'
  • Network accessline 347
    # r['official_website']== 'https://www.python.org/'

agent-workspace/domain-skills/ebay/scraping.md

  • Access to secretsline 4
    [Credential-related source omitted]
  • Access to secretsline 8
    [Credential-related source omitted]
  • Network accessline 58
    html = safe_get("https://www.ebay.com/sch/i.html?_nkw=laptop&LH_BIN=1", HEADERS)
  • Network accessline 81
    https://www.ebay.com/sch/i.html?_nkw={query}&{filters}
  • Network accessline 86
    # Buy It Now only, sorted by lowest price "https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard&LH_BIN=1&_sop=15"
  • Network accessline 87
    "https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard&LH_BIN=1&_sop=15"
  • Network accessline 89
    # Auctions only "https://www.ebay.com/sch/i.html?_nkw=vintage+camera&LH_Auction=1"
  • Network accessline 90
    "https://www.ebay.com/sch/i.html?_nkw=vintage+camera&LH_Auction=1"
  • Network accessline 92
    # New condition only, page 2 "https://www.ebay.com/sch/i.html?_nkw=laptop&LH_ItemCondition=1000&_pgn=2"
  • Network accessline 93
    "https://www.ebay.com/sch/i.html?_nkw=laptop&LH_ItemCondition=1000&_pgn=2"
  • Network accessline 135
    https://www.ebay.com/itm/{listing_id}
  • Network accessline 151
    |------|---------| | Listing ID | `data-listingid=(\d+)` on the `<li>` | | Item URL | `href=(https://(?:www\.)?ebay\.com/itm/(\d+))` |
  • Network accessline 152
    | Listing ID | `data-listingid=(\d+)` on the `<li>` | | Item URL | `href=(https://(?:www\.)?ebay\.com/itm/(\d+))` | | Title | `s-card__title` > `su-styled-text primary` > text |
  • Network accessline 153
    | Item URL | `href=(https://(?:www\.)?ebay\.com/itm/(\d+))` |
  • Network accessline 187
    # Item URL (clean, no tracking params)         url_m = re.search(r'href=["\']?(https://(?:www\.)?ebay\.com/itm/(\d+))', card)
  • Network accessline 188
    url_m = re.search(r'href=["\']?(https://(?:www\.)?ebay\.com/itm/(\d+))', card)
  • Network accessline 233
    html = safe_get("https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard&LH_BIN=1&_sop=15", headers=HEADERS)
  • Network accessline 352
    html = safe_get("https://www.ebay.com/itm/167040158614", headers=HEADERS)
  • Network accessline 365
    #   'shipping':     'Free', #   'return_days':  30, #   'images':       ['https://i.ebayimg.com/images/g/vwsAAeSwEcFpw~hW/s-l1600.jpg', ...],  # 5 images
  • Network accessline 366
    #   'return_days':  30, #   'images':       ['https://i.ebayimg.com/images/g/vwsAAeSwEcFpw~hW/s-l1600.jpg', ...],  # 5 images #   'gtin13':       '097855189066',
  • Network accessline 367
    #   'images':       ['https://i.ebayimg.com/images/g/vwsAAeSwEcFpw~hW/s-l1600.jpg', ...],  # 5 images
  • Network accessline 404
    for page in range(1, 4):     url = f"https://www.ebay.com/sch/i.html?_nkw=laptop&LH_BIN=1&_sop=15&_pgn={page}"
  • Network accessline 405
    url = f"https://www.ebay.com/sch/i.html?_nkw=laptop&LH_BIN=1&_sop=15&_pgn={page}"
  • Network accessline 443
    # Step 1: Search html = safe_get(     "https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard&LH_BIN=1&_sop=15&LH_ItemCondition=1000",
  • Network accessline 444
    html = safe_get(     "https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard&LH_BIN=1&_sop=15&LH_ItemCondition=1000",     headers=HEADERS
  • Network accessline 445
    "https://www.ebay.com/sch/i.html?_nkw=mechanical+keyboard&LH_BIN=1&_sop=15&LH_ItemCondition=1000",
  • Network accessline 480
    - **Item URLs have tracking params** — Raw extracted URLs look like `https://www.ebay.com/itm/167040158614?_skw=...&epid=...&hash=...&itmprp=...`. Always strip to `itm/{id}` with `.split('?')[0]`.
  • Network accessline 488
    - **Condition in JSON-LD is a schema.org URL** — `offers.itemCondition` returns `"https://schema.org/RefurbishedCondition"`, not a human label. Split on `/` and map the last segment using `CONDITION_MAP` (see `extract_item_detail` above).

agent-workspace/domain-skills/espn/scraping.md

  • Network accessline 23
    BASE = "https://www.espn.com"
  • Network accessline 26
    # longest matching pattern wins, Allow wins a tie. def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 27
    def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()     rules, in_star, prev_ua = [], False, False
  • Network accessline 28
    txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()

agent-workspace/domain-skills/etsy/scraping.md

  • Network accessline 18
    Etsy uses [DataDome](https://datadome.co/) for every user-facing HTML endpoint.
  • Network accessline 38
    <script>var dd={'rt':'c','cid':'...','hsh':'D013AA...','t':'bv',     'host':'geo.captcha-delivery.com','cookie':'...'}</script>   <script src="https://ct.captcha-delivery.com/c.js"></script>
  • Network accessline 39
    'host':'geo.captcha-delivery.com','cookie':'...'}</script>   <script src="https://ct.captcha-delivery.com/c.js"></script> </body>
  • Network accessline 40
    <script src="https://ct.captcha-delivery.com/c.js"></script>
  • Network accessline 78
    from helpers import http_get text = http_get("https://www.etsy.com/robots.txt")
  • Network accessline 79
    text = http_get("https://www.etsy.com/robots.txt")
  • Network accessline 87
    The `openapi.etsy.com/v3/` endpoint is NOT DataDome-protected. It returns structured JSON but requires a free API key from [developer.etsy.com](https://developer.etsy.com/).
  • Access to secretsline 93
    [Credential-related source omitted]
  • Network accessline 96
    from urllib.parse import urlencode     qs = urlencode(params)     url = f"https://openapi.etsy.com/v3/application/{path}?{qs}"
  • Network accessline 97
    [Credential-related source omitted]
  • Network accessline 98
    url = f"https://openapi.etsy.com/v3/application/{path}?{qs}"
  • Access to secretsline 99
    [Credential-related source omitted]
  • Network accessline 141
    results[i].shipping_profile_id → int   results[i].shop_id           → int   results[i].url               → "https://www.etsy.com/listing/..."
  • Network accessline 142
    results[i].shop_id           → int   results[i].url               → "https://www.etsy.com/listing/..."   results[i].views             → int
  • Network accessline 143
    results[i].url               → "https://www.etsy.com/listing/..."
  • Network accessline 166
    # Always use new_tab() for the first Etsy navigation in a session tid = new_tab("https://www.etsy.com/search?q=handmade+candle&explicit=1")
  • Network accessline 167
    tid = new_tab("https://www.etsy.com/search?q=handmade+candle&explicit=1")
  • Network accessline 175
    https://www.etsy.com/search?q={query}&explicit=1
  • Network accessline 226
    # ld_json_str.itemListElement is a list of:     # { '@type': 'ListItem', 'position': 1,     #   'url': 'https://www.etsy.com/listing/...', 'name': 'Handmade Soy Candle' }
  • Network accessline 227
    # { '@type': 'ListItem', 'position': 1,     #   'url': 'https://www.etsy.com/listing/...', 'name': 'Handmade Soy Candle' }     for item in ld_json_str.get('itemListElement', []):
  • Network accessline 228
    #   'url': 'https://www.etsy.com/listing/...', 'name': 'Handmade Soy Candle' }
  • Network accessline 235
    1  https://www.etsy.com/listing/1234567890/handmade-soy-candle  "Handmade Soy Candle"
  • Network accessline 236
    2  https://www.etsy.com/listing/0987654321/beeswax-pillar-candle  "Beeswax Pillar Candle"
  • Network accessline 243
    goto_url("https://www.etsy.com/listing/1234567890/product-slug")
  • Network accessline 264
    # product['offers']['price']         → e.g. "25.99" # product['offers']['priceCurrency'] → "USD" # product['offers']['availability']  → "http://schema.org/InStock"
  • Network accessline 265
    # product['offers']['priceCurrency'] → "USD" # product['offers']['availability']  → "http://schema.org/InStock" # product['brand']['name']           → shop name (seller)
  • Network accessline 266
    # product['offers']['availability']  → "http://schema.org/InStock"
  • Network accessline 295
    goto_url("https://www.etsy.com/shop/ShopName")
  • Network accessline 350
    # Or construct directly: goto_url(f"https://www.etsy.com/search?q=handmade+candle&explicit=1&page={page_num}")
  • Network accessline 351
    goto_url(f"https://www.etsy.com/search?q=handmade+candle&explicit=1&page={page_num}")
  • Network accessline 381
    "description": "These beautiful hand-dipped candles...",   "image": [     "https://i.etsystatic.com/12345678/r/il/abc123/1234567890/il_1588xN.1234567890.jpg"
  • Network accessline 382
    "image": [     "https://i.etsystatic.com/12345678/r/il/abc123/1234567890/il_1588xN.1234567890.jpg"   ],
  • Network accessline 383
    "https://i.etsystatic.com/12345678/r/il/abc123/1234567890/il_1588xN.1234567890.jpg"
  • Network accessline 388
    "price": "32.00",     "priceCurrency": "USD",     "availability": "http://schema.org/InStock",
  • Network accessline 389
    "priceCurrency": "USD",     "availability": "http://schema.org/InStock",     "url": "https://www.etsy.com/listing/1234567890/..."
  • Network accessline 390
    "availability": "http://schema.org/InStock",
  • Network accessline 391
    "url": "https://www.etsy.com/listing/1234567890/..."
  • Network accessline 410
    "@type": "ListItem",       "position": 1,       "url": "https://www.etsy.com/listing/1234567890/handmade-beeswax-candle",
  • Network accessline 411
    "position": 1,       "url": "https://www.etsy.com/listing/1234567890/handmade-beeswax-candle",       "name": "Handmade Beeswax Taper Candles, Set of 12"
  • Network accessline 412
    "url": "https://www.etsy.com/listing/1234567890/handmade-beeswax-candle",
  • Network accessline 425
    The official API at `openapi.etsy.com/v3/` bypasses DataDome entirely. It requires a free API key from [developer.etsy.com](https://developer.etsy.com/) (no payment needed; approval is automatic for basic read access).
  • Access to secretsline 460
    [Credential-related source omitted]
  • Network accessline 465
    limit = 100     while offset < max_results:         url = (f"https://openapi.etsy.com/v3/application/listings/active"
  • Network accessline 466
    while offset < max_results:         url = (f"https://openapi.etsy.com/v3/application/listings/active"                f"?keywords={keywords}&limit={limit}&offset={offset}"
  • Network accessline 467
    url = (f"https://openapi.etsy.com/v3/application/listings/active"
  • Access to secretsline 470
    [Credential-related source omitted]
  • Network accessline 486
    - **DataDome detects TLS fingerprint.** The challenge runs JavaScript at `geo.captcha-delivery.com`. Even curl with perfect browser headers returns 403 — the HTTP library's TLS handshake is fingerprinted.
  • Network accessline 492
    - **Listing slug is optional.** `https://www.etsy.com/listing/1234567890` works without the slug; Etsy redirects to the canonical URL with the full slug.

agent-workspace/domain-skills/eventbrite/scraping.md

  • Network accessline 3
    `https://www.eventbrite.com` — public event listings and detail pages, no auth required for HTML scraping. REST API requires an OAuth token.
  • Network accessline 12
    headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"} html = http_get("https://www.eventbrite.com/d/ca--san-francisco/tech/", headers=headers)
  • Network accessline 13
    html = http_get("https://www.eventbrite.com/d/ca--san-francisco/tech/", headers=headers)
  • Network accessline 33
    https://www.eventbrite.com/d/{location}/{category}/
  • Network accessline 34
    https://www.eventbrite.com/d/{location}/{category}/?page=2
  • Network accessline 35
    https://www.eventbrite.com/d/{location}/{category}/?start_date=2026-05-01&end_date=2026-05-31
  • Network accessline 71
    https://www.eventbrite.com/e/{slug}-tickets-{event_id}
  • Network accessline 74
    Example: `https://www.eventbrite.com/e/icontact-the-tactile-tech-opera-tickets-1982861003639`
  • Network accessline 92
    "name": "iContact the tactile tech opera",     "description": "An immersive performance...",     "url": "https://www.eventbrite.com/e/icontact-the-tactile-tech-opera-tickets-1982861003639",
  • Network accessline 93
    "description": "An immersive performance...",     "url": "https://www.eventbrite.com/e/icontact-the-tactile-tech-opera-tickets-1982861003639",     "image": "https://img.evbuc.com/...",
  • Network accessline 94
    "url": "https://www.eventbrite.com/e/icontact-the-tactile-tech-opera-tickets-1982861003639",
  • Network accessline 95
    "image": "https://img.evbuc.com/...",
  • Network accessline 96
    "startDate": "2026-06-21",     "endDate": "2026-06-21",     "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  • Network accessline 97
    "endDate": "2026-06-21",     "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",     "location": {
  • Network accessline 98
    "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  • Network accessline 131
    headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"} html = http_get("https://www.eventbrite.com/e/icontact-the-tactile-tech-opera-tickets-1982861003639", headers=headers)
  • Network accessline 132
    html = http_get("https://www.eventbrite.com/e/icontact-the-tactile-tech-opera-tickets-1982861003639", headers=headers)
  • Network accessline 143
    print(event_data['startDate'])         # "2026-06-21T17:05:00-07:00"  (ISO 8601 with TZ) print(event_data['endDate'])           # "2026-06-21T20:08:00-07:00" print(event_data['eventStatus'])       # "https://schema.org/EventScheduled"
  • Network accessline 144
    print(event_data['endDate'])           # "2026-06-21T20:08:00-07:00" print(event_data['eventStatus'])       # "https://schema.org/EventScheduled" print(event_data['eventAttendanceMode'])  # "https://schema.org/OfflineEventAttendanceMode"
  • Network accessline 145
    print(event_data['eventStatus'])       # "https://schema.org/EventScheduled"
  • Network accessline 146
    print(event_data['eventAttendanceMode'])  # "https://schema.org/OfflineEventAttendanceMode"
  • Network accessline 148
    print(event_data['location']['address']['streetAddress'])   # "94107 1661 Tennessee Street, San Francisco, CA 94107" print(event_data['organizer']['name'])  # "Beth McNamara" print(event_data['organizer']['url'])   # "https://www.eventbrite
  • Network accessline 150
    print(event_data['organizer']['url'])   # "https://www.eventbrite.com/o/beth-mcnamara-120755148166"
  • Network accessline 268
    """Returns list of event dicts with name, url, startDate, endDate, location."""     headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"}     url = f"https://www.eventbrite.com/d/{location}/{category
  • Network accessline 269
    headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"}     url = f"https://www.eventbrite.com/d/{location}/{category}/?page={page}"     html = http_get(url, headers=headers)
  • Network accessline 270
    url = f"https://www.eventbrite.com/d/{location}/{category}/?page={page}"
  • Network accessline 319
    The Eventbrite REST API (`https://www.eventbriteapi.com/v3/`) requires an OAuth token for all endpoints:
  • Access to secretsline 329
    [Credential-related source omitted]
  • Network accessline 332
    [Credential-related source omitted]
  • Network accessline 334
    data = json.loads(http_get(f"https://www.eventbriteapi.com/v3/events/{event_id}/", headers=headers))
  • Network accessline 341
    - **`re.findall(r'href="https://www.eventbrite.com/e/...')` returns 0 results** — Confirmed: event cards in the HTML do not have `https://www.eventbrite.com/e/` in href attributes. Use JSON-LD extraction only.

agent-workspace/domain-skills/expedia/api.md

  • Network accessline 9
    GET https://www.expedia.mx/api/v4/typeahead/{url-encoded query}
  • Network accessline 25
    - Canonical shape: `https://www.expedia.mx/{slug}.h{hotelId}.Informacion-Hotel`
  • Network accessline 30
    `rm1=a{adults}[:c{age}...]` (e.g. `rm1=a2:c8:c5`), `expediaPropertyId={id}`.   These pre-fill dates and occupancy on the page. - Search fallback: `https://www.expedia.mx/Hotel-Search?destination={name},
  • Network accessline 31
    These pre-fill dates and occupancy on the page. - Search fallback: `https://www.expedia.mx/Hotel-Search?destination={name},   {city}&startDate=…&endDate=…&adults=N&rooms=1`.
  • Network accessline 32
    - Search fallback: `https://www.expedia.mx/Hotel-Search?destination={name},
  • Network accessline 37
    `GET` on property pages returned HTTP 429 from a residential-but-curl client
  • Network accessline 59
    - To mint these programmatically, don't reconstruct the chain — use the   Travelpayouts links API:   `POST https://api.travelpayouts.com/links/v1/create` with
  • Network accessline 60
    Travelpayouts links API:   `POST https://api.travelpayouts.com/links/v1/create` with   `{"trs": <project id>, "marker": <partner id>, "shorten": true,
  • Network accessline 61
    `POST https://api.travelpayouts.com/links/v1/create` with

agent-workspace/domain-skills/expedia/automation.md

  • Network accessline 20
    https://www.expedia.co.in/Hotel-Search?destination={DEST}&startDate={YYYY-MM-DD}&endDate={YYYY-MM-DD}&rooms={N}&adults={N}&children={N}&childrenAges={age1,age2,...}
  • Network accessline 26
    goto("https://www.expedia.co.in/Hotel-Search?"

agent-workspace/domain-skills/expedia/flights-search.md

  • Network accessline 31
    https://www.expedia.ca/Flights-Search?flight-type=roundtrip&mode=search&trip=roundtrip&leg1=from:YYZ,to:ICN,departure:2027/07/03TANYT&leg2=from:ICN,to:YYZ,departure:2027/07/25TANYT&passengers=adults:1&options=cabin:economy&sort=price%3Aa
  • Network accessline 47
    search_url = "https://www.expedia.ca/Flights-Search?flight-type=roundtrip&mode=search&trip=roundtrip&leg1=from:YYZ,to:ICN,departure:2027/07/03TANYT&leg2=from:ICN,to:YYZ,departure:2027/07/25TANYT&passengers=adults:1&options=cabin:economy&sor
  • Network accessline 62
    When navigating to `https://www.expedia.ca/Flights` directly, the page has:

agent-workspace/domain-skills/facebook/groups.md

  • Network accessline 19
    | What | URL | |------|-----| | Group main feed | `https://www.facebook.com/groups/{id_or_slug}` |
  • Network accessline 20
    |------|-----| | Group main feed | `https://www.facebook.com/groups/{id_or_slug}` | | Group "Discussion" tab (canonical feed) | `https://www.facebook.com/groups/{id_or_slug}/?sorting_setting=CHRONOLOGICAL` |
  • Network accessline 21
    | Group main feed | `https://www.facebook.com/groups/{id_or_slug}` |
  • Network accessline 22
    | Group "Discussion" tab (canonical feed) | `https://www.facebook.com/groups/{id_or_slug}/?sorting_setting=CHRONOLOGICAL` |
  • Network accessline 23
    | Single post (permalink) | `https://www.facebook.com/groups/{id_or_slug}/posts/{post_id}/` |
  • Network accessline 24
    | User's joined-groups feed | `https://www.facebook.com/groups/feed/` |
  • Network accessline 25
    | List of YOUR groups | `https://www.facebook.com/groups/joins/` |
  • Network accessline 41
    | Post author | `h3 a, h4 a` (first inside the article) | Falls back to `strong a` | | Post timestamp | `a[href*="/posts/"] abbr, a[role="link"] > span > span` (relative time text) | Hover gets the absolute time but the relative string is f
  • Network accessline 42
    | Post timestamp | `a[href*="/posts/"] abbr, a[role="link"] > span > span` (relative time text) | Hover gets the absolute time but the relative string is fine for sorting | | External link (FB redirector) | `a[href^="https://l.facebook.com/
  • Network accessline 43
    | External link (FB redirector) | `a[href^="https://l.facebook.com/l.php?u="]` | Decode the `u=` param to get the real URL |
  • Network accessline 65
    const author = el.querySelector('h3 a, h4 a, strong a');         const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]'))
  • Network accessline 66
    const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]'))           .map(a => a.href);
  • Network accessline 67
    const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]'))
  • Network accessline 92
    Every external link gets wrapped in `https://l.facebook.com/l.php?u={URL-encoded real URL}&h=...`.
  • Network accessline 96
    from urllib.parse import urlparse, parse_qs, unquote def decode_fb_link(href):     if not href.startswith("https://l.facebook.com/l.php"):
  • Network accessline 97
    def decode_fb_link(href):     if not href.startswith("https://l.facebook.com/l.php"):         return href
  • Network accessline 98
    if not href.startswith("https://l.facebook.com/l.php"):
  • Network accessline 154
    body_preview_a: document.querySelectorAll('div[data-ad-preview="message"]').length,     body_preview_b: document.querySelectorAll('div[data-ad-comet-preview="message"]').length,     external_redirectors: document.querySelectorAll('a[href^="
  • Network accessline 155
    body_preview_b: document.querySelectorAll('div[data-ad-comet-preview="message"]').length,     external_redirectors: document.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]').length,     permalink_posts: document.querySelectorA
  • Network accessline 156
    external_redirectors: document.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]').length,
  • Network accessline 178
    goto_url(f"https://www.facebook.com/groups/{GROUP}/?sorting_setting=CHRONOLOGICAL")
  • Network accessline 193
    const author = el.querySelector('h3 a, h4 a, strong a');         const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]')).ma
  • Network accessline 194
    const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]')).map(a => a.href);         return { url: link?.href, author: author?
  • Network accessline 195
    const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]')).map(a => a.href);
  • Network accessline 207
    def decode(u):     if not u.startswith("https://l.facebook.com/l.php"): return u
  • Network accessline 208
    if not u.startswith("https://l.facebook.com/l.php"): return u

agent-workspace/domain-skills/facebook/pages.md

  • Network accessline 28
    | What | URL | |------|-----| | Page main feed (default tab) | `https://www.facebook.com/{vanity_or_id}` |
  • Network accessline 29
    |------|-----| | Page main feed (default tab) | `https://www.facebook.com/{vanity_or_id}` | | Page Posts tab (canonical post feed) | `https://www.facebook.com/{vanity_or_id}/posts` |
  • Network accessline 30
    | Page main feed (default tab) | `https://www.facebook.com/{vanity_or_id}` |
  • Network accessline 31
    | Page Posts tab (canonical post feed) | `https://www.facebook.com/{vanity_or_id}/posts` |
  • Network accessline 32
    | Page About | `https://www.facebook.com/{vanity_or_id}/about` |
  • Network accessline 33
    | Page Reviews | `https://www.facebook.com/{vanity_or_id}/reviews` |
  • Network accessline 34
    | Page Videos | `https://www.facebook.com/{vanity_or_id}/videos` |
  • Network accessline 35
    | Page Events | `https://www.facebook.com/{vanity_or_id}/events` |
  • Network accessline 36
    | Single post (vanity permalink) | `https://www.facebook.com/{vanity_or_id}/posts/pfbid{...}` |
  • Network accessline 37
    | Single post (legacy permalink) | `https://www.facebook.com/permalink.php?story_fbid={story_id}&id={page_id}` |
  • Network accessline 38
    | Single post (story permalink) | `https://www.facebook.com/story.php?story_fbid={story_id}&id={page_id}` |
  • Network accessline 39
    | Page-search (find a Page by name) | `https://www.facebook.com/search/pages/?q={query}` |
  • Network accessline 55
    | Follower/like count | `a[href$="/followers/"], a[href$="/friends_likes/"]` | Text node contains the count — parse with a regex | | Category line | `div[role="main"] span:has(a[href*="/pages/category/"])` | Sits under the name in the heade
  • Network accessline 56
    | Category line | `div[role="main"] span:has(a[href*="/pages/category/"])` | Sits under the name in the header | | Website link in header | `a[href^="https://l.facebook.com/l.php"][href*="u="]` inside the About rail | Same redirector wrappe
  • Network accessline 57
    | Website link in header | `a[href^="https://l.facebook.com/l.php"][href*="u="]` inside the About rail | Same redirector wrapper as post links — decode before using |
  • Network accessline 61
    | Post author | `h3 a, h4 a, strong a` | On a Page, this is always the Page itself — useful only for sanity checking you're still on the right Page | | Post timestamp | `a[href*="/posts/"] abbr, a[role="link"] > span > span` | Hover returns
  • Network accessline 62
    | Post timestamp | `a[href*="/posts/"] abbr, a[role="link"] > span > span` | Hover returns absolute time; relative string is fine for sorting | | External link (FB redirector) | `a[href^="https://l.facebook.com/l.php?u="]` | Decode the `u=`
  • Network accessline 63
    | External link (FB redirector) | `a[href^="https://l.facebook.com/l.php?u="]` | Decode the `u=` param |
  • Network accessline 83
    .find(a => /friends_likes$/.test(a.getAttribute('href')||''))?.innerText) || null,     category: (Array.from(document.querySelectorAll('a[href*="/pages/category/"]'))[0]?.innerText) || null,     website_redirector: (Array.from(document.quer
  • Network accessline 84
    category: (Array.from(document.querySelectorAll('a[href*="/pages/category/"]'))[0]?.innerText) || null,     website_redirector: (Array.from(document.querySelectorAll('a[href^="https://l.facebook.com/l.php"]'))       .find(a => !a.closest('d
  • Network accessline 85
    website_redirector: (Array.from(document.querySelectorAll('a[href^="https://l.facebook.com/l.php"]'))
  • Network accessline 107
    const body = el.querySelector('div[data-ad-preview="message"], div[data-ad-comet-preview="message"]');         const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[
  • Network accessline 108
    const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]'))           .map(a => a.href);
  • Network accessline 109
    const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]'))
  • Network accessline 136
    Identical to groups.md — every outbound link is wrapped in `https://l.facebook.com/l.php?u={URL-encoded real URL}&h=...`. Strip the wrapper.
  • Network accessline 137
    `https://l.facebook.com/l.php?u={URL-encoded real URL}&h=...`. Strip the wrapper.
  • Network accessline 140
    from urllib.parse import urlparse, parse_qs, unquote def decode_fb_link(href):     if not href.startswith("https://l.facebook.com/l.php"):
  • Network accessline 141
    def decode_fb_link(href):     if not href.startswith("https://l.facebook.com/l.php"):         return href
  • Network accessline 142
    if not href.startswith("https://l.facebook.com/l.php"):
  • Network accessline 183
    body_preview_a: document.querySelectorAll('div[data-ad-preview="message"]').length,     body_preview_b: document.querySelectorAll('div[data-ad-comet-preview="message"]').length,     external_redirectors: document.querySelectorAll('a[href^="
  • Network accessline 184
    body_preview_b: document.querySelectorAll('div[data-ad-comet-preview="message"]').length,     external_redirectors: document.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]').length,     pfbid_posts: document.querySelectorAll('
  • Network accessline 185
    external_redirectors: document.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]').length,
  • Network accessline 208
    goto_url(f"https://www.facebook.com/{PAGE}/posts")
  • Network accessline 222
    followers: (Array.from(document.querySelectorAll('a'))       .find(a => /followers$/.test(a.getAttribute('href')||''))?.innerText) || null,     website_redirector: (Array.from(document.querySelectorAll('a[href^="https://l.facebook.com/l.php
  • Network accessline 223
    .find(a => /followers$/.test(a.getAttribute('href')||''))?.innerText) || null,     website_redirector: (Array.from(document.querySelectorAll('a[href^="https://l.facebook.com/l.php"]'))       .find(a => !a.closest('div[role="article"]'))?.hr
  • Network accessline 224
    website_redirector: (Array.from(document.querySelectorAll('a[href^="https://l.facebook.com/l.php"]'))
  • Network accessline 236
    const body = el.querySelector('div[data-ad-preview="message"], div[data-ad-comet-preview="message"]');         const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[
  • Network accessline 237
    const time = el.querySelector('abbr, a[role="link"] > span > span');         const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]')).map(a => a.href);         return { url: link?.href, time: time?.inn
  • Network accessline 238
    const externals = Array.from(el.querySelectorAll('a[href^="https://l.facebook.com/l.php?u="]')).map(a => a.href);
  • Network accessline 252
    def decode(u):     if not u.startswith("https://l.facebook.com/l.php"): return u
  • Network accessline 253
    if not u.startswith("https://l.facebook.com/l.php"): return u

agent-workspace/domain-skills/feishu/docx-scraping.md

  • Possible obfuscationline 110
    t = t.replace("<U+200B>","").replace("<U+FEFF>","").replace("<U+2060>","")

agent-workspace/domain-skills/figma/comments.md

  • Network accessline 12
    GET https://www.figma.com/api/file/<FILE_KEY>/comments
  • Network accessline 19
    r = js(""" (async () => {   const response = await fetch("/api/file/<FILE_KEY>/comments");
  • Network accessline 20
    (async () => {   const response = await fetch("/api/file/<FILE_KEY>/comments");   if (!response.ok) throw new Error("Comments request failed: " + response.status);
  • Network accessline 21
    const response = await fetch("/api/file/<FILE_KEY>/comments");

agent-workspace/domain-skills/finviz/scraping.md

  • Network accessline 9
    - **Stock page** `https://finviz.com/stock?t=<T>` is server-rendered: 6 `table.js-snapshot-table` tables hold 84 label/value cells (valuation, growth, ownership, margins, technicals, performance), plus a header with company, sector, industr
  • Network accessline 80
    if not re.fullmatch(r"[A-Z0-9.\-]{1,10}", t):         raise ValueError(f"bad ticker {ticker!r}")     url = "https://finviz.com/stock?" + urllib.parse.urlencode({"t": t})
  • Network accessline 81
    raise ValueError(f"bad ticker {ticker!r}")     url = "https://finviz.com/stock?" + urllib.parse.urlencode({"t": t})     landed = urllib.parse.urlparse(fv_open(url))
  • Network accessline 82
    url = "https://finviz.com/stock?" + urllib.parse.urlencode({"t": t})
  • Network accessline 214
    raise ValueError(f"{signal}: not a robots.txt-allowed preset")     v = ALLOWED_PRESETS[signal]     url = f"https://finviz.com/screener/stocks?v={v}&s={signal}" + (f"&r={row}" if row > 1 else "")
  • Network accessline 215
    v = ALLOWED_PRESETS[signal]     url = f"https://finviz.com/screener/stocks?v={v}&s={signal}" + (f"&r={row}" if row > 1 else "")     landed = fv_open(url)
  • Network accessline 216
    url = f"https://finviz.com/screener/stocks?v={v}&s={signal}" + (f"&r={row}" if row > 1 else "")

agent-workspace/domain-skills/flighthub/flights-search.md

  • Network accessline 30
    https://www.flighthub.com/flight/search?seg0_from={ORIGIN}&seg0_to={DEST}&seg1_to={ORIGIN}&seg1_from={DEST}&seg0_date={YYYY-MM-DD}&seg1_date={YYYY-MM-DD}&order_by=cheapest&currency=cad&num_adults=1&num_children=0&num_infants=0&num_infants_l
  • Network accessline 53
    https://www.flighthub.com/flight/search?seg0_from=YYZ&seg0_to=ICN&seg1_to=YYZ&seg1_from=ICN&seg0_date=2027-07-03&seg1_date=2027-07-25&order_by=cheapest&currency=cad&num_adults=1&num_children=0&num_infants=0&num_infants_lap=0&type=roundtrip&
  • Network accessline 60
    When navigating to `https://www.flighthub.com/` directly, the page has an

agent-workspace/domain-skills/flipkart/shopping.md

  • Network accessline 22
    https://www.flipkart.com/search?q={query}&marketplace=FLIPKART&p%5B%5D=facets.price_range.from%3DMin&p%5B%5D=facets.price_range.to%3D{max_price}
  • Network accessline 28
    goto_url("https://www.flipkart.com/search?"
  • Network accessline 38
    goto_url("https://www.flipkart.com/search?"
  • Network accessline 236
    price: card.querySelector('div._30jeq3')?.innerText?.trim(),             rating: card.querySelector('div._3LWZlK')?.innerText?.trim(),             url: 'https://www.flipkart.com' + href,
  • Network accessline 237
    rating: card.querySelector('div._3LWZlK')?.innerText?.trim(),             url: 'https://www.flipkart.com' + href,         };
  • Network accessline 238
    url: 'https://www.flipkart.com' + href,
  • Network accessline 278
    9. **Category browse pages** — Use `sid` parameter for category navigation:    `https://www.flipkart.com/toys/pr?sid=tng` for toys. Combine with price
  • Network accessline 279
    `https://www.flipkart.com/toys/pr?sid=tng` for toys. Combine with price

agent-workspace/domain-skills/framer/editor.md

  • Network accessline 10
    URL shape: `https://framer.com/projects/<project-slug>-<id>` (teamId query param after login). The left rail is tab-driven; the right rail is context-sensitive.
  • Network accessline 80
    - **Drag-drop** — component insertion, layer reordering, cross-hierarchy moves. - **Smart Component variant switching** — the On Tap → Change Variant setup lives in a modal nested panel; no stable selector path. - **Property binding** (the 
  • Network accessline 81
    - **Smart Component variant switching** — the On Tap → Change Variant setup lives in a modal nested panel; no stable selector path. - **Property binding** (the chain icon on a code-component prop) — exposes only `Fetch (HTTP)` and `Create V
  • Network accessline 82
    - **Property binding** (the chain icon on a code-component prop) — exposes only `Fetch (HTTP)` and `Create Variable`; no CMS-field binding available from the UI, let alone scriptable.

agent-workspace/domain-skills/fred/scraping.md

  • Network accessline 3
    `https://fred.stlouisfed.org` / `https://api.stlouisfed.org` — the canonical source for US macroeconomic time series (800,000+ series). The REST API at `api.stlouisfed.org` requires a free registered key. The web endpoints at `fred.stlouisf
  • Network accessline 17
    # ALL OF THESE TIMEOUT — confirmed dead from headless HTTP: # https://fred.stlouisfed.org/graph/fredgraph.csv?id=GDP      ← timeout
  • Network accessline 18
    # https://fred.stlouisfed.org/graph/fredgraph.csv?id=GDP      ← timeout
  • Network accessline 19
    # https://fred.stlouisfed.org/graph/fredgraph.json?id=GDP     ← timeout
  • Network accessline 20
    # https://fred.stlouisfed.org/data/GDP.txt                    ← timeout
  • Network accessline 21
    # https://fred.stlouisfed.org/series/GDP                      ← timeout
  • Network accessline 26
    [Credential-related source omitted]
  • Access to secretsline 26
    [Credential-related source omitted]
  • Network accessline 40
    import json, os FRED_KEY = os.environ["FRED_KEY"]   # 32-char lowercase alphanumeric BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 41
    [Credential-related source omitted]
  • Network accessline 42
    BASE = "https://api.stlouisfed.org/fred"
  • Network accessline 48
    import json, os FRED_KEY = os.environ["FRED_KEY"] BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 49
    [Credential-related source omitted]
  • Network accessline 50
    BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 52
    [Credential-related source omitted]
  • Network accessline 69
    import json, os FRED_KEY = os.environ["FRED_KEY"] BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 70
    [Credential-related source omitted]
  • Network accessline 71
    BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 77
    [Credential-related source omitted]
  • Network accessline 98
    import json, os FRED_KEY = os.environ["FRED_KEY"] BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 99
    [Credential-related source omitted]
  • Network accessline 100
    BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 105
    [Credential-related source omitted]
  • Network accessline 144
    import json, os FRED_KEY = os.environ["FRED_KEY"] BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 145
    [Credential-related source omitted]
  • Network accessline 146
    BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 151
    [Credential-related source omitted]
  • Network accessline 167
    from concurrent.futures import ThreadPoolExecutor FRED_KEY = os.environ["FRED_KEY"] BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 168
    [Credential-related source omitted]
  • Network accessline 169
    BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 174
    [Credential-related source omitted]
  • Network accessline 197
    import json, os FRED_KEY = os.environ["FRED_KEY"] BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 198
    [Credential-related source omitted]
  • Network accessline 199
    BASE = "https://api.stlouisfed.org/fred"
  • Access to secretsline 202
    [Credential-related source omitted]
  • Network accessline 221
    [Credential-related source omitted]
  • Network accessline 222
    [Credential-related source omitted]
  • Access to secretsline 222
    [Credential-related source omitted]
  • Network accessline 235
    Bureau of Labor Statistics. Covers unemployment, CPI, payrolls — the most-queried FRED series. **Without a key: 10 requests/day limit.** Free key registration at `https://www.bls.gov/developers/` gives 500 req/day and 10 years of data per c
  • Network accessline 238
    import json # Single series GET — no auth needed r = http_get("https://api.bls.gov/publicAPI/v2/timeseries/data/LNS14000000?startyear=2024&endyear=2024")
  • Network accessline 239
    # Single series GET — no auth needed r = http_get("https://api.bls.gov/publicAPI/v2/timeseries/data/LNS14000000?startyear=2024&endyear=2024") data = json.loads(r)
  • Network accessline 240
    r = http_get("https://api.bls.gov/publicAPI/v2/timeseries/data/LNS14000000?startyear=2024&endyear=2024")
  • Network accessline 263
    req = urllib.request.Request(
  • Network accessline 264
    "https://api.bls.gov/publicAPI/v2/timeseries/data/",
  • Network accessline 266
    headers={"Content-Type": "application/json"} ) with urllib.request.urlopen(req, timeout=20) as resp:
  • Network accessline 267
    ) with urllib.request.urlopen(req, timeout=20) as resp:     data = json.loads(resp.read().decode())
  • Network accessline 268
    with urllib.request.urlopen(req, timeout=20) as resp:
  • Network accessline 309
    # Single country, single indicator r = http_get("https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD?format=json&per_page=5&mrv=5")
  • Network accessline 310
    r = http_get("https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD?format=json&per_page=5&mrv=5")
  • Network accessline 328
    # Historical range: date=YYYY:YYYY r = http_get("https://api.worldbank.org/v2/country/US/indicator/FP.CPI.TOTL.ZG?format=json&date=2015:2024&per_page=15")
  • Network accessline 329
    r = http_get("https://api.worldbank.org/v2/country/US/indicator/FP.CPI.TOTL.ZG?format=json&date=2015:2024&per_page=15")
  • Network accessline 339
    # Multi-country: semicolon-separated ISO codes r = http_get("https://api.worldbank.org/v2/country/US;CN;DE;JP;GB/indicator/NY.GDP.MKTP.CD?format=json&date=2023&per_page=10")
  • Network accessline 340
    r = http_get("https://api.worldbank.org/v2/country/US;CN;DE;JP;GB/indicator/NY.GDP.MKTP.CD?format=json&date=2023&per_page=10")
  • Network accessline 366
    Some economic indicators work with the `demo` key (no registration); most require a free registered key (25 requests/day, instant signup at `https://www.alphavantage.co/support/#api-key`).
  • Network accessline 372
    [Credential-related source omitted]
  • Network accessline 373
    [Credential-related source omitted]
  • Network accessline 405
    [Credential-related source omitted]
  • Network accessline 406
    [Credential-related source omitted]
  • Network accessline 414
    [Credential-related source omitted]
  • Network accessline 415
    [Credential-related source omitted]
  • Network accessline 427
    # Navigate to a series page goto_url("https://fred.stlouisfed.org/series/GDP")
  • Network accessline 428
    goto_url("https://fred.stlouisfed.org/series/GDP")

agent-workspace/domain-skills/frontier/checkout.md

  • Network accessline 9
    1. `https://www.flyfrontier.com/` — search widget (not a `<form>`; submit happens via `#btnSearch`).
  • Network accessline 10
    2. `https://booking.flyfrontier.com/Flight/Select` — fare grid + sticky "CONTINUE" summary footer.
  • Network accessline 11
    3. `https://booking.flyfrontier.com/Passengers/Edit` — passenger details + contact.
  • Network accessline 12
    4. `https://booking.flyfrontier.com/Bundles/Index` — upsell grid + "BUNDLE AND SAVE" confirmation modal.
  • Network accessline 13
    5. `https://booking.flyfrontier.com/SeatMap/Index` — seat map + "SELECT YOUR SEAT NOW" upsell.
  • Network accessline 14
    6. `https://booking.flyfrontier.com/Bags/Index` — carry-on / checked bag radios + carry-on upsell modal.
  • Network accessline 15
    7. `https://booking.flyfrontier.com/Extras/Add` — disruption assistance (Hopper iframe) + agent-assist radios.
  • Network accessline 16
    8. `https://booking.flyfrontier.com/Payment/New` — credit card + billing form.

agent-workspace/domain-skills/furnishedfinder/search.md

  • Network accessline 3
    Next.js App Router site. Listing search results are **server-rendered into the RSC payload** (`self.__next_f.push(...)` script tags). There is no XHR to intercept on first load, and the GraphQL endpoint (`https://cfw-edge-auth.furnishedfind
  • Network accessline 4
    (`self.__next_f.push(...)` script tags). There is no XHR to intercept on first load, and the GraphQL endpoint (`https://cfw-edge-auth.furnishedfinder.com/graphql`) rejects a plain in-page `fetch()` (CORS/auth). Read the payload instead.
  • Network accessline 5
    GraphQL endpoint (`https://cfw-edge-auth.furnishedfinder.com/graphql`) rejects a plain
  • Network accessline 6
    in-page `fetch()` (CORS/auth). Read the payload instead.
  • Network accessline 10
    - City page: `https://www.furnishedfinder.com/housing/us--ca--san-francisco` (region id

agent-workspace/domain-skills/g2/scraping.md

  • Network accessline 9
    Tested URLs (all 403): - `https://www.g2.com/products/slack/reviews`
  • Network accessline 10
    - `https://www.g2.com/products/slack/reviews`
  • Network accessline 11
    - `https://www.g2.com/categories/team-collaboration`
  • Network accessline 12
    - `https://www.g2.com/products/slack`
  • Network accessline 13
    - `https://www.g2.com/products/slack/reviews.json`
  • Network accessline 14
    - `https://www.g2.com/blog/` (and most `www.g2.com/*`)
  • Network accessline 32
    [Credential-related source omitted]
  • Access to secretsline 37
    [Credential-related source omitted]
  • Network accessline 39
    def g2_api_get(path, params=""):     url = f"https://data.g2.com/api/v1/{path}?{params}"     req = urllib.request.Request(url, headers={
  • Network accessline 40
    [Credential-related source omitted]
  • Network accessline 41
    req = urllib.request.Request(url, headers={
  • Access to secretsline 42
    [Credential-related source omitted]
  • Network accessline 44
    "Accept": "application/json",     })     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 45
    })     with urllib.request.urlopen(req, timeout=20) as r:         return json.loads(r.read())
  • Network accessline 46
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 56
    # avg_rating: string e.g. "4.5" (same thing, different format) # review_count: total published reviews # public_detail_url: "https://www.g2.com/products/slack/reviews"
  • Network accessline 58
    # public_detail_url: "https://www.g2.com/products/slack/reviews"
  • Network accessline 145
    new_tab("https://www.g2.com/products/slack/reviews")
  • Network accessline 189
    goto_url("https://www.g2.com/products/slack/reviews")
  • Network accessline 232
    goto_url("https://www.g2.com/products/slack/reviews")
  • Network accessline 293
    goto_url("https://www.g2.com/products/slack/reviews")
  • Network accessline 406
    for page_num in range(1, 6):  # up to 5 pages (~10 reviews each)     url = f"https://www.g2.com/products/{slug}/reviews?page={page_num}"
  • Network accessline 407
    url = f"https://www.g2.com/products/{slug}/reviews?page={page_num}"
  • Network accessline 456
    goto_url("https://www.g2.com/categories/team-collaboration")
  • Network accessline 506
    # Usage new_tab("https://www.g2.com/products/slack/reviews")
  • Network accessline 507
    new_tab("https://www.g2.com/products/slack/reviews")
  • Access to secretsline 558
    [Credential-related source omitted]
  • Network accessline 576
    [Credential-related source omitted]

agent-workspace/domain-skills/gemini/spark-skills.md

  • Network accessline 5
    - Open `https://gemini.google.com/spark/skills`. Locate the card whose title text exactly equals the intended skill name. Read the title separately from the description. A prefix match can select both `Foo` and `Foo Bar`. Stop if the title 

agent-workspace/domain-skills/genius/scraping.md

  • Network accessline 63
    def genius_song(song_id):     """Fetch full song metadata by Genius song ID."""     data = json.loads(genius_get(f"https://genius.com/api/songs/{song_id}"))
  • Network accessline 64
    """Fetch full song metadata by Genius song ID."""     data = json.loads(genius_get(f"https://genius.com/api/songs/{song_id}"))     return data["response"]["song"]
  • Network accessline 65
    data = json.loads(genius_get(f"https://genius.com/api/songs/{song_id}"))
  • Network accessline 73
    # song["primary_artist"]["name"]         → "Queen" # song["primary_artist"]["id"]           → 563 # song["primary_artist"]["url"]          → "https://genius.com/artists/Queen"
  • Network accessline 74
    # song["primary_artist"]["id"]           → 563 # song["primary_artist"]["url"]          → "https://genius.com/artists/Queen" # song["release_date"]                   → "1975-10-31"
  • Network accessline 75
    # song["primary_artist"]["url"]          → "https://genius.com/artists/Queen"
  • Network accessline 85
    # song["album"]["name"]                 → "Studio Collection"   (varies by region) # song["albums"][0]["name"]             → "A Night at the Opera"  (first = original) # song["url"]                           → "https://genius.com/Queen-bohe
  • Network accessline 86
    # song["albums"][0]["name"]             → "A Night at the Opera"  (first = original) # song["url"]                           → "https://genius.com/Queen-bohemian-rhapsody-lyrics" # song["path"]                          → "/Queen-bohemian-rh
  • Network accessline 87
    # song["url"]                           → "https://genius.com/Queen-bohemian-rhapsody-lyrics"
  • Network accessline 88
    # song["path"]                          → "/Queen-bohemian-rhapsody-lyrics" # song["song_art_image_url"]            → "https://images.genius.com/718de9d..." # song["explicit"]                      → False
  • Network accessline 89
    # song["song_art_image_url"]            → "https://images.genius.com/718de9d..."
  • Network accessline 93
    # song["lyrics_verified"]              → False # song["spotify_uuid"]                  → "7tFiyTwD0nx5a1eklYtX2J" # song["youtube_url"]                   → "https://www.youtube.com/watch?v=fJ9rUzIMcZQ"
  • Network accessline 94
    # song["spotify_uuid"]                  → "7tFiyTwD0nx5a1eklYtX2J" # song["youtube_url"]                   → "https://www.youtube.com/watch?v=fJ9rUzIMcZQ" # song["writer_artists"]                → [{"name": "Freddie Mercury", ...}]
  • Network accessline 95
    # song["youtube_url"]                   → "https://www.youtube.com/watch?v=fJ9rUzIMcZQ"
  • Network accessline 107
    def genius_search(query, per_page=5):     """Search Genius. Returns sections: top_hit, song, lyric, artist, album, video, article, user."""     url = f"https://genius.com/api/search/multi?per_page={per_page}&q={urllib.parse.quote(query)}"
  • Network accessline 108
    """Search Genius. Returns sections: top_hit, song, lyric, artist, album, video, article, user."""     url = f"https://genius.com/api/search/multi?per_page={per_page}&q={urllib.parse.quote(query)}"     data = json.loads(genius_get(url))
  • Network accessline 109
    url = f"https://genius.com/api/search/multi?per_page={per_page}&q={urllib.parse.quote(query)}"
  • Network accessline 122
    r = hit["result"]             print(r["full_title"], r["url"], r["id"])         # Bohemian Rhapsody by Queen  https://genius.com/Queen-bohemian-rhapsody-lyrics  1063
  • Network accessline 123
    print(r["full_title"], r["url"], r["id"])         # Bohemian Rhapsody by Queen  https://genius.com/Queen-bohemian-rhapsody-lyrics  1063         break
  • Network accessline 124
    # Bohemian Rhapsody by Queen  https://genius.com/Queen-bohemian-rhapsody-lyrics  1063
  • Network accessline 141
    page = 1     while True:         url = (f"https://genius.com/api/artists/{artist_id}/songs"
  • Network accessline 142
    while True:         url = (f"https://genius.com/api/artists/{artist_id}/songs"                f"?per_page={per_page}&page={page}&sort={sort}")
  • Network accessline 143
    url = (f"https://genius.com/api/artists/{artist_id}/songs"
  • Network accessline 262
    url: the canonical lyrics URL, e.g. 'https://genius.com/Queen-bohemian-rhapsody-lyrics'
  • Network accessline 275
    lyrics = genius_lyrics("https://genius.com/Queen-bohemian-rhapsody-lyrics")
  • Network accessline 333
    # Call 1: search for song     sections = json.loads(         genius_get(f"https://genius.com/api/search/multi?per_page=3&q={urllib.parse.quote(query)}")
  • Network accessline 334
    sections = json.loads(         genius_get(f"https://genius.com/api/search/multi?per_page=3&q={urllib.parse.quote(query)}")     )["response"]["sections"]
  • Network accessline 335
    genius_get(f"https://genius.com/api/search/multi?per_page=3&q={urllib.parse.quote(query)}")
  • Network accessline 348
    # Call 2: full metadata from internal API     meta = json.loads(genius_get(f"https://genius.com/api/songs/{song_id}"))["response"]["song"]
  • Network accessline 349
    meta = json.loads(genius_get(f"https://genius.com/api/songs/{song_id}"))["response"]["song"]
  • Network accessline 383
    #   "producers":    ["Roy Thomas Baker", "Queen"], #   "spotify_uuid": "7tFiyTwD0nx5a1eklYtX2J", #   "youtube_url":  "https://www.youtube.com/watch?v=fJ9rUzIMcZQ",
  • Network accessline 384
    #   "spotify_uuid": "7tFiyTwD0nx5a1eklYtX2J", #   "youtube_url":  "https://www.youtube.com/watch?v=fJ9rUzIMcZQ", #   "song_art_url": "https://images.genius.com/718de9d1fbcaae9f3c9b1bf483bfa8f1.1000x1000x1.png",
  • Network accessline 385
    #   "youtube_url":  "https://www.youtube.com/watch?v=fJ9rUzIMcZQ",
  • Network accessline 386
    #   "song_art_url": "https://images.genius.com/718de9d1fbcaae9f3c9b1bf483bfa8f1.1000x1000x1.png",
  • Network accessline 387
    #   "lyrics_url":   "https://genius.com/Queen-bohemian-rhapsody-lyrics",
  • Network accessline 416
    # Or from search API (no HTML required): sections = json.loads(genius_get(f"https://genius.com/api/search/multi?per_page=1&q={query}"))
  • Network accessline 417
    sections = json.loads(genius_get(f"https://genius.com/api/search/multi?per_page=1&q={query}"))
  • Network accessline 452
    import json     from helpers import http_get     url = f"https://api.genius.com{path}"
  • Network accessline 453
    [Credential-related source omitted]
  • Network accessline 454
    url = f"https://api.genius.com{path}"
  • Access to secretsline 460
    [Credential-related source omitted]

agent-workspace/domain-skills/github/repo-actions.md

  • Network accessline 3
    `https://github.com/{owner}/{repo}` — user-triggered actions on the repo header (Star, Unstar, Watch, Unwatch) are HTML forms that POST back to GitHub with the session's CSRF token already rendered inline. **Submit the form — do not click t
  • Network accessline 65
    - **For read-only star counts, don't touch the DOM — use the API.** `http_get("https://api.github.com/repos/{owner}/{repo}")` returns `stargazers_count` without any browser interaction. See `scraping.md`. Only use the form-submit pattern wh

agent-workspace/domain-skills/github/scraping.md

  • Network accessline 3
    `https://github.com` — public data, mix of REST API (fast, rate-limited) and browser (trending page only).
  • Network accessline 10
    import json data = json.loads(http_get("https://api.github.com/repos/{owner}/{repo}"))
  • Network accessline 11
    data = json.loads(http_get("https://api.github.com/repos/{owner}/{repo}"))
  • Network accessline 21
    readme = http_get("https://raw.githubusercontent.com/owner/repo/main/README.md")
  • Network accessline 22
    content = http_get("https://raw.githubusercontent.com/owner/repo/main/pyproject.toml")
  • Network accessline 32
    import json data = json.loads(http_get("https://api.github.com/repos/browser-use/browser-use"))
  • Network accessline 33
    data = json.loads(http_get("https://api.github.com/repos/browser-use/browser-use"))
  • Network accessline 41
    import json user = json.loads(http_get("https://api.github.com/users/browser-use"))
  • Network accessline 42
    user = json.loads(http_get("https://api.github.com/users/browser-use"))
  • Network accessline 44
    # returns: 'Organization'  3046  39  'https://browser-use.com'
  • Network accessline 52
    import json goto_url("https://github.com/trending")          # or /trending/python?since=weekly
  • Network accessline 53
    goto_url("https://github.com/trending")          # or /trending/python?since=weekly
  • Network accessline 67
    return {       name: h2link ? h2link.innerText.trim().replace(/\\s+/g,' ') : null,       url: h2link ? 'https://github.com' + h2link.getAttribute('href') : null,
  • Network accessline 68
    name: h2link ? h2link.innerText.trim().replace(/\\s+/g,' ') : null,       url: h2link ? 'https://github.com' + h2link.getAttribute('href') : null,       stars_total: starLink ? starLink.innerText.trim() : null,
  • Network accessline 69
    url: h2link ? 'https://github.com' + h2link.getAttribute('href') : null,
  • Network accessline 92
    import json results = json.loads(http_get(     "https://api.github.com/search/repositories?q=browser+automation+language:python&sort=stars&per_page=10"
  • Network accessline 93
    results = json.loads(http_get(     "https://api.github.com/search/repositories?q=browser+automation+language:python&sort=stars&per_page=10" ))
  • Network accessline 94
    "https://api.github.com/search/repositories?q=browser+automation+language:python&sort=stars&per_page=10"
  • Network accessline 106
    import json # Commits commits = json.loads(http_get("https://api.github.com/repos/owner/repo/commits?per_page=10"))
  • Network accessline 107
    # Commits commits = json.loads(http_get("https://api.github.com/repos/owner/repo/commits?per_page=10")) # Fields: sha, commit.message, commit.author.date, author.login
  • Network accessline 108
    commits = json.loads(http_get("https://api.github.com/repos/owner/repo/commits?per_page=10"))
  • Network accessline 111
    # Releases releases = json.loads(http_get("https://api.github.com/repos/owner/repo/releases?per_page=5"))
  • Network accessline 112
    releases = json.loads(http_get("https://api.github.com/repos/owner/repo/releases?per_page=5"))
  • Network accessline 115
    # Issues issues = json.loads(http_get("https://api.github.com/repos/owner/repo/issues?state=open&per_page=10"))
  • Network accessline 116
    issues = json.loads(http_get("https://api.github.com/repos/owner/repo/issues?state=open&per_page=10"))
  • Network accessline 119
    # Contributors contribs = json.loads(http_get("https://api.github.com/repos/owner/repo/contributors?per_page=10"))
  • Network accessline 120
    contribs = json.loads(http_get("https://api.github.com/repos/owner/repo/contributors?per_page=10"))
  • Network accessline 127
    import json, base64 resp = json.loads(http_get("https://api.github.com/repos/owner/repo/contents/path/to/file.py"))
  • Network accessline 128
    resp = json.loads(http_get("https://api.github.com/repos/owner/repo/contents/path/to/file.py"))
  • Possible obfuscationline 129
    content = base64.b64decode(resp['content']).decode()
  • Network accessline 140
    def fetch_repo(name):     data = json.loads(http_get(f"https://api.github.com/repos/{name}"))
  • Network accessline 141
    data = json.loads(http_get(f"https://api.github.com/repos/{name}"))
  • Network accessline 152
    - **Rate limits are per IP, unauthenticated** — Core API: 60 req/hour. Search API: 10 req/min. These are separate pools. Check `/rate_limit` endpoint: `http_get("https://api.github.com/rate_limit")`. With a `GITHUB_TOKEN`, both limits incre
  • Network accessline 157
    [Credential-related source omitted]
  • Access to secretsline 157
    [Credential-related source omitted]
  • Network accessline 159
    data = json.loads(http_get("https://api.github.com/repos/owner/repo", headers=headers))
  • Network accessline 164
    try:       data = json.loads(http_get("https://api.github.com/repos/owner/repo"))
  • Network accessline 165
    data = json.loads(http_get("https://api.github.com/repos/owner/repo"))

agent-workspace/domain-skills/glassdoor/scraping.md

  • Access to secretsline 21
    [Credential-related source omitted]
  • Network accessline 33
    new_tab("https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm")
  • Network accessline 82
    query = "software engineer" new_tab(f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}")
  • Network accessline 83
    new_tab(f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}")
  • Network accessline 148
    for page in range(1, 4):   # pages 1-3, ~10 cards each     url = f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}&p={page}"
  • Network accessline 149
    url = f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}&p={page}"
  • Network accessline 204
    goto_url(f"https://www.glassdoor.com/Overview/Working-at-{company_slug}-EI_IE{employer_id}.htm")
  • Network accessline 253
    goto_url(f"https://www.glassdoor.com/Reviews/{company_slug}-Reviews-E{employer_id}.htm")
  • Network accessline 319
    goto_url(f"https://www.glassdoor.com/Salaries/{role}-salary-SRCH_KO0,{n}.htm")
  • Network accessline 430
    # Usage goto_url("https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm")
  • Network accessline 431
    goto_url("https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm")
  • Network accessline 452
    company_name = "OpenAI" goto_url(f"https://www.glassdoor.com/Search/results.htm?keyword={quote_plus(company_name)}&locT=N")
  • Network accessline 453
    goto_url(f"https://www.glassdoor.com/Search/results.htm?keyword={quote_plus(company_name)}&locT=N")

agent-workspace/domain-skills/gmail/compose.md

  • Network accessline 3
    URL: `https://mail.google.com`

agent-workspace/domain-skills/goodreads/scraping.md

  • Network accessline 22
    URL pattern: `https://www.goodreads.com/book/show/{book_id}` or `/{book_id}.{Slug}`
  • Network accessline 30
    def parse_book(book_id):     html = http_get(f"https://www.goodreads.com/book/show/{book_id}")
  • Network accessline 31
    html = http_get(f"https://www.goodreads.com/book/show/{book_id}")
  • Network accessline 108
    def parse_book_fast(book_id):     html = http_get(f"https://www.goodreads.com/book/show/{book_id}")
  • Network accessline 109
    html = http_get(f"https://www.goodreads.com/book/show/{book_id}")
  • Network accessline 139
    URL: `https://www.goodreads.com/search?q={query}&search_type=books&page={n}`
  • Network accessline 147
    def search_books(query, page=1):     from urllib.parse import quote_plus     url = f"https://www.goodreads.com/search?q={quote_plus(query)}&search_type=books&page={page}"
  • Network accessline 148
    from urllib.parse import quote_plus     url = f"https://www.goodreads.com/search?q={quote_plus(query)}&search_type=books&page={page}"     html = http_get(url)
  • Network accessline 149
    url = f"https://www.goodreads.com/search?q={quote_plus(query)}&search_type=books&page={page}"
  • Network accessline 152
    rows = re.findall(         r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',
  • Network accessline 153
    r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',
  • Network accessline 172
    'ratings_count':cnt.group(1).replace(',', '') if cnt else None,             'cover_url':    cover.group(1) if cover else None,             'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",
  • Network accessline 173
    'cover_url':    cover.group(1) if cover else None,             'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",         })
  • Network accessline 174
    'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",
  • Network accessline 199
    URL: `https://www.goodreads.com/author/show/{author_id}.{Slug}`
  • Network accessline 208
    def parse_author(author_id_and_slug):     # author_id_and_slug e.g. "58.Frank_Patrick_Herbert"     html = http_get(f"https://www.goodreads.com/author/show/{author_id_and_slug}")
  • Network accessline 210
    html = http_get(f"https://www.goodreads.com/author/show/{author_id_and_slug}")
  • Network accessline 224
    # Top books listed on the page (10 rows, same microdata format as search)     rows = re.findall(         r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',
  • Network accessline 225
    rows = re.findall(         r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',         html, re.DOTALL
  • Network accessline 226
    r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',
  • Network accessline 239
    'avg_rating':   float(avg.group(1)) if avg else None,                 'ratings_count':cnt.group(1).replace(',', '') if cnt else None,                 'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",
  • Network accessline 240
    'ratings_count':cnt.group(1).replace(',', '') if cnt else None,                 'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",             })
  • Network accessline 241
    'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",
  • Network accessline 271
    URL: `https://www.goodreads.com/list/show/{list_id}.{Slug}?page={n}`
  • Network accessline 279
    def parse_list(list_id_and_slug, page=1):     url = f"https://www.goodreads.com/list/show/{list_id_and_slug}?page={page}"
  • Network accessline 280
    url = f"https://www.goodreads.com/list/show/{list_id_and_slug}?page={page}"
  • Network accessline 283
    rows = re.findall(         r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',
  • Network accessline 284
    r'<tr itemscope itemtype="http://schema.org/Book">(.*?)</tr>',
  • Network accessline 303
    'avg_rating':   float(avg.group(1)) if avg else None,             'ratings_count':cnt.group(1).replace(',', '') if cnt else None,             'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",
  • Network accessline 304
    'ratings_count':cnt.group(1).replace(',', '') if cnt else None,             'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",         })
  • Network accessline 305
    'url':          f"https://www.goodreads.com/book/show/{bid.group(1)}",
  • Network accessline 337
    def ol_search(query, limit=10):     url = f"https://openlibrary.org/search.json?q={quote_plus(query)}&limit={limit}"
  • Network accessline 338
    url = f"https://openlibrary.org/search.json?q={quote_plus(query)}&limit={limit}"
  • Network accessline 349
    'edition_count':    doc.get('edition_count'),             'series':           doc.get('series_name'),             'cover_url':        f"https://covers.openlibrary.org/b/id/{cover_id}-M.jpg" if cover_id else None,
  • Network accessline 350
    'series':           doc.get('series_name'),             'cover_url':        f"https://covers.openlibrary.org/b/id/{cover_id}-M.jpg" if cover_id else None,         })
  • Network accessline 351
    'cover_url':        f"https://covers.openlibrary.org/b/id/{cover_id}-M.jpg" if cover_id else None,
  • Network accessline 364
    # ol_key like "/works/OL893415W" or just "OL893415W"     key = ol_key if ol_key.startswith('/') else f'/works/{ol_key}'     data = json.loads(http_get(f"https://openlibrary.org{key}.json"))
  • Network accessline 365
    key = ol_key if ol_key.startswith('/') else f'/works/{ol_key}'     data = json.loads(http_get(f"https://openlibrary.org{key}.json"))     desc = data.get('description', '')
  • Network accessline 366
    data = json.loads(http_get(f"https://openlibrary.org{key}.json"))
  • Network accessline 387
    def ol_ratings(ol_key):     key = ol_key if ol_key.startswith('/') else f'/works/{ol_key}'     data = json.loads(http_get(f"https://openlibrary.org{key}/ratings.json"))
  • Network accessline 388
    key = ol_key if ol_key.startswith('/') else f'/works/{ol_key}'     data = json.loads(http_get(f"https://openlibrary.org{key}/ratings.json"))     return data.get('summary', {})
  • Network accessline 389
    data = json.loads(http_get(f"https://openlibrary.org{key}/ratings.json"))
  • Network accessline 398
    def ol_author(author_key):     # author_key like "OL79034A"     data = json.loads(http_get(f"https://openlibrary.org/authors/{author_key}.json"))
  • Network accessline 399
    # author_key like "OL79034A"     data = json.loads(http_get(f"https://openlibrary.org/authors/{author_key}.json"))     bio = data.get('bio', '')
  • Network accessline 400
    data = json.loads(http_get(f"https://openlibrary.org/authors/{author_key}.json"))
  • Network accessline 451
    - **Search has no `__NEXT_DATA__`**: Search result pages (`/search`) are classic server-rendered HTML. JSON-LD is absent. Use the `<tr itemscope itemtype="http://schema.org/Book">` microdata rows.
  • Network accessline 455
    - **Open Library cover URLs return binary JPEG**: `http_get()` will raise a `UnicodeDecodeError` on cover image URLs. Use `urllib.request.urlopen()` directly and read bytes, or just store the URL string without fetching.

agent-workspace/domain-skills/google-maps/scraping.md

  • Network accessline 10
    - Observed: "coffee shops in Austin TX" -> 9 requests (offsets 0-160, 2 s apart) -> 175 result rows in the run that counted them -> **150 to 175 unique places** across nine runs (175 in the run shown below: 145 with a phone, 167 with a webs
  • Network accessline 11
    - **Browser fallback: scroll the results feed** (`div[role=feed]`) and read the cards. Card-level fields only (name, rating, reviews, category, short address, open status, place_id, lat/lng). The feed only lazy-loads in a visible tab, so br
  • Network accessline 12
    - **Phone, website, hours for one place in the browser:** open `https://www.google.com/maps/place/?q=place_id:<id>` and read `[data-item-id]` elements.
  • Network accessline 31
    for i in range(tries):                            # retry transient errors with backoff, then raise         try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r:
  • Network accessline 32
    try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r:                 data = r.read()
  • Network accessline 33
    with urllib.request.urlopen(urllib.request.Request(url, headers=HEADERS), timeout=30) as r:
  • Network accessline 78
    "place_id": pid,         "cid": cid,         "maps_url": f"https://www.google.com/maps/place/?q=place_id:{pid}" if pid else None,
  • Network accessline 79
    "cid": cid,         "maps_url": f"https://www.google.com/maps/place/?q=place_id:{pid}" if pid else None,         "open_now": (at(p, 203, 1, 4, 0) or "").replace(" ", " ") or None,
  • Network accessline 80
    "maps_url": f"https://www.google.com/maps/place/?q=place_id:{pid}" if pid else None,
  • Network accessline 85
    def search_places(query, max_results=200, pause=2.0):     q = urllib.parse.quote_plus(query)     page = get(f"https://www.google.com/maps/search/{q}?hl=en&gl=us")
  • Network accessline 86
    q = urllib.parse.quote_plus(query)     page = get(f"https://www.google.com/maps/search/{q}?hl=en&gl=us")     m = re.search(r'<link href="(/search\?tbm=map[^"]+)"', page)
  • Network accessline 87
    page = get(f"https://www.google.com/maps/search/{q}?hl=en&gl=us")
  • Network accessline 89
    if not m:         raise RuntimeError("no /search?tbm=map preload link (consent page or layout change?)")     base = "https://www.google.com" + html.unescape(m.group(1))
  • Network accessline 90
    [Credential-related source omitted]
  • Network accessline 91
    base = "https://www.google.com" + html.unescape(m.group(1))
  • Network accessline 143
    "phone": "(512) 852-2300",   "phone_e164": "+15128522300",   "website": "https://www.joscoffee.com/south-congress-jos",
  • Network accessline 144
    "phone_e164": "+15128522300",   "website": "https://www.joscoffee.com/south-congress-jos",   "lat": 30.2510458,
  • Network accessline 145
    "website": "https://www.joscoffee.com/south-congress-jos",
  • Network accessline 148
    "place_id": "ChIJ1S_Bov20RIYRe7MiR8tYawY",   "cid": "462561016830669691",   "maps_url": "https://www.google.com/maps/place/?q=place_id:ChIJ1S_Bov20RIYRe7MiR8tYawY",
  • Network accessline 149
    "cid": "462561016830669691",   "maps_url": "https://www.google.com/maps/place/?q=place_id:ChIJ1S_Bov20RIYRe7MiR8tYawY",   "open_now": "Open · Closes 7 PM",
  • Network accessline 150
    "maps_url": "https://www.google.com/maps/place/?q=place_id:ChIJ1S_Bov20RIYRe7MiR8tYawY",
  • Network accessline 185
    if FOREGROUND:     activate_tab(tid)      # make it visible BEFORE loading the search goto_url("https://www.google.com/maps/search/" + urllib.parse.quote_plus(query) + "?hl=en")
  • Network accessline 186
    activate_tab(tid)      # make it visible BEFORE loading the search goto_url("https://www.google.com/maps/search/" + urllib.parse.quote_plus(query) + "?hl=en") wait_for_load()
  • Network accessline 187
    goto_url("https://www.google.com/maps/search/" + urllib.parse.quote_plus(query) + "?hl=en")
  • Network accessline 269
    "lat": 30.2510458,   "lng": -97.7493717,   "maps_url": "https://www.google.com/maps/place/Jo%27s+Coffee+%E2%80%93+South+Congress/data=!4m7!3m6!1s0x8644b4fda2c12fd5:0x66b58cb4722b37b!8m2!3d30.2510458!4d-97.7493717!16s%2Fm%2F020z01l!19sChIJ1S
  • Network accessline 270
    "lng": -97.7493717,   "maps_url": "https://www.google.com/maps/place/Jo%27s+Coffee+%E2%80%93+South+Congress/data=!4m7!3m6!1s0x8644b4fda2c12fd5:0x66b58cb4722b37b!8m2!3d30.2510458!4d-97.7493717!16s%2Fm%2F020z01l!19sChIJ1S_Bov20RIYRe7MiR8tYawY
  • Network accessline 271
    "maps_url": "https://www.google.com/maps/place/Jo%27s+Coffee+%E2%80%93+South+Congress/data=!4m7!3m6!1s0x8644b4fda2c12fd5:0x66b58cb4722b37b!8m2!3d30.2510458!4d-97.7493717!16s%2Fm%2F020z01l!19sChIJ1S_Bov20RIYRe7MiR8tYawY"
  • Network accessline 284
    def place_details(place_id):     goto_url(f"https://www.google.com/maps/place/?q=place_id:{place_id}&hl=en")
  • Network accessline 285
    goto_url(f"https://www.google.com/maps/place/?q=place_id:{place_id}&hl=en")
  • Network accessline 314
    "address": "1300 S Congress Ave, Austin, TX 78704",  "phone": "(512) 852-2300",  "website": "https://www.joscoffee.com/south-congress-jos",
  • Network accessline 315
    "phone": "(512) 852-2300",  "website": "https://www.joscoffee.com/south-congress-jos",  "hours": ["Friday, 7 AM to 7 PM", "Saturday, 7 AM to 7 PM", ...]
  • Network accessline 316
    "website": "https://www.joscoffee.com/south-congress-jos",
  • Network accessline 321
    "address": "3908 Avenue B, Austin, TX 78751",  "phone": null,  "website": "http://terriblelovecoffee.com/",
  • Network accessline 322
    "phone": null,  "website": "http://terriblelovecoffee.com/",  "hours": ["Friday, 7:30 AM to 2 PM", ...]
  • Network accessline 323
    "website": "http://terriblelovecoffee.com/",
  • Network accessline 339
    | neighborhood | `p[14]` | - | `Bouldin Creek` | | phone | `p[178][0][0]`, E.164 at `p[178][0][3]` | `[data-item-id^="phone:tel:"]` aria | `(512) 852-2300` | | website | `p[7][0]` (a `/url?q=<site>` redirect for non-browser UAs), domain at 
  • Network accessline 340
    | phone | `p[178][0][0]`, E.164 at `p[178][0][3]` | `[data-item-id^="phone:tel:"]` aria | `(512) 852-2300` | | website | `p[7][0]` (a `/url?q=<site>` redirect for non-browser UAs), domain at `p[7][1]` | `a[data-item-id=authority]` href | `h
  • Network accessline 341
    | website | `p[7][0]` (a `/url?q=<site>` redirect for non-browser UAs), domain at `p[7][1]` | `a[data-item-id=authority]` href | `https://www.joscoffee.com/...` |
  • Network accessline 349
    `https://www.google.com/maps/place/?q=place_id:<place_id>` opened the matching place page in the browser (checked for two places).

agent-workspace/domain-skills/google-patents/scraping.md

  • Network accessline 9
    - A patent page (`/patent/<publication number>/en`) is server-rendered HTML with schema.org microdata (`itemprop` attributes). Title, bibliographic data, every claim, every citation table and the family tables are all in that one document. 
  • Network accessline 10
    - The browser block opens one patent page so the tab is on `patents.google.com`, then for each number calls `fetch('/patent/<number>/en')` inside the tab and parses the response with `DOMParser`. It does not read the rendered page: the Poly
  • Network accessline 29
    const url = `/patent/${encodeURIComponent(num)}/${lang}`;   let r;   try { r = await fetch(url); }
  • Network accessline 30
    let r;   try { r = await fetch(url); }   catch (e) { return {error: `fetch failed (${e}); a cross-origin redirect here usually means a google.com/sorry challenge`}; }
  • Network accessline 31
    try { r = await fetch(url); }
  • Network accessline 98
    def gp_open(num):     """Point the tab at a patent page (any /patent/ page works as the origin for gp_patent)."""     goto_url(f"https://patents.google.com/patent/{num}/en")
  • Network accessline 99
    """Point the tab at a patent page (any /patent/ page works as the origin for gp_patent)."""     goto_url(f"https://patents.google.com/patent/{num}/en")     wait_for_load()
  • Network accessline 100
    goto_url(f"https://patents.google.com/patent/{num}/en")
  • Network accessline 102
    time.sleep(2)     href = js("location.href")     if not href.startswith("https://patents.google.com/patent/"):
  • Network accessline 103
    href = js("location.href")     if not href.startswith("https://patents.google.com/patent/"):         raise RuntimeError(f"tab landed on {href}, not a patent page (challenge or redirect). Stop and tell the user.")
  • Network accessline 104
    if not href.startswith("https://patents.google.com/patent/"):
  • Network accessline 107
    def gp_patent(num, lang="en"):     """Full record for one publication number ('US6285999B1'), or None when Google Patents returns 404.     Runs fetch() inside the attached patents.google.com tab and parses the server-rendered page."""
  • Network accessline 108
    """Full record for one publication number ('US6285999B1'), or None when Google Patents returns 404.     Runs fetch() inside the attached patents.google.com tab and parses the server-rendered page."""     rec = js(f"{PATENT_JS}({json.dumps(n
  • Network accessline 109
    Runs fetch() inside the attached patents.google.com tab and parses the server-rendered page."""
  • Network accessline 179
    Self-contained, Python standard library only. `html.parser` builds a small tree and the same `itemprop` lookups run on it, so the keys and values match block 1 (block 1 also has `pdf`, `assignee_current`, `application_number`, `abstract`, `
  • Network accessline 249
    def fetch(url):
  • Network accessline 250
    """HTML for a /patent/ page, None on 404. Any other status, or a redirect off /patent/, raises: stop, do not retry around it."""     try:         with urllib.request.urlopen(urllib.request.Request(url, headers=UA), timeout=60) as r:
  • Network accessline 251
    try:         with urllib.request.urlopen(urllib.request.Request(url, headers=UA), timeout=60) as r:             final = r.geturl()
  • Network accessline 252
    with urllib.request.urlopen(urllib.request.Request(url, headers=UA), timeout=60) as r:
  • Network accessline 262
    def gp_patent_http(num, lang="en"):     html, final = fetch(f"https://patents.google.com/patent/{urllib.parse.quote(num)}/{lang}")
  • Network accessline 263
    html, final = fetch(f"https://patents.google.com/patent/{urllib.parse.quote(num)}/{lang}")
  • Network accessline 360
    | `country_status` | rows `countryStatus` (`countryCode`, `num`, `representativePublication`) | `[{"countryCode": "US", "num": "10", ...}]` | | `priority_applications` | rows `priorityApps` | 12 rows | | `url` | final URL of the fetch | `ht
  • Network accessline 362
    | `url` | final URL of the fetch | `https://patents.google.com/patent/US6285999B1/en` |
  • Access to secretsline 374
    [Credential-related source omitted]

agent-workspace/domain-skills/google-play/scraping.md

  • Network accessline 41
    def fetch(url, tries=4):
  • Network accessline 44
    Other HTTP errors (404 included) raise urllib.error.HTTPError immediately."""     for i in range(tries):         req = urllib.request.Request(url, headers=H)
  • Network accessline 45
    for i in range(tries):         req = urllib.request.Request(url, headers=H)         try:
  • Network accessline 46
    req = urllib.request.Request(url, headers=H)
  • Network accessline 47
    try:             with urllib.request.urlopen(req, timeout=20) as r:                 return r.read().decode()
  • Network accessline 48
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 125
    """Full detail record for one package name, or None if Play returns HTTP 404     or the page has neither app data nor JSON-LD for this id."""     url = "https://play.google.com/store/apps/details?" + urllib.parse.urlencode({"id": app_id, "h
  • Network accessline 126
    or the page has neither app data nor JSON-LD for this id."""     url = "https://play.google.com/store/apps/details?" + urllib.parse.urlencode({"id": app_id, "hl": HL, "gl": GL})     try:
  • Network accessline 127
    url = "https://play.google.com/store/apps/details?" + urllib.parse.urlencode({"id": app_id, "hl": HL, "gl": GL})
  • Network accessline 128
    try:         html = fetch(url)     except urllib.error.HTTPError as e:
  • Network accessline 129
    html = fetch(url)
  • Network accessline 197
    {"app_id": "com.spotify.music", "title": "Spotify: Music and Podcasts", "developer": "Spotify AB", "developer_id": "6523013212965523194", "rating": 4.3489933, "ratings_count": 36528069, "installs": "1,000,000,000+", "min_installs": 10000000
  • Network accessline 198
    {"app_id": "com.mojang.minecraftpe", "title": "Minecraft: Dream it, Build it!", "developer": "Mojang", "developer_id": "4772240228547998649", "rating": 4.303256, "ratings_count": 5866778, "installs": "50,000,000+", "min_installs": 50000000,
  • Network accessline 199
    {"app_id": "org.videolan.vlc", "title": "VLC for Android", "developer": "Videolabs", "developer_id": "6364851808230428105", "rating": 4.042392, "ratings_count": 2009187, "installs": "500,000,000+", "min_installs": 500000000, "installs_exact
  • Network accessline 227
    def open_play(path, params, ready_expr, timeout=30):     """Navigate, then wait until the loaded document is THIS url (same path, same id) and ready_expr is true."""     url = "https://play.google.com" + path + "?" + urllib.parse.urlencode(
  • Network accessline 228
    """Navigate, then wait until the loaded document is THIS url (same path, same id) and ready_expr is true."""     url = "https://play.google.com" + path + "?" + urllib.parse.urlencode(params)     _retry(goto_url, url)
  • Network accessline 229
    url = "https://play.google.com" + path + "?" + urllib.parse.urlencode(params)
  • Network accessline 313
    def open_play(path, params, ready_expr, timeout=30):     """Navigate, then wait until the loaded document is THIS url (same path, same id) and ready_expr is true."""     url = "https://play.google.com" + path + "?" + urllib.parse.urlencode(
  • Network accessline 314
    """Navigate, then wait until the loaded document is THIS url (same path, same id) and ready_expr is true."""     url = "https://play.google.com" + path + "?" + urllib.parse.urlencode(params)     _retry(goto_url, url)
  • Network accessline 315
    url = "https://play.google.com" + path + "?" + urllib.parse.urlencode(params)
  • Network accessline 443
    | `contains_ads` | `a[48]` is `["Contains ads"]` for apps with ads (Spotify) and null for apps without (Minecraft, VLC); `null` if the app array is missing or `a[48]` has another shape | `true` | | `in_app_purchases` | `a[19][0]` | `$4.99 -
  • Network accessline 445
    | `url` | the detail URL that was fetched | `https://play.google.com/store/apps/details?id=com.spotify.music&hl=en_US&gl=US` |
  • Network accessline 456
    - **Two kinds of developer page.** App pages link either to `/store/apps/developer?id=<name>` (Spotify) or to `/store/apps/dev?id=<numeric id>` (Microsoft Teams, Angry Birds 2, YouTube). The numeric page is a showcase of 10-11 apps. The nam
  • Network accessline 457
    - **Country and language come from `gl` and `hl`.** With `GL = "DE"` Minecraft came back as `6.99 EUR`, `€6.99`. Set them explicitly; without them Play picks from the request. - **Missing apps return HTTP 404** (`com.example.does.not.exist`
  • Network accessline 458
    - **Missing apps return HTTP 404** (`com.example.does.not.exist`). `fetch()` raises `urllib.error.HTTPError` at once for a 404 (only 429 and 5xx are retried); `play_app()` turns the 404 into `None`, and also returns `None` for any page with
  • Access to secretsline 459
    [Credential-related source omitted]

agent-workspace/domain-skills/google-sheets/writing-cells.md

  • Network accessline 36
    https://docs.google.com/spreadsheets/d/<id>/export?format=csv&gid=<gid>

agent-workspace/domain-skills/google-trends/scraping.md

  • Network accessline 9
    - **RSS, no browser:** `https://trends.google.com/trending/rss?geo=<CC>` returns exactly 10 items: the 10 most recently started trends for that country or region (`US`, `GB`, `JP`, `US-CA`...), each with approximate traffic (`2000+`), start
  • Network accessline 10
    - **/trending page, everything:** `https://trends.google.com/trending?geo=<CC>&hl=en-US&hours=<4|24|48|168>` ships every trend for that window in one inline script, `AF_initDataCallback({key: 'ds:0', ...})` (658 trends for US / 24 h on 2026
  • Network accessline 26
    BASE = "https://trends.google.com"
  • Network accessline 27
    HT = "{https://trends.google.com/trending/rss}"   # namespace of the ht:* tags
  • Network accessline 30
    # longest matching pattern wins, Allow wins a tie. def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 31
    def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()     rules, in_star, prev_ua = [], False, False
  • Network accessline 32
    txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 63
    raise PermissionError(f"robots.txt disallows {path}")     try:         body = urllib.request.urlopen(BASE + path, timeout=20).read()
  • Network accessline 64
    try:         body = urllib.request.urlopen(BASE + path, timeout=20).read()     except urllib.error.HTTPError as e:
  • Network accessline 65
    body = urllib.request.urlopen(BASE + path, timeout=20).read()
  • Network accessline 125
    BASE = "https://trends.google.com"
  • Network accessline 128
    # longest matching pattern wins, Allow wins a tie. def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 129
    def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()     rules, in_star, prev_ua = [], False, False
  • Network accessline 130
    txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 294
    BASE = "https://trends.google.com"
  • Network accessline 296
    # robots.txt, group "User-agent: *", wildcard rules matched Google-style (same parser as blocks 1 and 2). def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 297
    def _robots_rules():     txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()     rules, in_star, prev_ua = [], False, False
  • Network accessline 298
    txt = urllib.request.urlopen(BASE + "/robots.txt", timeout=20).read().decode()
  • Network accessline 330
    if not robots_allowed(path):         raise PermissionError(f"robots.txt disallows {path}")     html = urllib.request.urlopen(BASE + path, timeout=30).read().decode()
  • Network accessline 331
    raise PermissionError(f"robots.txt disallows {path}")     html = urllib.request.urlopen(BASE + path, timeout=30).read().decode()     m = re.search(r"AF_initDataCallback\(\{key: 'ds:0', hash: '\d+', data:(\[.*?\]), sideChannel: \{\}\}\);", h
  • Network accessline 332
    html = urllib.request.urlopen(BASE + path, timeout=30).read().decode()

agent-workspace/domain-skills/google/flights-multi-city.md

  • Network accessline 7
    https://www.google.com/travel/flights?tfs=<base64 protobuf>&hl=en&curr=USD

agent-workspace/domain-skills/gutenberg/scraping.md

  • Network accessline 3
    `https://www.gutenberg.org` — 78 000+ free public-domain ebooks. Every workflow here is pure `http_get` — no browser needed.
  • Network accessline 12
    # Search by title/author keyword data = json.loads(http_get("https://gutendex.com/books/?search=pride+and+prejudice"))
  • Network accessline 13
    data = json.loads(http_get("https://gutendex.com/books/?search=pride+and+prejudice"))
  • Network accessline 28
    book = json.loads(http_get("https://gutendex.com/books/1342/"))
  • Network accessline 38
    data = json.loads(http_get("https://gutendex.com/books/?search=frankenstein"))
  • Network accessline 53
    data = json.loads(http_get("https://gutendex.com/books/?sort=popular"))
  • Network accessline 74
    # 'topic' matches both subjects and bookshelves fields data = json.loads(http_get("https://gutendex.com/books/?topic=science+fiction"))
  • Network accessline 75
    data = json.loads(http_get("https://gutendex.com/books/?topic=science+fiction"))
  • Network accessline 78
    data = json.loads(http_get("https://gutendex.com/books/?topic=detective+fiction"))
  • Network accessline 82
    # Filter by language (ISO 639-1 code) data = json.loads(http_get("https://gutendex.com/books/?languages=fr&topic=roman"))
  • Network accessline 83
    data = json.loads(http_get("https://gutendex.com/books/?languages=fr&topic=roman"))
  • Network accessline 92
    url = "https://gutendex.com/books/?topic=science+fiction"
  • Network accessline 97
    url = data['next']   # None on last page     # data['previous'] is also populated after page 1     # e.g. data['next'] = "https://gutendex.com/books/?page=3&topic=science+fiction"
  • Network accessline 98
    # data['previous'] is also populated after page 1     # e.g. data['next'] = "https://gutendex.com/books/?page=3&topic=science+fiction" # All 3473 sci-fi books loaded across ~109 pages of 32 each
  • Network accessline 99
    # e.g. data['next'] = "https://gutendex.com/books/?page=3&topic=science+fiction"
  • Network accessline 108
    data = json.loads(http_get("https://gutendex.com/books/?ids=1342,11,84"))
  • Network accessline 120
    raw = http_get("https://www.gutenberg.org/cache/epub/1342/pg1342.txt")
  • Network accessline 135
    # Both of these return identical content (763 083 chars): http_get("https://www.gutenberg.org/ebooks/1342.txt.utf-8")          # redirect
  • Network accessline 136
    http_get("https://www.gutenberg.org/ebooks/1342.txt.utf-8")          # redirect
  • Network accessline 137
    http_get("https://www.gutenberg.org/cache/epub/1342/pg1342.txt")     # direct cache
  • Network accessline 157
    b = json.loads(http_get("https://gutendex.com/books/1342/"))
  • Network accessline 159
    for mime, url in b['formats'].items():     print(mime, '->', url) # text/html                         -> https://www.gutenberg.org/ebooks/1342.html.images
  • Network accessline 160
    print(mime, '->', url) # text/html                         -> https://www.gutenberg.org/ebooks/1342.html.images # application/epub+zip              -> https://www.gutenberg.org/ebooks/1342.epub3.images
  • Network accessline 161
    # text/html                         -> https://www.gutenberg.org/ebooks/1342.html.images
  • Network accessline 162
    # application/epub+zip              -> https://www.gutenberg.org/ebooks/1342.epub3.images
  • Network accessline 163
    # application/x-mobipocket-ebook   -> https://www.gutenberg.org/ebooks/1342.kf8.images
  • Network accessline 164
    # application/rdf+xml               -> https://www.gutenberg.org/ebooks/1342.rdf
  • Network accessline 165
    # image/jpeg                        -> https://www.gutenberg.org/cache/epub/1342/pg1342.cover.medium.jpg
  • Network accessline 166
    # application/octet-stream          -> https://www.gutenberg.org/cache/epub/1342/pg1342-h.zip
  • Network accessline 167
    # text/plain; charset=utf-8         -> https://www.gutenberg.org/ebooks/1342.txt.utf-8
  • Network accessline 175
    rdf = http_get("https://www.gutenberg.org/cache/epub/1342/pg1342.rdf")
  • Network accessline 176
    # Also available as: http_get("https://www.gutenberg.org/ebooks/1342.rdf")
  • Network accessline 206
    html = http_get(     "https://www.gutenberg.org/ebooks/search/"
  • Network accessline 207
    "https://www.gutenberg.org/ebooks/search/"
  • Network accessline 229
    # Paginate with start_index (25 per page) html_p2 = http_get(     "https://www.gutenberg.org/ebooks/search/"
  • Network accessline 230
    html_p2 = http_get(     "https://www.gutenberg.org/ebooks/search/"     "?query=shakespeare&sort_order=downloads&start_index=26"
  • Network accessline 231
    "https://www.gutenberg.org/ebooks/search/"
  • Network accessline 241
    # Bookshelf 68 = Science Fiction html = http_get("https://www.gutenberg.org/ebooks/bookshelf/68")
  • Network accessline 242
    html = http_get("https://www.gutenberg.org/ebooks/bookshelf/68")
  • Network accessline 253
    feed = http_get("https://www.gutenberg.org/ebooks/search.opds/?query=dracula")
  • Network accessline 267
    Validated against a real call to `GET https://gutendex.com/books/1342/`:
  • Network accessline 298
    "media_type": "Text",   "formats": {     "text/html":                       "https://www.gutenberg.org/ebooks/1342.html.images",
  • Network accessline 299
    "formats": {     "text/html":                       "https://www.gutenberg.org/ebooks/1342.html.images",     "application/epub+zip":            "https://www.gutenberg.org/ebooks/1342.epub3.images",
  • Network accessline 300
    "text/html":                       "https://www.gutenberg.org/ebooks/1342.html.images",
  • Network accessline 301
    "application/epub+zip":            "https://www.gutenberg.org/ebooks/1342.epub3.images",
  • Network accessline 302
    "application/x-mobipocket-ebook": "https://www.gutenberg.org/ebooks/1342.kf8.images",
  • Network accessline 303
    "application/rdf+xml":             "https://www.gutenberg.org/ebooks/1342.rdf",
  • Network accessline 304
    "image/jpeg":                      "https://www.gutenberg.org/cache/epub/1342/pg1342.cover.medium.jpg",
  • Network accessline 305
    "application/octet-stream":        "https://www.gutenberg.org/cache/epub/1342/pg1342-h.zip",
  • Network accessline 306
    "text/plain; charset=utf-8":       "https://www.gutenberg.org/ebooks/1342.txt.utf-8"
  • Network accessline 347
    1. **Gutendex search** — returns `id` directly in JSON. 2. **Gutenberg HTML catalog** — `book_id = re.search(r'/ebooks/(\d+)', entry)`. IDs in the URL. 3. **URL pattern** — `https://www.gutenberg.org/ebooks/{id}` — if you already know the I
  • Network accessline 349
    3. **URL pattern** — `https://www.gutenberg.org/ebooks/{id}` — if you already know the ID from any source.
  • Network accessline 360
    url = "https://gutendex.com/books/?sort=popular"
  • Network accessline 369
    For gutenberg.org file downloads (txt, epub, etc.) there is no documented rate limit but Gutenberg asks not to use automated bulk downloading; use their [offline catalogs](https://www.gutenberg.org/ebooks/offline_catalogs.html) for bulk acc
  • Network accessline 373
    - **`.opf` 404**: `https://www.gutenberg.org/cache/epub/1342/pg1342.opf` returns 404. Use `.rdf` instead — same path prefix, same data in RDF/XML. - **`formats` URLs redirect**: URLs like `https://www.gutenberg.org/ebooks/1342.txt.utf-8` ar
  • Network accessline 374
    - **`formats` URLs redirect**: URLs like `https://www.gutenberg.org/ebooks/1342.txt.utf-8` are redirect endpoints that resolve to `/cache/epub/1342/pg1342.txt`. Either form works with `http_get` (urllib follows redirects automatically), but

agent-workspace/domain-skills/hackernews/scraping.md

  • Network accessline 3
    `https://news.ycombinator.com` — YCombinator's link aggregator. Three access paths tested: `http_get` DOM scraping, Algolia search API, and the official HN Firebase API. All work without a browser.
  • Network accessline 26
    page = http_get("https://news.ycombinator.com")
  • Network accessline 91
    # Keyword search — sorted by relevance data = json.loads(http_get(     "https://hn.algolia.com/api/v1/search"
  • Network accessline 92
    data = json.loads(http_get(     "https://hn.algolia.com/api/v1/search"     "?query=llm&tags=story&hitsPerPage=20"
  • Network accessline 93
    "https://hn.algolia.com/api/v1/search"
  • Network accessline 97
    # Date-sorted (most recent first) data = json.loads(http_get(     "https://hn.algolia.com/api/v1/search_by_date"
  • Network accessline 98
    data = json.loads(http_get(     "https://hn.algolia.com/api/v1/search_by_date"     "?tags=story&hitsPerPage=20"
  • Network accessline 99
    "https://hn.algolia.com/api/v1/search_by_date"
  • Network accessline 161
    thread = json.loads(http_get(     "https://hn.algolia.com/api/v1/items/47806725"
  • Network accessline 162
    "https://hn.algolia.com/api/v1/items/47806725"
  • Network accessline 188
    # Ranked story ID lists (no metadata — just IDs) top   = json.loads(http_get("https://hacker-news.firebaseio.com/v0/topstories.json"))  # 500 IDs
  • Network accessline 189
    top   = json.loads(http_get("https://hacker-news.firebaseio.com/v0/topstories.json"))  # 500 IDs
  • Network accessline 190
    new   = json.loads(http_get("https://hacker-news.firebaseio.com/v0/newstories.json"))  # 500 IDs
  • Network accessline 191
    best  = json.loads(http_get("https://hacker-news.firebaseio.com/v0/beststories.json")) # 200 IDs
  • Network accessline 192
    ask   = json.loads(http_get("https://hacker-news.firebaseio.com/v0/askstories.json"))  # ~32 IDs
  • Network accessline 193
    show  = json.loads(http_get("https://hacker-news.firebaseio.com/v0/showstories.json")) # ~119 IDs
  • Network accessline 194
    jobs  = json.loads(http_get("https://hacker-news.firebaseio.com/v0/jobstories.json"))  # ~31 IDs
  • Network accessline 196
    # Fetch a single item item = json.loads(http_get(     "https://hacker-news.firebaseio.com/v0/item/47806725.json"
  • Network accessline 197
    item = json.loads(http_get(     "https://hacker-news.firebaseio.com/v0/item/47806725.json" ))
  • Network accessline 198
    "https://hacker-news.firebaseio.com/v0/item/47806725.json"
  • Network accessline 203
    # Fetch a user profile user = json.loads(http_get(     "https://hacker-news.firebaseio.com/v0/user/pg.json"
  • Network accessline 204
    user = json.loads(http_get(     "https://hacker-news.firebaseio.com/v0/user/pg.json" ))
  • Network accessline 205
    "https://hacker-news.firebaseio.com/v0/user/pg.json"
  • Network accessline 209
    # Highest current item ID (useful for polling new items) maxid = json.loads(http_get("https://hacker-news.firebaseio.com/v0/maxitem.json"))
  • Network accessline 210
    maxid = json.loads(http_get("https://hacker-news.firebaseio.com/v0/maxitem.json"))
  • Network accessline 227
    page = http_get("https://news.ycombinator.com/item?id=47806725")

agent-workspace/domain-skills/home-depot/scraping.md

  • Network accessline 9
    - **No search.** `/s/<query>` and the `NCNI-5` category redirect a search lands on are disallowed. Find a category instead: the site's own sitemap `https://www.homedepot.com/sitemap/B/PLPs.xml` points to `PLP_CORE_TAX-0.xml` with 5356 categ
  • Network accessline 11
    - **Category page** (`/b/<slug>/N-<id>`) carries the product grid as JSON, not just HTML:   - server-rendered Apollo cache `window.__APOLLO_STATE__` (`SearchModel` -> `products(...)` -> `base-searchNav-<itemId>` entries), and   - the page's
  • Network accessline 12
    - server-rendered Apollo cache `window.__APOLLO_STATE__` (`SearchModel` -> `products(...)` -> `base-searchNav-<itemId>` entries), and   - the page's own `POST https://apionline.homedepot.com/federation-gateway/graphql?opname=searchModel`.  
  • Network accessline 13
    - the page's own `POST https://apionline.homedepot.com/federation-gateway/graphql?opname=searchModel`.
  • Network accessline 28
    KEYWORDS = ["lawn", "mowers"]   # words that must all appear in the category URL path UA = "browser-harness-domain-skill/1.0 (+https://github.com/browser-use/browser-harness)"   # truthful client UA
  • Network accessline 29
    UA = "browser-harness-domain-skill/1.0 (+https://github.com/browser-use/browser-harness)"   # truthful client UA
  • Network accessline 48
    for attempt in range(1, tries + 1):         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 49
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 50
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 51
    with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 91
    rules = robots_rules(get("https://www.homedepot.com/robots.txt"))
  • Network accessline 92
    if not rules:     raise RuntimeError("robots.txt has no User-agent: * rules (layout change?); stop") index = get("https://www.homedepot.com/sitemap/B/PLPs.xml")
  • Network accessline 93
    raise RuntimeError("robots.txt has no User-agent: * rules (layout change?); stop") index = get("https://www.homedepot.com/sitemap/B/PLPs.xml") core = [u for u in re.findall(r"<loc>([^<]+)</loc>", index) if "/PLP_CORE_TAX/" in u]
  • Network accessline 94
    index = get("https://www.homedepot.com/sitemap/B/PLPs.xml")
  • Network accessline 117
    1 core category sitemap(s), 5356 category URLs 15 match ['lawn', 'mowers']; 0 dropped as disallowed by robots.txt https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers/N-5yc1vZc5ar
  • Network accessline 118
    15 match ['lawn', 'mowers']; 0 dropped as disallowed by robots.txt https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers/N-5yc1vZc5ar https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Riding-Lawn-Mowers/N-5yc1v
  • Network accessline 119
    https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers/N-5yc1vZc5ar
  • Network accessline 120
    https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Riding-Lawn-Mowers/N-5yc1vZc5ax
  • Network accessline 121
    https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers-Push-Mowers/N-5yc1vZc5ah
  • Network accessline 122
    https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers-Reel-Lawn-Mowers/N-5yc1vZc5av
  • Network accessline 134
    CATEGORY = "https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers/N-5yc1vZc5ar"   # from block 1, no query string
  • Network accessline 135
    MAX_PAGES = 3             # safety cap; the run prints when it stops because of it MAX_WAIT = 120            # longest backoff / Retry-After sleep in seconds; a longer ask stops the run UA = "browser-harness-domain-skill/1.0 (+https://githu
  • Network accessline 137
    UA = "browser-harness-domain-skill/1.0 (+https://github.com/browser-use/browser-harness)"   # robots.txt fetch only
  • Network accessline 201
    for attempt in range(1, tries + 1):         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 202
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 203
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 204
    with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 359
    "rating": num(rr.get("averageRating")),         "reviews": int(reviews) if reviews is not None else None,         "url": "https://www.homedepot.com" + url if isinstance(url, str) and url.startswith("/") else None,
  • Network accessline 360
    "reviews": int(reviews) if reviews is not None else None,         "url": "https://www.homedepot.com" + url if isinstance(url, str) and url.startswith("/") else None,         "sponsored": bool(obj(p.get("info")).get("isSponsored")),
  • Network accessline 361
    "url": "https://www.homedepot.com" + url if isinstance(url, str) and url.startswith("/") else None,
  • Network accessline 366
    if urllib.parse.urlsplit(CATEGORY).query or not re.match(r"https://www\.homedepot\.com/b/", CATEGORY):
  • Network accessline 367
    raise ValueError("CATEGORY must be a https://www.homedepot.com/b/... URL without a query string")
  • Network accessline 368
    RULES = robots_rules(get("https://www.homedepot.com/robots.txt"))
  • Network accessline 376
    # A brand-new session is served a default store until the site's own script sets the # THD_LOCALIZER cookie. Open the home page first so every listing page uses the same store. open_page("https://www.homedepot.com/", lambda d: d["cookie"], 
  • Network accessline 377
    # THD_LOCALIZER cookie. Open the home page first so every listing page uses the same store. open_page("https://www.homedepot.com/", lambda d: d["cookie"], "home page warm-up") time.sleep(3)
  • Network accessline 378
    open_page("https://www.homedepot.com/", lambda d: d["cookie"], "home page warm-up")
  • Network accessline 381
    data = open_page(CATEGORY, grid_done(0), "category page 1") base = data["path"] if not re.match(r"https://www\.homedepot\.com/b/", base):
  • Network accessline 382
    base = data["path"] if not re.match(r"https://www\.homedepot\.com/b/", base):     raise RuntimeError(f"category landed on an unexpected page: {data['href']}")
  • Network accessline 383
    if not re.match(r"https://www\.homedepot\.com/b/", base):
  • Network accessline 437
    landed on: https://www.homedepot.com/b/Outdoors-Outdoor-Power-Equipment-Lawn-Mowers/N-5yc1vZc5ar | Lawn Mowers - The Home Depot
  • Network accessline 452
    "rating": 4.5112,   "reviews": 1254,   "url": "https://www.homedepot.com/p/RYOBI-40V-HP-Brushless-20-in-Cordless-Battery-Walk-Behind-Push-Lawn-Mower-with-6-0-Ah-Battery-and-Charger-RY40HPLM06K/337561634",
  • Network accessline 453
    "reviews": 1254,   "url": "https://www.homedepot.com/p/RYOBI-40V-HP-Brushless-20-in-Cordless-Battery-Walk-Behind-Push-Lawn-Mower-with-6-0-Ah-Battery-and-Charger-RY40HPLM06K/337561634",   "sponsored": false,
  • Network accessline 454
    "url": "https://www.homedepot.com/p/RYOBI-40V-HP-Brushless-20-in-Cordless-Battery-Walk-Behind-Push-Lawn-Mower-with-6-0-Ah-Battery-and-Charger-RY40HPLM06K/337561634",
  • Network accessline 478
    ITEM_ID = "320326875"   # the digits at the end of any /p/ URL, or item_id from the block 2 rows UA = "browser-harness-domain-skill/1.0 (+https://github.com/browser-use/browser-harness)"   # robots.txt fetch only
  • Network accessline 479
    UA = "browser-harness-domain-skill/1.0 (+https://github.com/browser-use/browser-harness)"   # robots.txt fetch only
  • Network accessline 511
    for attempt in range(1, tries + 1):         try:             req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 512
    try:             req = urllib.request.Request(url, headers={"User-Agent": UA})             with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 513
    req = urllib.request.Request(url, headers={"User-Agent": UA})
  • Network accessline 514
    with urllib.request.urlopen(req, timeout=60) as r:
  • Network accessline 630
    RULES = robots_rules(get("https://www.homedepot.com/robots.txt"))
  • Network accessline 636
    cdp("Page.addScriptToEvaluateOnNewDocument", source=HOOK) # Warm-up: let the site pick a store (THD_LOCALIZER cookie) before the product page asks for stock. open_page("https://www.homedepot.com/", lambda d: d["cookie"], "home page warm-up"
  • Network accessline 637
    # Warm-up: let the site pick a store (THD_LOCALIZER cookie) before the product page asks for stock. open_page("https://www.homedepot.com/", lambda d: d["cookie"], "home page warm-up") time.sleep(3)
  • Network accessline 638
    open_page("https://www.homedepot.com/", lambda d: d["cookie"], "home page warm-up")
  • Network accessline 639
    time.sleep(3) # /p/<id> redirects to the canonical /p/<slug>/<id>; wait for that page's own JSON-LD. d = open_page(f"https://www.homedepot.com/p/{ITEM_ID}",
  • Network accessline 640
    # /p/<id> redirects to the canonical /p/<slug>/<id>; wait for that page's own JSON-LD. d = open_page(f"https://www.homedepot.com/p/{ITEM_ID}",               lambda d: d["path"].rstrip("/").endswith("/" + ITEM_ID) and ld_product(d["ld"]) is 
  • Network accessline 641
    d = open_page(f"https://www.homedepot.com/p/{ITEM_ID}",
  • Network accessline 730
    "rating": 4.7,  "reviews": 2491,  "url": "https://www.homedepot.com/p/Milwaukee-M18-FUEL-18V-Lithium-Ion-Brushless-Cordless-1-4-in-Hex-Impact-Driver-Tool-Only-2953-20/320326875",
  • Network accessline 731
    "reviews": 2491,  "url": "https://www.homedepot.com/p/Milwaukee-M18-FUEL-18V-Lithium-Ion-Brushless-Cordless-1-4-in-Hex-Impact-Driver-Tool-Only-2953-20/320326875",  "image": "https://images.thdstatic.com/productImages/3ca82630-d888-44f5-bd56
  • Network accessline 732
    "url": "https://www.homedepot.com/p/Milwaukee-M18-FUEL-18V-Lithium-Ion-Brushless-Cordless-1-4-in-Hex-Impact-Driver-Tool-Only-2953-20/320326875",
  • Network accessline 733
    "image": "https://images.thdstatic.com/productImages/3ca82630-d888-44f5-bd56-b2798a6d59f8/svn/milwaukee-impact-drivers-2953-20-64_100.jpg",

agent-workspace/domain-skills/howlongtobeat/scraping.md

  • Network accessline 17
    def get_token():     """Fetch a fresh session token. Token encodes IP+UA+timestamp, reusable for ~15 min."""     url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 18
    """Fetch a fresh session token. Token encodes IP+UA+timestamp, reusable for ~15 min."""     url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"     data = http_get(url, headers={"Referer": "https://howlongtobeat.com/"
  • Network accessline 19
    url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 20
    data = http_get(url, headers={"Referer": "https://howlongtobeat.com/"})
  • Network accessline 49
    hp_key: hp_val      # honeypot field — key and value vary per token     }     req = urllib.request.Request(
  • Network accessline 50
    }     req = urllib.request.Request(         "https://howlongtobeat.com/api/find",
  • Network accessline 51
    req = urllib.request.Request(
  • Network accessline 52
    "https://howlongtobeat.com/api/find",
  • Network accessline 55
    "User-Agent": UA,             "Content-Type": "application/json",             "Origin": "https://howlongtobeat.com",
  • Network accessline 56
    "Content-Type": "application/json",             "Origin": "https://howlongtobeat.com",             "Referer": "https://howlongtobeat.com/",
  • Network accessline 57
    "Origin": "https://howlongtobeat.com",
  • Network accessline 58
    "Referer": "https://howlongtobeat.com/",
  • Network accessline 63
    method="POST"     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 64
    )     with urllib.request.urlopen(req, timeout=20) as r:         return json.loads(r.read().decode())
  • Network accessline 65
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 97
    def hltb_search(title, size=5):     """One-shot: get token + search, return list of dicts with hours."""     url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 98
    """One-shot: get token + search, return list of dicts with hours."""     url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"     tok = json.loads(http_get(url, headers={"Referer": "https://howlongtobeat.com/"}))
  • Network accessline 99
    url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 100
    tok = json.loads(http_get(url, headers={"Referer": "https://howlongtobeat.com/"}))
  • Network accessline 112
    "useCache": True, hp_key: hp_val     }     req = urllib.request.Request(
  • Network accessline 113
    }     req = urllib.request.Request(         "https://howlongtobeat.com/api/find", data=json.dumps(payload).encode(),
  • Network accessline 114
    req = urllib.request.Request(
  • Network accessline 115
    "https://howlongtobeat.com/api/find", data=json.dumps(payload).encode(),
  • Network accessline 116
    [Credential-related source omitted]
  • Network accessline 117
    "Origin": "https://howlongtobeat.com", "Referer": "https://howlongtobeat.com/",
  • Network accessline 119
    method="POST"     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 120
    )     with urllib.request.urlopen(req, timeout=20) as r:         data = json.loads(r.read().decode())
  • Network accessline 121
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 140
    "comp_count":   g["comp_100_count"],             "review_score": g["review_score"],       # 0–100             "image_url":    f"https://howlongtobeat.com/games/{g['game_image']}",
  • Network accessline 141
    "review_score": g["review_score"],       # 0–100             "image_url":    f"https://howlongtobeat.com/games/{g['game_image']}",             "page_url":     f"https://howlongtobeat.com/game/{g['game_id']}",
  • Network accessline 142
    "image_url":    f"https://howlongtobeat.com/games/{g['game_image']}",
  • Network accessline 143
    "page_url":     f"https://howlongtobeat.com/game/{g['game_id']}",
  • Network accessline 171
    Returns pageProps['game']['data'] with keys: 'game', 'individuality', 'relationships'.     """     html = http_get(f"https://howlongtobeat.com/game/{game_id}")
  • Network accessline 172
    """     html = http_get(f"https://howlongtobeat.com/game/{game_id}")     nd = json.loads(re.search(
  • Network accessline 173
    html = http_get(f"https://howlongtobeat.com/game/{game_id}")
  • Network accessline 252
    def get_times(title):     """Return Main/+Extras/100% hours for the top search match."""     tok_url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 253
    """Return Main/+Extras/100% hours for the top search match."""     tok_url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"     tok = json.loads(http_get(tok_url, headers={"Referer": "https://howlongtobeat.com/"}))
  • Network accessline 254
    tok_url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 255
    tok = json.loads(http_get(tok_url, headers={"Referer": "https://howlongtobeat.com/"}))
  • Network accessline 267
    "useCache": True, hp_key: hp_val     }     req = urllib.request.Request(
  • Network accessline 268
    }     req = urllib.request.Request(         "https://howlongtobeat.com/api/find", data=json.dumps(payload).encode(),
  • Network accessline 269
    req = urllib.request.Request(
  • Network accessline 270
    "https://howlongtobeat.com/api/find", data=json.dumps(payload).encode(),
  • Network accessline 271
    [Credential-related source omitted]
  • Network accessline 272
    "Origin": "https://howlongtobeat.com", "Referer": "https://howlongtobeat.com/",
  • Network accessline 274
    method="POST"     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 275
    )     with urllib.request.urlopen(req, timeout=20) as r:         data = json.loads(r.read().decode())
  • Network accessline 276
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 302
    def search_all_pages(title, size=20):     """Yield every search result for a query across all pages."""     tok_url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 303
    """Yield every search result for a query across all pages."""     tok_url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"     tok = json.loads(http_get(tok_url, headers={"Referer": "https://howlongtobeat.com/"}))
  • Network accessline 304
    tok_url = f"https://howlongtobeat.com/api/find/init?t={int(time.time()*1000)}"
  • Network accessline 305
    tok = json.loads(http_get(tok_url, headers={"Referer": "https://howlongtobeat.com/"}))
  • Network accessline 321
    "useCache": True, hp_key: hp_val         }         req = urllib.request.Request(
  • Network accessline 322
    }         req = urllib.request.Request(             "https://howlongtobeat.com/api/find", data=json.dumps(payload).encode(),
  • Network accessline 323
    req = urllib.request.Request(
  • Network accessline 324
    "https://howlongtobeat.com/api/find", data=json.dumps(payload).encode(),
  • Network accessline 325
    [Credential-related source omitted]
  • Network accessline 326
    "Origin": "https://howlongtobeat.com", "Referer": "https://howlongtobeat.com/",
  • Network accessline 328
    method="POST"         )         with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 329
    )         with urllib.request.urlopen(req, timeout=20) as r:             data = json.loads(r.read().decode())
  • Network accessline 330
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 349
    def fetch_game(game_id):     html = http_get(f"https://howlongtobeat.com/game/{game_id}")
  • Network accessline 350
    html = http_get(f"https://howlongtobeat.com/game/{game_id}")
  • Network accessline 387
    | `game_alias` | str | Alternate title / edition name | | `game_type` | str | `"game"` \| `"dlc"` \| `"expansion"` \| `"hack"` | | `game_image` | str | Image filename → `https://howlongtobeat.com/games/{game_image}` |
  • Network accessline 388
    | `game_type` | str | `"game"` \| `"dlc"` \| `"expansion"` \| `"hack"` | | `game_image` | str | Image filename → `https://howlongtobeat.com/games/{game_image}` | | `release_world` | int | Release year (just the year integer, not a date) |
  • Network accessline 389
    | `game_image` | str | Image filename → `https://howlongtobeat.com/games/{game_image}` |
  • Network accessline 439
    - **Token system**: Every search requires a fresh token from `/api/find/init`. Token encodes `timestamp::IP|UA|hpKey|hmacHash`. The server validates that the UA used to fetch the token matches the UA used in the search POST. - **Honeypot fi
  • Network accessline 440
    - **Honeypot field**: `hpKey` and `hpVal` from the init response must appear as a top-level field in the POST body (e.g., `{"ign_7671546b": "a6679ea54598d502", ...}`). The key name rotates per request. - **Required headers on search POST**:
  • Network accessline 441
    - **Required headers on search POST**: `Origin: https://howlongtobeat.com` AND `Referer: https://howlongtobeat.com/` — missing either causes HTTP 403 or 404. `x-auth-token`, `x-hp-key`, `x-hp-val` are also required. - **Required header on i
  • Network accessline 442
    - **Required header on init GET**: `Referer: https://howlongtobeat.com/` — missing causes HTTP 403. - **Token reuse**: A single token works for multiple searches and multiple pages. No per-request token fetch needed. - **No CAPTCHA** observ

agent-workspace/domain-skills/hubspot/private-app-webhooks.md

  • Network accessline 7
    - `https://app-<region>.hubspot.com/private-apps/{portalId}/{appId}/webhooks` — **read-only view** of current subscriptions. Useful for verification after a change. `<region>` is `na1`, `na2`, `eu1`, etc.
  • Network accessline 8
    - `https://app-<region>.hubspot.com/private-apps/{portalId}/{appId}/edit` — drops you into the editor. From here, click the **Webhooks** tab in the left rail to reach the subscription editor.

agent-workspace/domain-skills/imdb/scraping.md

  • Network accessline 3
    `https://www.imdb.com` — the Internet Movie Database. Field-tested on 2026-04-24 against `chart/top`, `chart/moviemeter`, `find/?s=tt&q=`, and `title/tt{id}/` pages.
  • Network accessline 31
    goto("https://www.imdb.com/chart/top/")
  • Network accessline 97
    goto("https://www.imdb.com/chart/moviemeter/")
  • Network accessline 117
    def imdb_search(keyword, limit=25):     q = urllib.parse.quote(keyword)     goto(f"https://www.imdb.com/find/?s=tt&q={q}")
  • Network accessline 118
    q = urllib.parse.quote(keyword)     goto(f"https://www.imdb.com/find/?s=tt&q={q}")     wait_for_load()
  • Network accessline 119
    goto(f"https://www.imdb.com/find/?s=tt&q={q}")
  • Network accessline 157
    hits = imdb_search("shawshank") # [{'tt_id': 'tt0111161', 'title': 'The Shawshank Redemption', #   'url': 'https://www.imdb.com/title/tt0111161/',
  • Network accessline 158
    # [{'tt_id': 'tt0111161', 'title': 'The Shawshank Redemption', #   'url': 'https://www.imdb.com/title/tt0111161/', #   'meta': ['1994', 'Feature', 'Tim Robbins, Morgan Freeman']}, ...]
  • Network accessline 159
    #   'url': 'https://www.imdb.com/title/tt0111161/',
  • Network accessline 177
    def more_like_this(tt_id, limit=12):     goto(f"https://www.imdb.com/title/{tt_id}/")
  • Network accessline 178
    goto(f"https://www.imdb.com/title/{tt_id}/")
  • Network accessline 265
    **`http_get` works on title pages.** If you only need year, runtime, directors, cast, and the aggregate rating, a plain `http_get(f"https://www.imdb.com/title/{tt_id}/")` gives you the `<script type="application/ld+json">` Movie block in on

agent-workspace/domain-skills/itch-io/scraping.md

  • Network accessline 33
    Parse any itch.io RSS listing feed.     url examples:       https://itch.io/games/top-rated.xml
  • Network accessline 34
    url examples:       https://itch.io/games/top-rated.xml       https://itch.io/games/newest.xml
  • Network accessline 35
    https://itch.io/games/top-rated.xml
  • Network accessline 36
    https://itch.io/games/newest.xml
  • Network accessline 37
    https://itch.io/games/featured.xml
  • Network accessline 38
    https://itch.io/games/on-sale.xml
  • Network accessline 39
    https://itch.io/games/free.xml
  • Network accessline 40
    https://itch.io/games/tag-puzzle.xml    # any tag slug works
  • Network accessline 41
    https://itch.io/games/top-rated.xml?page=2
  • Network accessline 66
    # Confirmed output: items = parse_rss("https://itch.io/games/top-rated.xml")
  • Network accessline 67
    items = parse_rss("https://itch.io/games/top-rated.xml")
  • Network accessline 68
    # items[0] -> { #   'url':         'https://gbpatch.itch.io/our-life', #   'title':       'Our Life: Beginnings & Always',
  • Network accessline 69
    #   'url':         'https://gbpatch.itch.io/our-life',
  • Network accessline 73
    #   'pub_date':    'Fri, 07 Jun 2019 23:47:57 GMT', #   'update_date': 'Sun, 22 May 2022 15:48:27 GMT', #   'image':       'https://img.itch.zone/aW1nLzcwMTIxNDMucG5n/315x250%23c/BalGQb.png',
  • Network accessline 74
    #   'update_date': 'Sun, 22 May 2022 15:48:27 GMT', #   'image':       'https://img.itch.zone/aW1nLzcwMTIxNDMucG5n/315x250%23c/BalGQb.png', #   'platforms':   {'windows': True, 'osx': True, 'linux': True, 'android': True},
  • Network accessline 75
    #   'image':       'https://img.itch.zone/aW1nLzcwMTIxNDMucG5n/315x250%23c/BalGQb.png',
  • Network accessline 92
    Extract all game cards from any itch.io browse/listing/search/profile HTML page.     Works on:       https://itch.io/games/top-rated
  • Network accessline 93
    Works on:       https://itch.io/games/top-rated       https://itch.io/games/newest
  • Network accessline 94
    https://itch.io/games/top-rated
  • Network accessline 95
    https://itch.io/games/newest
  • Network accessline 96
    https://itch.io/games/featured
  • Network accessline 97
    https://itch.io/games/on-sale
  • Network accessline 98
    https://itch.io/games/free
  • Network accessline 99
    https://itch.io/games/tag-puzzle      (genre/tag path)
  • Network accessline 100
    https://itch.io/search?q=platformer   (search — 54 cards per page)
  • Network accessline 142
    # Usage: html = http_get("https://itch.io/games/top-rated")
  • Network accessline 143
    html = http_get("https://itch.io/games/top-rated")
  • Network accessline 144
    games = parse_game_cards(html) # games[0] -> { #   'id': '434554', 'url': 'https://gbpatch.itch.io/our-life',
  • Network accessline 145
    # games[0] -> { #   'id': '434554', 'url': 'https://gbpatch.itch.io/our-life', #   'title': 'Our Life: Beginnings & Always',
  • Network accessline 146
    #   'id': '434554', 'url': 'https://gbpatch.itch.io/our-life',
  • Network accessline 153
    # Paid game example: html = http_get("https://itch.io/games/top-rated?page=5")
  • Network accessline 154
    html = http_get("https://itch.io/games/top-rated?page=5")
  • Network accessline 242
    # Free game: r = extract_game_detail("https://gbpatch.itch.io/our-life")
  • Network accessline 243
    r = extract_game_detail("https://gbpatch.itch.io/our-life")
  • Network accessline 247
    #   'price': None, 'currency': None,   <- no 'offers' block for free games #   'rating': '4.9', 'rating_count': 7191, #   'cover': 'https://img.itch.zone/aW1hZ2Uv.../347x500/7HqrvV.jpg',
  • Network accessline 248
    #   'rating': '4.9', 'rating_count': 7191, #   'cover': 'https://img.itch.zone/aW1hZ2Uv.../347x500/7HqrvV.jpg', #   'info': {
  • Network accessline 249
    #   'cover': 'https://img.itch.zone/aW1hZ2Uv.../347x500/7HqrvV.jpg',
  • Network accessline 261
    # Paid game: r = extract_game_detail("https://adamgryu.itch.io/a-short-hike")
  • Network accessline 262
    r = extract_game_detail("https://adamgryu.itch.io/a-short-hike")
  • Network accessline 308
    """     Scrape multiple pages from any itch.io browse URL.     base_url: https://itch.io/games/top-rated  (no ?page= suffix)
  • Network accessline 309
    Scrape multiple pages from any itch.io browse URL.     base_url: https://itch.io/games/top-rated  (no ?page= suffix)     Returns flat list of game dicts.
  • Network accessline 310
    base_url: https://itch.io/games/top-rated  (no ?page= suffix)
  • Network accessline 341
    BASE = "https://itch.io/games"
  • Network accessline 354
    # Combine: tag + sort via separate pages (no combined URL that survives http_get) # Note: https://itch.io/games/top-rated/tag-puzzle -> HTTP 403
  • Network accessline 355
    # Note: https://itch.io/games/top-rated/tag-puzzle -> HTTP 403
  • Network accessline 367
    # Search (54 results/page, no server-side pagination beyond page 1 via http_get) "https://itch.io/search?q=platformer"
  • Network accessline 368
    "https://itch.io/search?q=platformer"
  • Network accessline 378
    itch.io has an official REST API. A free key is issued per-account with no rate limit published. Get one at: `https://itch.io/user/settings/api-keys`
  • Network accessline 379
    Get one at: `https://itch.io/user/settings/api-keys`
  • Network accessline 381
    Base URL: `https://itch.io/api/1/<key>/`
  • Network accessline 387
    ITCH_KEY = "your_api_key_here"   # from https://itch.io/user/settings/api-keys
  • Network accessline 389
    def api(path):     return json.loads(http_get(f"https://itch.io/api/1/{ITCH_KEY}/{path}"))
  • Network accessline 390
    return json.loads(http_get(f"https://itch.io/api/1/{ITCH_KEY}/{path}"))
  • Network accessline 411
    **No unauthenticated game lookup API.** `https://itch.io/api/1/x/games` -> HTTP 404.
  • Network accessline 428
    6. **`?tag=` query param is ignored server-side.** `https://itch.io/games/top-rated?tag=puzzle` returns the same games as `?top-rated`. Use `/games/tag-puzzle` path instead.
  • Network accessline 432
    8. **Search beyond page 1 is AJAX-only.** `https://itch.io/search?q=X&page=2` via `http_get` returns the same 54 results as page 1. To get more search results use the browser and scroll/click "load more".
  • Possible obfuscationline 436
    10. **Unicode zero-width space in some titles.** `\u200b` (zero-width space) appears at the start of certain titles (e.g. "<U+200B>Our Life: Beginnings & Always"). Strip with `.replace('\u200b', '').strip()` or `.strip()` alone won't remove it — u

agent-workspace/domain-skills/jetblue/checkout.md

  • Network accessline 9
    - Home: `https://www.jetblue.com`
  • Network accessline 10
    - Search results (deep link, skips home form): `https://www.jetblue.com/booking/flights?from={IATA}&to={IATA}&depart=YYYY-MM-DD&isMultiCity=false&noOfRoute=1&adults=1&children=0&infants=0&roundTripFaresFlag=false&sharedMarket=false&usePoint
  • Network accessline 11
    - Cart: `https://www.jetblue.com/booking/cart`
  • Network accessline 12
    - Checkout (all three steps share this URL; tabs rendered as sections): `https://www.jetblue.com/booking/checkout` (titles change: `Traveler Details` -> `Seats & Extras` -> `Review & Pay`)

agent-workspace/domain-skills/job-boards/indeed-glassdoor.md

  • Network accessline 14
    # Indeed — English (US) query, location = "Python developer", "San Francisco" goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}")
  • Network accessline 15
    query, location = "Python developer", "San Francisco" goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}") wait_for_load()
  • Network accessline 16
    goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}")
  • Network accessline 20
    # Indeed — last 24 hours goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}&fromage=1")
  • Network accessline 21
    goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}&fromage=1")
  • Network accessline 25
    # Glassdoor — public search (no login required for result cards) goto_url(f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}")
  • Network accessline 26
    goto_url(f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}")
  • Network accessline 30
    # Stepstone (Germany) keyword, city = "Data Scientist", "Berlin" goto_url(f"https://www.stepstone.de/jobs/{quote_plus(keyword)}/in-{quote_plus(city)}.html")
  • Network accessline 31
    keyword, city = "Data Scientist", "Berlin" goto_url(f"https://www.stepstone.de/jobs/{quote_plus(keyword)}/in-{quote_plus(city)}.html") wait_for_load()
  • Network accessline 32
    goto_url(f"https://www.stepstone.de/jobs/{quote_plus(keyword)}/in-{quote_plus(city)}.html")
  • Network accessline 53
    | Page 2 (results 11-20) | append `&start=10` | | Page 3 (results 21-30) | append `&start=20` | | Job detail page | `https://www.indeed.com/viewjob?jk={job_key}` |
  • Network accessline 55
    | Job detail page | `https://www.indeed.com/viewjob?jk={job_key}` |
  • Network accessline 79
    kw_path = keyword.replace(" ", "-") city_path = city.replace(" ", "-") goto_url(f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}.html")
  • Network accessline 81
    goto_url(f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}.html")
  • Network accessline 125
    goto_url("https://www.indeed.co.uk/jobs?q=Python+developer&l=London")
  • Network accessline 142
    query, location = "machine learning engineer", "New York" goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}")
  • Network accessline 143
    goto_url(f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}")
  • Network accessline 178
    // Direct URL via job key     var url = 'https://www.indeed.com/viewjob?jk=' + jk;
  • Network accessline 179
    var url = 'https://www.indeed.com/viewjob?jk=' + jk;
  • Network accessline 205
    query, location = "data scientist", "remote" base_url = f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}"
  • Network accessline 206
    base_url = f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}"
  • Network accessline 238
    salary:  salEl   ? salEl.innerText.trim()   : '',           posted:  dateEl  ? dateEl.innerText.trim()  : '',           url: 'https://www.indeed.com/viewjob?jk=' + jk,
  • Network accessline 239
    posted:  dateEl  ? dateEl.innerText.trim()  : '',           url: 'https://www.indeed.com/viewjob?jk=' + jk,         });
  • Network accessline 240
    url: 'https://www.indeed.com/viewjob?jk=' + jk,
  • Network accessline 257
    base_url = f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}&fromage=1"
  • Network accessline 269
    def get_indeed_job_detail(jk: str) -> dict:     """Fetch full job details from an Indeed job key."""     goto_url(f"https://www.indeed.com/viewjob?jk={jk}")
  • Network accessline 270
    """Fetch full job details from an Indeed job key."""     goto_url(f"https://www.indeed.com/viewjob?jk={jk}")     wait_for_load()
  • Network accessline 271
    goto_url(f"https://www.indeed.com/viewjob?jk={jk}")
  • Network accessline 326
    query = "product manager" goto_url(f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}")
  • Network accessline 327
    goto_url(f"https://www.glassdoor.com/Job/jobs.htm?sc.keyword={quote_plus(query)}")
  • Network accessline 370
    // Canonical URL     var linkEl = c.querySelector('a[href*="/job-listing/"], a[href*="glassdoor.com/job"]');     var url = linkEl ? linkEl.href : (jobId ? 'https://www.glassdoor.com/job-listing/glassdoor-jl' + jobId + '.htm' : '');
  • Network accessline 372
    var url = linkEl ? linkEl.href : (jobId ? 'https://www.glassdoor.com/job-listing/glassdoor-jl' + jobId + '.htm' : '');
  • Network accessline 451
    goto_url(f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}.html")
  • Network accessline 500
    for page in range(1, 4):   # pages 1-3     if page == 1:         url = f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}.html"
  • Network accessline 501
    if page == 1:         url = f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}.html"     else:
  • Network accessline 502
    url = f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}.html"
  • Network accessline 504
    url = f"https://www.stepstone.de/jobs/{kw_path}/in-{city_path}/page-{page}.html"
  • Network accessline 562
    # Canonical job detail URL for any job key: for jk in jks:     direct_url = f"https://www.indeed.com/viewjob?jk={jk}"
  • Network accessline 563
    for jk in jks:     direct_url = f"https://www.indeed.com/viewjob?jk={jk}"     print(direct_url)
  • Network accessline 564
    direct_url = f"https://www.indeed.com/viewjob?jk={jk}"
  • Network accessline 718
    html = http_get(         f"https://www.indeed.com/jobs?{params}",
  • Network accessline 719
    f"https://www.indeed.com/jobs?{params}",
  • Network accessline 758
    "salary":   r.get("salarySnippet", {}).get("text", ""),             "posted":   r.get("formattedRelativeTime", ""),             "url":      f"https://www.indeed.com/viewjob?jk={jk}",
  • Network accessline 759
    "posted":   r.get("formattedRelativeTime", ""),             "url":      f"https://www.indeed.com/viewjob?jk={jk}",             "snippet":  r.get("snippet", ""),  # short description preview
  • Network accessline 760
    "url":      f"https://www.indeed.com/viewjob?jk={jk}",
  • Network accessline 780
    def get_application_type(jk: str) -> dict:     """Returns {type: 'easy_apply'|'external'|'unknown', external_url: str|None}"""     goto_url(f"https://www.indeed.com/viewjob?jk={jk}")
  • Network accessline 781
    """Returns {type: 'easy_apply'|'external'|'unknown', external_url: str|None}"""     goto_url(f"https://www.indeed.com/viewjob?jk={jk}")     wait_for_load()
  • Network accessline 782
    goto_url(f"https://www.indeed.com/viewjob?jk={jk}")
  • Network accessline 887
    start: int = 0, ) -> str:     base = f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}"
  • Network accessline 888
    ) -> str:     base = f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}"     if fromage:
  • Network accessline 889
    base = f"https://www.indeed.com/jobs?q={quote_plus(query)}&l={quote_plus(location)}"
  • Network accessline 955
    salary:   salEl   ? salEl.innerText.trim()   : '',               posted:   dateEl  ? dateEl.innerText.trim()  : '',               url: 'https://www.indeed.com/viewjob?jk=' + jk,
  • Network accessline 956
    posted:   dateEl  ? dateEl.innerText.trim()  : '',               url: 'https://www.indeed.com/viewjob?jk=' + jk,             });
  • Network accessline 957
    url: 'https://www.indeed.com/viewjob?jk=' + jk,
  • Network accessline 987
    - **Indeed redirect links are NOT stable URLs** — Anchor `href` values in search results go through `https://www.indeed.com/rc/clk?...` tracking redirects which expire. Always extract `data-jk` from the card and construct `https://www.indee

agent-workspace/domain-skills/kalshi/scraping.md

  • Network accessline 3
    Field-tested against kalshi.com and api.elections.kalshi.com on 2026-11-02 using a Browser Use cloud browser, logged out. Every browser call is a `fetch()` from a kalshi.com tab to Kalshi's public Trade API. No CAPTCHA, 403 or 429 across ab
  • Network accessline 5
    robots.txt (kalshi.com, fetched 2026-11-02 in the browser): `User-agent: *` disallows only `/ideas` (except `/ideas/profiles/` and `/ideas/posts/`), `/sign-up?` and `/search`, so `/robots.txt` and `/markets/...` are allowed; api.elections.k
  • Network accessline 13
    - `GET /trade-api/v2/markets/<TICKER>/orderbook?depth=<n>` - bids only, both sides, as `[price_dollars, contracts]` string pairs.   - `GET /trade-api/v2/markets/trades?ticker=<TICKER>&limit=<n>` - recent fills. - **Base host:** `https://api
  • Network accessline 14
    - `GET /trade-api/v2/markets/trades?ticker=<TICKER>&limit=<n>` - recent fills. - **Base host:** `https://api.elections.kalshi.com/trade-api/v2/` (Kalshi's AGENTS.md calls it production; the docs list `https://external-api.kalshi.com/trade-a
  • Network accessline 15
    - **Base host:** `https://api.elections.kalshi.com/trade-api/v2/` (Kalshi's AGENTS.md calls it production; the docs list `https://external-api.kalshi.com/trade-api/v2` first and this one as "also supported"; both returned the same events to
  • Network accessline 16
    - **Run `fetch()` from a kalshi.com tab.** The API's CORS answers `access-control-allow-origin: https://kalshi.com`. The blocks open `https://kalshi.com/robots.txt` (small, robots-allowed) once and reuse it.
  • Network accessline 22
    All browser blocks share the same helpers: `on_kalshi_tab()` opens `https://kalshi.com/robots.txt` once and later blocks reuse that tab; it raises if Vercel's "Security Checkpoint" page appears instead. `get(path, params)` fetches `https://
  • Network accessline 35
    API = "https://api.elections.kalshi.com/trade-api/v2/"
  • Network accessline 38
    def on_kalshi_tab():     """fetch() runs in a logged-out kalshi.com tab: the API's CORS allows that origin. Reuse the tab if already there."""
  • Network accessline 39
    """fetch() runs in a logged-out kalshi.com tab: the API's CORS allows that origin. Reuse the tab if already there."""
  • Network accessline 40
    try:         if js("location.origin") == "https://kalshi.com":             return
  • Network accessline 41
    if js("location.origin") == "https://kalshi.com":
  • Network accessline 43
    except Exception:         pass     new_tab("https://kalshi.com/robots.txt")   # small robots-allowed page on kalshi.com
  • Network accessline 44
    pass     new_tab("https://kalshi.com/robots.txt")   # small robots-allowed page on kalshi.com     wait_for_load()
  • Network accessline 45
    new_tab("https://kalshi.com/robots.txt")   # small robots-allowed page on kalshi.com
  • Network accessline 50
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, text: await r.text()}; }
  • Network accessline 51
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, text: await r.text()}; }
  • Network accessline 96
    "lead_last_cents": lead and cents(lead["last_price_dollars"]),                 "volume_24h": round(sum(float(m.get("volume_24h_fp") or 0) for m in ms), 2),                 "url": f"https://kalshi.com/markets/{e['series_ticker'].lower()}/{e[
  • Network accessline 97
    "volume_24h": round(sum(float(m.get("volume_24h_fp") or 0) for m in ms), 2),                 "url": f"https://kalshi.com/markets/{e['series_ticker'].lower()}/{e['event_ticker'].lower()}",             })
  • Network accessline 98
    "url": f"https://kalshi.com/markets/{e['series_ticker'].lower()}/{e['event_ticker'].lower()}",
  • Network accessline 140
    URLS = [     "https://kalshi.com/markets/kxfeddecision",                                        # series page: soonest-closing open event
  • Network accessline 141
    "https://kalshi.com/markets/kxfeddecision",                                        # series page: soonest-closing open event
  • Network accessline 142
    "https://kalshi.com/markets/kxhighny/highest-temperature-in-nyc/kxhighny-26nov01", # event page, settled
  • Network accessline 143
    "https://kalshi.com/markets/kxhighny/kxhighny-25jan01",                            # settled before the historical cutoff
  • Network accessline 144
    "https://kalshi.com/markets/kxnosuchseries",
  • Network accessline 147
    API = "https://api.elections.kalshi.com/trade-api/v2/"
  • Network accessline 150
    def on_kalshi_tab():     """fetch() runs in a logged-out kalshi.com tab: the API's CORS allows that origin. Reuse the tab if already there."""
  • Network accessline 151
    """fetch() runs in a logged-out kalshi.com tab: the API's CORS allows that origin. Reuse the tab if already there."""
  • Network accessline 152
    try:         if js("location.origin") == "https://kalshi.com":             return
  • Network accessline 153
    if js("location.origin") == "https://kalshi.com":
  • Network accessline 155
    except Exception:         pass     new_tab("https://kalshi.com/robots.txt")
  • Network accessline 156
    pass     new_tab("https://kalshi.com/robots.txt")     wait_for_load()
  • Network accessline 157
    new_tab("https://kalshi.com/robots.txt")
  • Network accessline 162
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, text: await r.text()}; }
  • Network accessline 163
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, text: await r.text()}; }
  • Network accessline 202
    "category": ev.get("category"), "mutually_exclusive": ev.get("mutually_exclusive"),         "settlement_sources": [s.get("name") for s in ev.get("settlement_sources") or []],         "url": f"https://kalshi.com/markets/{ev['series_ticker'].
  • Network accessline 203
    "settlement_sources": [s.get("name") for s in ev.get("settlement_sources") or []],         "url": f"https://kalshi.com/markets/{ev['series_ticker'].lower()}/{ev['event_ticker'].lower()}",         "markets": [{
  • Network accessline 204
    "url": f"https://kalshi.com/markets/{ev['series_ticker'].lower()}/{ev['event_ticker'].lower()}",
  • Network accessline 258
    https://kalshi.com/markets/kxnosuchseries: no open event found
  • Network accessline 270
    API = "https://api.elections.kalshi.com/trade-api/v2/"
  • Network accessline 273
    def on_kalshi_tab():     """fetch() runs in a logged-out kalshi.com tab: the API's CORS allows that origin. Reuse the tab if already there."""
  • Network accessline 274
    """fetch() runs in a logged-out kalshi.com tab: the API's CORS allows that origin. Reuse the tab if already there."""
  • Network accessline 275
    try:         if js("location.origin") == "https://kalshi.com":             return
  • Network accessline 276
    if js("location.origin") == "https://kalshi.com":
  • Network accessline 278
    except Exception:         pass     new_tab("https://kalshi.com/robots.txt")
  • Network accessline 279
    pass     new_tab("https://kalshi.com/robots.txt")     wait_for_load()
  • Network accessline 280
    new_tab("https://kalshi.com/robots.txt")
  • Network accessline 285
    FETCH_JS = """(async () => {   try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, text: await r.text()}; }
  • Network accessline 286
    try { const r = await fetch(%s, {credentials: 'omit'}); return {status: r.status, text: await r.text()}; }
  • Network accessline 379
    curl -s "https://api.elections.kalshi.com/trade-api/v2/markets/KXFEDDECISION-26DEC-H25/orderbook?depth=3"; echo
  • Dangerous shell operationline 380
    curl -s "https://api.elections.kalshi.com/trade-api/v2/historical/markets?event_ticker=KXHIGHNY-25JAN01"    | python3 -c 'import json, sys; [print(m["ticker"], m["result"], m["last_price_dollars"]) for m in json.load(sys.stdin)["markets"]]'
  • Network accessline 380
    curl -s "https://api.elections.kalshi.com/trade-api/v2/historical/markets?event_ticker=KXHIGHNY-25JAN01" \
  • Network accessline 414
    - **Bids only in the order book.** A NO bid at p is a YES ask at 1 - p (Kalshi's "Orderbook Responses" doc). Today the computed best ask matched the market snapshot's `yes_ask_dollars` (0.73 / 0.73) and best bid matched `yes_bid_dollars` (0
  • Network accessline 415
    - **Unknown ticker on `/orderbook` is HTTP 200** with empty `yes_dollars` / `no_dollars`, not 404. Block 3 checks `/markets/<ticker>` first (that one returns 404 `{"error":{"code":"not_found",...}}`). - **Status filter values differ from st
  • Network accessline 416
    - **Status filter values differ from status field values.** Filter with `status=open` (`unopened`, `open`, `closed`, `settled`); market objects say `active` / `finalized`. `status=active`, which kalshi.com/AGENTS.md shows in its `/markets` 
  • Network accessline 421
    - **Sum of YES asks exceeds 100c** in mutually exclusive events (on 2026-11-02: 105c for the Fed decision, 103c to 105c during the day for NYC high temperature on Nov 2): asks carry the spread. Use last or mid for an implied probability. - 
  • Network accessline 422
    - **Page vs API.** On the event page, "Yes NNc" is the YES ask, "No NNc" the NO ask, and the big percent matched `last_price_dollars` in the row checked (65° to 66°: 92% / Yes 92c / No 10c vs API last 0.92, yes_ask 0.92, no_ask 0.10). Anoth
  • Network accessline 423
    - **URLs.** `https://kalshi.com/markets/<series>/<event>` (lowercase) redirects to the canonical `/markets/<series>/<slug>/<event>`, and `/markets/<series>` redirects to its current event, so a URL can be built from tickers alone. - **Rate 
  • Network accessline 429
    - **Same-origin `fetch()` from an api.elections.kalshi.com tab:** `TypeError: Failed to fetch` on every path today, although navigating to the same URL showed the JSON. Fetch from a kalshi.com tab instead.
  • Network accessline 430
    - **Other origins:** a request with `Origin: https://example.com` got HTTP 403, so `fetch()` from a non-Kalshi page fails.
  • Network accessline 431
    - **Plain HTTP to kalshi.com pages:** `curl https://kalshi.com/robots.txt` got HTTP 429 with a "Vercel Security Checkpoint" page. Not worked around; the browser loaded the same URL normally. The API host does not do this.

agent-workspace/domain-skills/letterboxd/scraping.md

  • Network accessline 3
    `https://letterboxd.com` — film logging, rating, and review site. Film pages and user profile root pages are publicly accessible via `http_get` (~200–350ms). Most sub-pages (reviews, ratings, user film lists, browse/genre pages) return 403 
  • Network accessline 40
    slug examples: 'the-godfather', 'parasite-2019', 'inception', '2001-a-space-odyssey'     """     html = http_get(f"https://letterboxd.com/film/{slug}/")
  • Network accessline 41
    """     html = http_get(f"https://letterboxd.com/film/{slug}/")     result = {}
  • Network accessline 42
    html = http_get(f"https://letterboxd.com/film/{slug}/")
  • Network accessline 139
    #   'og_title': 'The Godfather (1972)', #   'synopsis': 'Spanning the years 1945 to 1955...', #   'poster_url': 'https://a.ltrbxd.com/resized/film-poster/.../51818-the-godfather-0-230-0-345-crop.jpg...',
  • Network accessline 140
    #   'synopsis': 'Spanning the years 1945 to 1955...', #   'poster_url': 'https://a.ltrbxd.com/resized/film-poster/.../51818-the-godfather-0-230-0-345-crop.jpg...', #   'og_image': 'https://a.ltrbxd.com/resized/sm/upload/.../the-godfather-12
  • Network accessline 141
    #   'poster_url': 'https://a.ltrbxd.com/resized/film-poster/.../51818-the-godfather-0-230-0-345-crop.jpg...',
  • Network accessline 142
    #   'og_image': 'https://a.ltrbxd.com/resized/sm/upload/.../the-godfather-1200-1200-675-675-crop-000000.jpg...',
  • Network accessline 168
    def extract_user_profile(username):     html = http_get(f"https://letterboxd.com/{username}/")
  • Network accessline 169
    html = http_get(f"https://letterboxd.com/{username}/")
  • Network accessline 224
    def extract_activity_stream():     html = http_get("https://letterboxd.com/films/")
  • Network accessline 225
    html = http_get("https://letterboxd.com/films/")
  • Network accessline 259
    # Popular films goto_url("https://letterboxd.com/films/popular/")
  • Network accessline 260
    goto_url("https://letterboxd.com/films/popular/")
  • Network accessline 278
    # User watched films list (paginated, 72/page) goto_url("https://letterboxd.com/dave/films/")
  • Network accessline 279
    goto_url("https://letterboxd.com/dave/films/")
  • Network accessline 296
    # User diary entries goto_url("https://letterboxd.com/dave/diary/")
  • Network accessline 297
    goto_url("https://letterboxd.com/dave/diary/")

agent-workspace/domain-skills/linkedin/invitation-manager.md

  • Network accessline 3
    Accept or ignore pending connection invitations in bulk from `https://www.linkedin.com/mynetwork/invitation-manager/received/<FILTER>/`.
  • Network accessline 4
    `https://www.linkedin.com/mynetwork/invitation-manager/received/<FILTER>/`.
  • Network accessline 99
    while True:     cdp("Page.navigate", url="https://www.linkedin.com/mynetwork/invitation-manager/received/PEOPLE_WITH_MUTUAL_CONNECTION/")
  • Network accessline 100
    cdp("Page.navigate", url="https://www.linkedin.com/mynetwork/invitation-manager/received/PEOPLE_WITH_MUTUAL_CONNECTION/")

agent-workspace/domain-skills/loom/folder-enumeration.md

  • Access to secretsline 17
    [Credential-related source omitted]
  • Network accessline 125
    - `https://www.loom.com/v1/folders/<id>?limit=10000` — works for `/share/folder/...` IDs (this is what `LoomFolderIE` uses), returns `Forbidden` for library folder IDs even with the user's cookies.
  • Network accessline 126
    - `https://www.loom.com/graphql` — fires hundreds of times during page load. A folder-listing operation almost certainly lives in there, but the `query` strings come from the bundled React app and would have to be reverse-engineered from th
  • Network accessline 137
    [Credential-related source omitted]
  • Access to secretsline 137
    [Credential-related source omitted]
  • Network accessline 139
    "https://www.loom.com/share/<any-known-id>" >/dev/null
  • Network accessline 143
    yt-dlp --cookies /tmp/loom_cookies.txt      -f http-transcoded      -o "%(title)s.%(ext)s"      --no-progress --no-warnings --no-mtime --no-overwrites      "https://www.loom.com/share/$1"
  • Network accessline 145
    -o "%(title)s.%(ext)s" \     --no-progress --no-warnings --no-mtime --no-overwrites \     "https://www.loom.com/share/$1"
  • Network accessline 147
    "https://www.loom.com/share/$1"

agent-workspace/domain-skills/loom/read-recording.md

  • Network accessline 3
    Use the shared recording URL (`https://www.loom.com/share/<video-id>`) in the
  • Network accessline 27
    const videoId = location.pathname.split('/').filter(Boolean).at(-1); const response = await fetch('/graphql', {
  • Network accessline 28
    const response = await fetch('/graphql', {

agent-workspace/domain-skills/lulu/account-currency.md

  • Network accessline 5
    Lulu's official [account basics](https://help.lulu.com/en/support/solutions/articles/64000255301-lulu-account-the-basics) says that a preferred account currency cannot be changed through account settings; the account owner must contact supp
  • Network accessline 11
    - Start at `https://help.lulu.com/en/support/tickets/new`.
  • Network accessline 19
    `https://developers.lulu.com/api-keys` may render client credentials in accessible text fields. Avoid full accessibility/DOM dumps of that page. Retrieve only the required credential into private storage when authorized; do not include cred

agent-workspace/domain-skills/ly-com/hotels.md

  • Network accessline 29
    List page:   https://www.ly.com/hotel/hotellist?city=<cityId>&inDate=YYYY-MM-DD&outDate=YYYY-MM-DD
  • Network accessline 30
    https://www.ly.com/hotel/hotellist?city=<cityId>&inDate=YYYY-MM-DD&outDate=YYYY-MM-DD
  • Network accessline 32
    Hotel detail page:   https://www.ly.com/hotel/hoteldetail?hotelId=<hotelId>&inDate=YYYY-MM-DD&outDate=YYYY-MM-DD
  • Network accessline 33
    https://www.ly.com/hotel/hoteldetail?hotelId=<hotelId>&inDate=YYYY-MM-DD&outDate=YYYY-MM-DD
  • Network accessline 35
    Login page (with return URL):   https://passport.ly.com/?pageurl=<urlencoded-target>
  • Network accessline 36
    https://passport.ly.com/?pageurl=<urlencoded-target>
  • Network accessline 51
    - `https://m.ly.com/scenery/hotel/<hotelId>` — 404
  • Network accessline 52
    - `https://hotelh5.ly.com/...` — not yet mapped
  • Network accessline 60
    On `https://www.ly.com/hotel/`, the green "搜索" search button is a `<div>`,
  • Access to secretsline 115
    [Credential-related source omitted]
  • Network accessline 188
    new_tab(f"https://passport.ly.com/?pageurl={urllib.parse.quote(target_url)}")
  • Network accessline 253
    HOTEL_ID = "92963586"   # 和颐至尊酒店(上海新国际博览中心世博园店) url = f"https://www.ly.com/hotel/hoteldetail?hotelId={HOTEL_ID}&inDate=2026-04-29&outDate=2026-04-30"
  • Network accessline 254
    url = f"https://www.ly.com/hotel/hoteldetail?hotelId={HOTEL_ID}&inDate=2026-04-29&outDate=2026-04-30"

agent-workspace/domain-skills/macrotrends/scraping.md

  • Network accessline 3
    `https://www.macrotrends.net` — long-term historical financial and economic charts. Three access patterns depending on page type; all work with plain `http_get`, no browser required.
  • Network accessline 36
    Omit (None) to get ALL available history (AAPL goes back to 1980).     """     url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/stock_price_history.php?t={ticker}"
  • Network accessline 37
    """     url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/stock_price_history.php?t={ticker}"     if years_back:
  • Network accessline 38
    url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/stock_price_history.php?t={ticker}"
  • Network accessline 104
    def get_market_cap(ticker: str, years_back: int = 15) -> list[dict]:     url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/market_cap.php?t={ticker}&yb={years_back}"
  • Network accessline 105
    url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/market_cap.php?t={ticker}&yb={years_back}"
  • Network accessline 132
    """     url = (         f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"
  • Network accessline 133
    url = (         f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"         f"fundamental_iframe.php?t={ticker}&type={metric_type}&statement={statement}"
  • Network accessline 134
    f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"
  • Network accessline 169
    def get_profit_margins(ticker: str, years_back: int = 15) -> list[dict]:     url = (         f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"
  • Network accessline 170
    url = (         f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"         f"fundamental_metric.php?t={ticker}&chart=profit-margin&sub=&yb={years_back}"
  • Network accessline 171
    f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"
  • Network accessline 193
    def get_dividend_yield(ticker: str, years_back: int = 15) -> list[dict]:     url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/dividend_yield.php?t={ticker}&yb={years_back}"
  • Network accessline 194
    url = f"https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/dividend_yield.php?t={ticker}&yb={years_back}"
  • Network accessline 225
    Base URL prefix: `https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/`
  • Network accessline 242
    url_slug: last segment of the page URL, e.g. 'sp500-pe-ratio-price-to-earnings-chart'     """     url = f"https://www.macrotrends.net/assets/php/chart_iframe_comp.php?id={page_id}&url={url_slug}"
  • Network accessline 243
    """     url = f"https://www.macrotrends.net/assets/php/chart_iframe_comp.php?id={page_id}&url={url_slug}"     html = http_get(url)
  • Network accessline 244
    url = f"https://www.macrotrends.net/assets/php/chart_iframe_comp.php?id={page_id}&url={url_slug}"
  • Network accessline 292
    page_url = "https://www.macrotrends.net/2577/sp500-pe-ratio-price-to-earnings-chart"
  • Network accessline 324
    Returns {'data': [[ts_ms, value], ...], 'metadata': {...}}     """     url = f"https://www.macrotrends.net/economic-data/{page_id}/{freq}"
  • Network accessline 325
    """     url = f"https://www.macrotrends.net/economic-data/{page_id}/{freq}"     headers = {
  • Network accessline 326
    url = f"https://www.macrotrends.net/economic-data/{page_id}/{freq}"
  • Network accessline 331
    "Referer": referer_url,     }     with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=20) as r:
  • Network accessline 332
    }     with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=20) as r:         raw = r.read()
  • Network accessline 333
    with urllib.request.urlopen(urllib.request.Request(url, headers=headers), timeout=20) as r:
  • Network accessline 342
    # Fed Funds Rate (daily, 25319 records) ffr = get_economic_data(2015, "https://www.macrotrends.net/2015/fed-funds-rate-historical-chart", freq='D')
  • Network accessline 343
    ffr = get_economic_data(2015, "https://www.macrotrends.net/2015/fed-funds-rate-historical-chart", freq='D')
  • Network accessline 355
    # 10-Year Treasury yield (daily, 16074 records) t10 = get_economic_data(2016, "https://www.macrotrends.net/2016/10-year-treasury-bond-rate-yield-chart", freq='D')
  • Network accessline 356
    t10 = get_economic_data(2016, "https://www.macrotrends.net/2016/10-year-treasury-bond-rate-yield-chart", freq='D')
  • Network accessline 359
    # Gold prices (monthly, 1336 records, 1915-present) — template=5 gold = get_economic_data(1333, "https://www.macrotrends.net/1333/historical-gold-prices-100-year-chart", freq='M')
  • Network accessline 360
    gold = get_economic_data(1333, "https://www.macrotrends.net/1333/historical-gold-prices-100-year-chart", freq='M')
  • Network accessline 363
    # US Unemployment Rate (monthly, 938 records) unemp = get_economic_data(1316, "https://www.macrotrends.net/1316/us-national-unemployment-rate", freq='M')
  • Network accessline 364
    unemp = get_economic_data(1316, "https://www.macrotrends.net/1316/us-national-unemployment-rate", freq='M')
  • Network accessline 367
    # Debt-to-GDP ratio (monthly, 712 records) debt_gdp = get_economic_data(1381, "https://www.macrotrends.net/1381/debt-to-gdp-ratio-historical-chart", freq='M')
  • Network accessline 368
    debt_gdp = get_economic_data(1381, "https://www.macrotrends.net/1381/debt-to-gdp-ratio-historical-chart", freq='M')
  • Network accessline 442
    # Works for dataDaily, chartData, or originalData: html = http_get("https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/stock_price_history.php?t=AAPL&yb=15")
  • Network accessline 443
    html = http_get("https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/stock_price_history.php?t=AAPL&yb=15")
  • Network accessline 446
    html2 = http_get("https://www.macrotrends.net/assets/php/chart_iframe_comp.php?id=2577&url=sp500-pe-ratio-price-to-earnings-chart")
  • Network accessline 457
    STOCK_BASE = "https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/"
  • Network accessline 482
    # From numeric ID + URL slug (read from page source or page URL) f"https://www.macrotrends.net/assets/php/chart_iframe_comp.php?id={id}&url={slug}"
  • Network accessline 483
    f"https://www.macrotrends.net/assets/php/chart_iframe_comp.php?id={id}&url={slug}"
  • Network accessline 485
    # Economic indicator JSON API (requires Referer header) f"https://www.macrotrends.net/economic-data/{page_id}/{freq}"
  • Network accessline 486
    f"https://www.macrotrends.net/economic-data/{page_id}/{freq}"
  • Network accessline 537
    **No public API for ticker lookup:** To find the company slug for a URL, check the search endpoint: `https://www.macrotrends.net/production/stocks/desktop/PRODUCTION/ticker_search_list.php?v=YYYYMMDD` — but the stock price iframe only needs

agent-workspace/domain-skills/manus/tasks.md

  • Network accessline 7
    - App home / new-task composer: `https://manus.im/app`
  • Network accessline 8
    - Running or completed task: `https://manus.im/app/<taskId>` — `<taskId>` is a 22-char base62-ish opaque id (character set includes letters, digits, and `-`/`_`). The same id is the session id on the API side.
  • Network accessline 9
    - Public share page: `https://manus.im/share/<taskId>` — only reachable after a `ShareSession` call (clicking *Share*).
  • Network accessline 16
    [Credential-related source omitted]
  • Access to secretsline 16
    [Credential-related source omitted]
  • Network accessline 34
    status = js(r""" (async()=>{   const r = await fetch('https://api.manus.im/session.v1.SessionService/GetSession', {
  • Network accessline 35
    (async()=>{   const r = await fetch('https://api.manus.im/session.v1.SessionService/GetSession', {     method: 'POST',
  • Network accessline 36
    const r = await fetch('https://api.manus.im/session.v1.SessionService/GetSession', {
  • Network accessline 53
    browser-harness <<'PY' new_tab("https://manus.im/app")
  • Network accessline 54
    new_tab("https://manus.im/app")
  • Network accessline 141
    click(rect['x'], rect['y']) wait(0.5) # The share URL is https://manus.im/share/<same-taskId-as-/app/>
  • Network accessline 142
    wait(0.5) # The share URL is https://manus.im/share/<same-taskId-as-/app/> print(page_info()['url'].replace('/app/', '/share/'))
  • Network accessline 143
    # The share URL is https://manus.im/share/<same-taskId-as-/app/>
  • Network accessline 150
    - Clicking **Share** in the top bar opens a floating popover (`div[role="dialog"]` inside a `[data-floating-ui-portal]`). It auto-runs `session.v1.SessionService/ShareSession` on first open and sets the task to **Public access** (the checkm
  • Network accessline 151
    - Clicking **Share** a second time **toggles the popover closed** — don't double-click thinking it's a no-op. - **"Copy link" writes via `document.execCommand('copy')`, not `navigator.clipboard.writeText`.** If you need to capture the URL, 
  • Network accessline 152
    - **"Copy link" writes via `document.execCommand('copy')`, not `navigator.clipboard.writeText`.** If you need to capture the URL, hook both or just compute it: it's `https://manus.im/share/<taskId>` where the id comes straight from the URL 
  • Network accessline 163
    - **"Task completed" is the only DOM marker for terminal state.** Failed / cancelled tasks may surface different text — if you hit one, extend this skill. - **Cloud PC / Computer Use tasks** (when the monitor icon in the composer is toggled
  • Network accessline 165
    - **Auth wall.** If `https://manus.im/app` redirects to `/login` or a Google OAuth page, stop and ask the user to sign in. Never type credentials from a screenshot.

agent-workspace/domain-skills/medium/article-hydration.md

  • Network accessline 13
    - Canonical: `https://medium.com/@<author>/<slug>-<id>`
  • Network accessline 14
    - Publication: `https://<pub>.medium.com/<slug>-<id>` or `https://medium.com/<pub>/<slug>-<id>`
  • Network accessline 36
    browser-harness <<'PY' new_tab("https://medium.com/@user/slug-abc123")
  • Network accessline 37
    new_tab("https://medium.com/@user/slug-abc123")

agent-workspace/domain-skills/medium/scraping.md

  • Network accessline 3
    `https://medium.com` — blogging platform. Three access paths tested and validated: the undocumented `?format=json` endpoint (fastest for article + publication data), the undocumented GraphQL API (best for targeted metric lookups), and RSS f
  • Network accessline 34
    """     sep = '&' if '?' in url else '?'     req = urllib.request.Request(
  • Network accessline 35
    sep = '&' if '?' in url else '?'     req = urllib.request.Request(         url + sep + 'format=json',
  • Network accessline 36
    req = urllib.request.Request(
  • Network accessline 42
    }     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 43
    )     with urllib.request.urlopen(req, timeout=20) as r:         raw = r.read()
  • Network accessline 44
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 60
    data = medium_json("https://medium.com/@karpathy/software-2-0-a64152b37c35")
  • Network accessline 68
    creator_id  = val['creatorId']                          # "ac9d9a35533e" slug        = val['uniqueSlug']                         # "software-2-0-a64152b37c35" url         = val['canonicalUrl']                       # "https://medium.com/@ka
  • Network accessline 69
    slug        = val['uniqueSlug']                         # "software-2-0-a64152b37c35" url         = val['canonicalUrl']                       # "https://medium.com/@karpathy/..." first_pub   = val['firstPublishedAt']                   # uni
  • Network accessline 70
    url         = val['canonicalUrl']                       # "https://medium.com/@karpathy/..."
  • Network accessline 132
    `POST https://medium.com/_/graphql` with a JSON body. No auth, no CSRF token required.
  • Network accessline 138
    def gql(query):     body = json.dumps({"query": query}).encode()     req  = urllib.request.Request(
  • Network accessline 139
    body = json.dumps({"query": query}).encode()     req  = urllib.request.Request(         "https://medium.com/_/graphql",
  • Network accessline 140
    req  = urllib.request.Request(
  • Network accessline 141
    "https://medium.com/_/graphql",
  • Network accessline 149
    method="POST",     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 150
    )     with urllib.request.urlopen(req, timeout=20) as r:         raw = r.read()
  • Network accessline 151
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 279
    # User feed (up to 10 latest posts) rss = http_get("https://medium.com/feed/@karpathy")
  • Network accessline 280
    rss = http_get("https://medium.com/feed/@karpathy")
  • Network accessline 284
    # posts[0]['creator']  -> "Andrej Karpathy" # posts[0]['tags']     -> ['programming', 'software-development', 'artificial-intelligence', 'future', 'machine-learning'] # posts[0]['link']     -> "https://karpathy.medium.com/software-2-0-a6415
  • Network accessline 285
    # posts[0]['tags']     -> ['programming', 'software-development', 'artificial-intelligence', 'future', 'machine-learning'] # posts[0]['link']     -> "https://karpathy.medium.com/software-2-0-a64152b37c35?source=rss-..." # posts[0]['body_htm
  • Network accessline 286
    # posts[0]['link']     -> "https://karpathy.medium.com/software-2-0-a64152b37c35?source=rss-..."
  • Network accessline 289
    # Publication feed (up to 10 latest posts) rss_pub = http_get("https://medium.com/feed/towards-data-science")
  • Network accessline 290
    rss_pub = http_get("https://medium.com/feed/towards-data-science")
  • Network accessline 306
    data = medium_json("https://medium.com/@karpathy?limit=10")
  • Network accessline 328
    # Append as query params to the same profile URL to get next page next_url = (     f"https://medium.com/@{user['username']}"
  • Network accessline 329
    next_url = (     f"https://medium.com/@{user['username']}"     f"?limit={next_params['limit']}&to={next_params['to']}"
  • Network accessline 330
    f"https://medium.com/@{user['username']}"
  • Network accessline 345
    data = medium_json("https://medium.com/towards-data-science")
  • Network accessline 376
    url = "https://medium.com/@karpathy/software-2-0-a64152b37c35"
  • Network accessline 390
    - **`?format=json` works; profile stream API does not** — `https://medium.com/_/api/users/{id}/profile/stream` returns HTTP 403 for unauthenticated requests. Use `?format=json` on the profile URL instead.

agent-workspace/domain-skills/mercari/scraping.md

  • Network accessline 11
    - **Item pages are server-rendered.** `/us/item/<id>/` embeds an Apollo cache in `__NEXT_DATA__.props.pageProps.serverState`: `ItemDetail:<id>` (price, condition, status, ...) and `PublicUser:<seller id>` (username, rating, sales). Block 2 
  • Network accessline 12
    - **Prices are cents** in both sources (`15000` = $150.00), and so are the URL price filters (`minPrice=10000`). - **Never follow tile links.** Result tiles link to `/us/item/<id>/?ref=search_results`, and the seller link carries `?tracking
  • Network accessline 13
    - **Never follow tile links.** Result tiles link to `/us/item/<id>/?ref=search_results`, and the seller link carries `?tracking_ref_id=`; robots.txt disallows both. Both blocks build `https://www.mercari.com/us/item/<id>/` instead.
  • Network accessline 23
    BASE = "https://www.mercari.com"
  • Possible obfuscationline 88
    data = json.loads(base64.b64decode(b["body"]) if b.get("base64Encoded") else b["body"])
  • Network accessline 166
    'nintendo switch oled' batch 2: offset 47, 100 rows, 99 new, count=8889 199 rows of 8889 status: truncated_max_batches {"id": "m34776430562", "title": "Nintendo Switch OLED Console - White - As is. For Parts or Repair", "price": 150.0, "ori
  • Network accessline 167
    199 rows of 8889 status: truncated_max_batches {"id": "m34776430562", "title": "Nintendo Switch OLED Console - White - As is. For Parts or Repair", "price": 150.0, "original_price": 170.0, "condition": "Poor", "status": "on_sale", "brand": 
  • Network accessline 168
    {"id": "m34776430562", "title": "Nintendo Switch OLED Console - White - As is. For Parts or Repair", "price": 150.0, "original_price": 170.0, "condition": "Poor", "status": "on_sale", "brand": "Nintendo", "category": "Consoles", "seller_id"
  • Network accessline 169
    {"id": "m18850154865", "title": "Nintendo Switch OLED Modded – 1TB Storage + Accessories", "price": 480.0, "original_price": null, "condition": "Good", "status": "on_sale", "brand": "Nintendo", "category": "Consoles", "seller_id": 506215568
  • Network accessline 187
    BASE = "https://www.mercari.com"
  • Network accessline 312
    ids: ['m34776430562', 'm18850154865', 'm15731011026'] {"id": "m34776430562", "title": "Nintendo Switch OLED Console - White - As is. For Parts or Repair", "price": 150.0, "original_price": 170.0, "condition": "Poor", "status": "on_sale", "b
  • Network accessline 313
    {"id": "m34776430562", "title": "Nintendo Switch OLED Console - White - As is. For Parts or Repair", "price": 150.0, "original_price": 170.0, "condition": "Poor", "status": "on_sale", "brand": "Nintendo", "category": "Consoles", "buyer_ship
  • Network accessline 314
    {"id": "m18850154865", "title": "Nintendo Switch OLED Modded – 1TB Storage + Accessories", "price": 480.0, "original_price": null, "condition": "Good", "status": "on_sale", "brand": "Nintendo", "category": "Consoles", "buyer_shipping": 0.0,
  • Network accessline 315
    {"id": "m15731011026", "title": "Nintendo Switch OLED Model with Splatoon 2 Game", "price": 185.25, "original_price": 195.0, "condition": "Good", "status": "trading", "brand": "Nintendo", "category": "Consoles", "buyer_shipping": 0.0, "ship
  • Network accessline 347
    | `category` | `categoryTitle` | leaf category, e.g. `Consoles` | | `seller_id` | `seller.id` | numeric; the search row has no seller name or rating, use block 2 for those | | `url` | built from `id` | `https://www.mercari.com/us/item/<id>/
  • Network accessline 348
    | `seller_id` | `seller.id` | numeric; the search row has no seller name or rating, use block 2 for those | | `url` | built from `id` | `https://www.mercari.com/us/item/<id>/`, no `?ref=` | | (batch) `count` | `count` | approximate total |
  • Network accessline 349
    | `url` | built from `id` | `https://www.mercari.com/us/item/<id>/`, no `?ref=` |
  • Network accessline 364
    | `seller.sales`, `seller.listed` | `.numSales`, `.numSellItems` | | | `seller.id_verified`, `seller.pro_seller` | `.kycVerificationStatus == "verified"`, `.isProSeller` | | | `seller.url` | built from username | `https://www.mercari.com/u/
  • Network accessline 366
    | `seller.url` | built from username | `https://www.mercari.com/u/<username>/` (no robots rule; not loaded here). The page's own seller link adds a disallowed `?tracking_ref_id=` |

agent-workspace/domain-skills/mermaid/render.md

  • Network accessline 12
    https://mermaid.live/edit#pako:<data>
  • Network accessline 25
    raw = json.dumps(state).encode("utf-8")     data = base64.urlsafe_b64encode(zlib.compress(raw, 9)).decode("ascii").rstrip("=")     return "https://mermaid.live/edit#pako:" + data
  • Network accessline 27
    return "https://mermaid.live/edit#pako:" + data

agent-workspace/domain-skills/metacritic/scraping.md

  • Access to secretsline 14
    [Credential-related source omitted]
  • Network accessline 16
    def get_game_scores(slug):     """slug = URL slug e.g. 'elden-ring', 'the-last-of-us'"""     base = f"https://backend.metacritic.com"
  • Network accessline 17
    """slug = URL slug e.g. 'elden-ring', 'the-last-of-us'"""     base = f"https://backend.metacritic.com"     product = json.loads(http_get(
  • Network accessline 18
    base = f"https://backend.metacritic.com"
  • Access to secretsline 21
    [Credential-related source omitted]
  • Access to secretsline 25
    [Credential-related source omitted]
  • Network accessline 60
    url = "https://www.metacritic.com/game/elden-ring/"   # or /movie/ or /tv/
  • Network accessline 93
    [Credential-related source omitted]
  • Access to secretsline 93
    [Credential-related source omitted]
  • Network accessline 94
    BASE = "https://backend.metacritic.com"
  • Access to secretsline 98
    [Credential-related source omitted]
  • Access to secretsline 99
    [Credential-related source omitted]
  • Access to secretsline 107
    [Credential-related source omitted]
  • Access to secretsline 108
    [Credential-related source omitted]
  • Access to secretsline 116
    [Credential-related source omitted]
  • Access to secretsline 117
    [Credential-related source omitted]
  • Access to secretsline 141
    [Credential-related source omitted]
  • Network accessline 143
    def _fetch(url):     h = {"User-Agent": "Mozilla/5.0", "Accept-Encoding": "gzip"}     with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=15) as r:
  • Network accessline 144
    h = {"User-Agent": "Mozilla/5.0", "Accept-Encoding": "gzip"}     with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=15) as r:         data = r.read()
  • Network accessline 145
    with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=15) as r:
  • Network accessline 150
    def batch_game_scores(slugs, workers=5):     """Fetch critic+user scores for multiple game slugs in parallel."""     BASE = "https://backend.metacritic.com"
  • Network accessline 151
    [Credential-related source omitted]
  • Network accessline 152
    BASE = "https://backend.metacritic.com"
  • Access to secretsline 153
    [Credential-related source omitted]
  • Access to secretsline 182
    [Credential-related source omitted]
  • Network accessline 191
    type_param = f"&mcoTypeId={type_map[media_type]}" if media_type else "&mcoTypeId=1%2C2%2C3%2C13"     url = (         f"https://backend.metacritic.com/finder/metacritic/search/{q}/web"
  • Network accessline 192
    url = (         f"https://backend.metacritic.com/finder/metacritic/search/{q}/web"         f"?offset=0&limit={limit}&sortBy=META_SCORE&sortDirection=DESC"
  • Network accessline 193
    f"https://backend.metacritic.com/finder/metacritic/search/{q}/web"
  • Access to secretsline 196
    [Credential-related source omitted]
  • Access to secretsline 223
    [Credential-related source omitted]
  • Network accessline 232
    [Credential-related source omitted]
  • Network accessline 233
    [Credential-related source omitted]
  • Network accessline 234
    [Credential-related source omitted]
  • Access to secretsline 234
    [Credential-related source omitted]
  • Access to secretsline 268
    [Credential-related source omitted]
  • Network accessline 270
    def game_platforms(slug):     url = (         f"https://backend.metacritic.com/games/metacritic/{slug}/web"
  • Network accessline 271
    [Credential-related source omitted]
  • Network accessline 272
    f"https://backend.metacritic.com/games/metacritic/{slug}/web"
  • Access to secretsline 273
    [Credential-related source omitted]
  • Access to secretsline 302
    [Credential-related source omitted]
  • Network accessline 305
    """sort: 'date' | 'score' | 'publication'"""     url = (         f"https://backend.metacritic.com/reviews/metacritic/critic/{media}/{slug}/web"
  • Network accessline 306
    url = (         f"https://backend.metacritic.com/reviews/metacritic/critic/{media}/{slug}/web"         f"?offset={offset}&limit={limit}&sort={sort}"
  • Network accessline 307
    f"https://backend.metacritic.com/reviews/metacritic/critic/{media}/{slug}/web"
  • Access to secretsline 309
    [Credential-related source omitted]
  • Access to secretsline 336
    [Credential-related source omitted]
  • Network accessline 339
    """order_by: 'score' | 'date' | 'helpfulness'"""     url = (         f"https://backend.metacritic.com/reviews/metacritic/user/{media}/{slug}/web"
  • Network accessline 340
    url = (         f"https://backend.metacritic.com/reviews/metacritic/user/{media}/{slug}/web"         f"?offset={offset}&limit={limit}&orderBy={order_by}&orderType={order_type}"
  • Network accessline 341
    f"https://backend.metacritic.com/reviews/metacritic/user/{media}/{slug}/web"
  • Access to secretsline 343
    [Credential-related source omitted]
  • Network accessline 369
    url = "https://www.metacritic.com/game/the-last-of-us/"
  • Network accessline 437
    slug_from_url("https://www.metacritic.com/game/the-last-of-us/")  # "the-last-of-us"

agent-workspace/domain-skills/microsoft-365/domain-setup.md

  • Network accessline 5
    - Admin portal: `https://admin.cloud.microsoft/`.
  • Network accessline 6
    - Domains: `https://admin.cloud.microsoft/#/Domains`.
  • Network accessline 7
    - Users: `https://admin.cloud.microsoft/#/users`.
  • Network accessline 8
    - DKIM: `https://security.microsoft.com/authentication?viewid=DKIM`.

agent-workspace/domain-skills/musicbrainz/scraping.md

  • Network accessline 3
    `https://musicbrainz.org` — open music encyclopedia with a fully free JSON API.
  • Network accessline 21
    data = json.loads(http_get("https://musicbrainz.org/ws/2/artist/?query=queen&fmt=json&limit=5", headers=UA))
  • Network accessline 57
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/artist/?query=queen&fmt=json&limit=5",
  • Network accessline 58
    "https://musicbrainz.org/ws/2/artist/?query=queen&fmt=json&limit=5",
  • Network accessline 76
    # inc= parameters stack with + between them resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/artist/0383dadf-2a4e-4d10-a46a-e9e041da8eb3"
  • Network accessline 77
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/artist/0383dadf-2a4e-4d10-a46a-e9e041da8eb3"     "?inc=releases+tags+ratings+release-groups&fmt=json",
  • Network accessline 78
    "https://musicbrainz.org/ws/2/artist/0383dadf-2a4e-4d10-a46a-e9e041da8eb3"
  • Network accessline 109
    # Browse API: uses 'artist' param (not 'query') — response key is 'release-count' not 'count' resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/"
  • Network accessline 110
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/"     "?artist=0383dadf-2a4e-4d10-a46a-e9e041da8eb3&fmt=json&limit=25&offset=0",
  • Network accessline 111
    "https://musicbrainz.org/ws/2/release/"
  • Network accessline 128
    # Search by title resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/?query=dark+side+of+the+moon&fmt=json&limit=5",
  • Network accessline 129
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/?query=dark+side+of+the+moon&fmt=json&limit=5",     headers=UA
  • Network accessline 130
    "https://musicbrainz.org/ws/2/release/?query=dark+side+of+the+moon&fmt=json&limit=5",
  • Network accessline 135
    # Full release with track list, artists, and labels release = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/b84ee12a-09ef-421b-82de-0441a926375b"
  • Network accessline 136
    release = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/b84ee12a-09ef-421b-82de-0441a926375b"     "?inc=artists+recordings+labels+release-groups&fmt=json",
  • Network accessline 137
    "https://musicbrainz.org/ws/2/release/b84ee12a-09ef-421b-82de-0441a926375b"
  • Network accessline 176
    # Use Lucene field syntax to filter by artist resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/recording/"
  • Network accessline 177
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/recording/"     "?query=bohemian+rhapsody+AND+artist:queen&fmt=json&limit=5",
  • Network accessline 178
    "https://musicbrainz.org/ws/2/recording/"
  • Network accessline 195
    # Use release-group endpoint to avoid getting every regional edition resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release-group/"
  • Network accessline 196
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release-group/"     "?query=release-group:\"A+Night+at+the+Opera\"+AND+artist:queen&fmt=json&limit=5",
  • Network accessline 197
    "https://musicbrainz.org/ws/2/release-group/"
  • Network accessline 206
    # Browse release-groups for an artist resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release-group/"
  • Network accessline 207
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release-group/"     "?artist=0383dadf-2a4e-4d10-a46a-e9e041da8eb3&fmt=json&limit=25",
  • Network accessline 208
    "https://musicbrainz.org/ws/2/release-group/"
  • Network accessline 220
    # Label search resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/label/?query=EMI&fmt=json&limit=3",
  • Network accessline 221
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/label/?query=EMI&fmt=json&limit=3",     headers=UA
  • Network accessline 222
    "https://musicbrainz.org/ws/2/label/?query=EMI&fmt=json&limit=3",
  • Network accessline 229
    # Work (song composition — author-level, not performance-level) resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/work/?query=bohemian+rhapsody&fmt=json&limit=3",
  • Network accessline 230
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/work/?query=bohemian+rhapsody&fmt=json&limit=3",     headers=UA
  • Network accessline 231
    "https://musicbrainz.org/ws/2/work/?query=bohemian+rhapsody&fmt=json&limit=3",
  • Network accessline 249
    try:         resp = json.loads(http_get(             f"https://coverartarchive.org/release/{release_mbid}",
  • Network accessline 250
    resp = json.loads(http_get(             f"https://coverartarchive.org/release/{release_mbid}",             headers=UA
  • Network accessline 251
    f"https://coverartarchive.org/release/{release_mbid}",
  • Network accessline 270
    url = get_cover_art("b84ee12a-09ef-421b-82de-0441a926375b") # http://coverartarchive.org/release/b84ee12a.../1611507818-500.jpg
  • Network accessline 271
    # http://coverartarchive.org/release/b84ee12a.../1611507818-500.jpg
  • Network accessline 273
    # Full images response structure resp = json.loads(http_get(     "https://coverartarchive.org/release/b84ee12a-09ef-421b-82de-0441a926375b",
  • Network accessline 274
    resp = json.loads(http_get(     "https://coverartarchive.org/release/b84ee12a-09ef-421b-82de-0441a926375b",     headers=UA
  • Network accessline 275
    "https://coverartarchive.org/release/b84ee12a-09ef-421b-82de-0441a926375b",
  • Network accessline 291
    # Field search: artist:, type:, country:, tag:, release:, date: resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/artist/"
  • Network accessline 292
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/artist/"     "?query=artist:queen+AND+type:group+AND+country:GB&fmt=json&limit=5",
  • Network accessline 293
    "https://musicbrainz.org/ws/2/artist/"
  • Network accessline 299
    # Phrase search with quotes resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/"
  • Network accessline 300
    resp = json.loads(http_get(     "https://musicbrainz.org/ws/2/release/"     '?query=release:"A+Night+at+the+Opera"+AND+artist:queen&fmt=json&limit=5',
  • Network accessline 301
    "https://musicbrainz.org/ws/2/release/"
  • Network accessline 320
    def fetch_artist(mbid):     resp = json.loads(http_get(         f"https://musicbrainz.org/ws/2/artist/{mbid}?inc=tags&fmt=json",
  • Network accessline 321
    resp = json.loads(http_get(         f"https://musicbrainz.org/ws/2/artist/{mbid}?inc=tags&fmt=json",         headers=UA
  • Network accessline 322
    f"https://musicbrainz.org/ws/2/artist/{mbid}?inc=tags&fmt=json",
  • Network accessline 353
    while total is None or offset < total:         resp = json.loads(http_get(             f"https://musicbrainz.org/ws/2/release/"
  • Network accessline 354
    resp = json.loads(http_get(             f"https://musicbrainz.org/ws/2/release/"             f"?artist={artist_mbid}&fmt=json&limit={page_size}&offset={offset}",
  • Network accessline 355
    f"https://musicbrainz.org/ws/2/release/"
  • Network accessline 433
    | Resource | URL | |---|---| | Artist search | `https://musicbrainz.org/ws/2/artist/?query={q}&fmt=json&limit=5` |
  • Network accessline 434
    |---|---| | Artist search | `https://musicbrainz.org/ws/2/artist/?query={q}&fmt=json&limit=5` | | Artist by MBID | `https://musicbrainz.org/ws/2/artist/{mbid}?inc=tags+ratings&fmt=json` |
  • Network accessline 435
    | Artist search | `https://musicbrainz.org/ws/2/artist/?query={q}&fmt=json&limit=5` |
  • Network accessline 436
    | Artist by MBID | `https://musicbrainz.org/ws/2/artist/{mbid}?inc=tags+ratings&fmt=json` |
  • Network accessline 437
    | Browse releases by artist | `https://musicbrainz.org/ws/2/release/?artist={mbid}&fmt=json&limit=25&offset=0` |
  • Network accessline 438
    | Release search | `https://musicbrainz.org/ws/2/release/?query={q}&fmt=json&limit=5` |
  • Network accessline 439
    | Release by MBID | `https://musicbrainz.org/ws/2/release/{mbid}?inc=artists+recordings+labels&fmt=json` |
  • Network accessline 440
    | Release-group browse | `https://musicbrainz.org/ws/2/release-group/?artist={mbid}&fmt=json&limit=25` |
  • Network accessline 441
    | Recording search | `https://musicbrainz.org/ws/2/recording/?query={q}&fmt=json&limit=5` |
  • Network accessline 442
    | Label search | `https://musicbrainz.org/ws/2/label/?query={q}&fmt=json&limit=5` |
  • Network accessline 443
    | Work search | `https://musicbrainz.org/ws/2/work/?query={q}&fmt=json&limit=5` |
  • Network accessline 444
    | Cover art | `https://coverartarchive.org/release/{release-mbid}` |
  • Network accessline 446
    MusicBrainz entity browser URL (human-readable): `https://musicbrainz.org/artist/{mbid}` (replace `artist` with `release`, `recording`, etc.)

agent-workspace/domain-skills/namecheap/advanced-dns.md

  • Network accessline 5
    - Domain DNS: `https://ap.www.namecheap.com/domains/domaincontrolpanel/<domain>/advancedns`.

agent-workspace/domain-skills/nasa/scraping.md

  • Network accessline 3
    `https://api.nasa.gov` — open NASA data APIs. **Never use the browser.** All endpoints return JSON via `http_get`. DEMO_KEY works for low-volume use; register for a free personal key at https://api.nasa.gov/ to raise limits.
  • Network accessline 13
    [Credential-related source omitted]
  • Network accessline 14
    [Credential-related source omitted]
  • Access to secretsline 14
    [Credential-related source omitted]
  • Network accessline 43
    [Credential-related source omitted]
  • Access to secretsline 43
    [Credential-related source omitted]
  • Network accessline 49
    print(apod.get('copyright'))  # None if public domain # Confirmed output (2026-04-18): # url:   https://apod.nasa.gov/apod/image/2604/PanstarrsPlanetsPerrotLab1024.jpg
  • Network accessline 50
    # Confirmed output (2026-04-18): # url:   https://apod.nasa.gov/apod/image/2604/PanstarrsPlanetsPerrotLab1024.jpg # hdurl: https://apod.nasa.gov/apod/image/2604/PanstarrsPlanetsPerrot.jpg
  • Network accessline 51
    # url:   https://apod.nasa.gov/apod/image/2604/PanstarrsPlanetsPerrotLab1024.jpg
  • Network accessline 52
    # hdurl: https://apod.nasa.gov/apod/image/2604/PanstarrsPlanetsPerrot.jpg
  • Network accessline 62
    apods = json.loads(http_get(     "https://api.nasa.gov/planetary/apod"
  • Network accessline 63
    "https://api.nasa.gov/planetary/apod"
  • Access to secretsline 64
    [Credential-related source omitted]
  • Network accessline 87
    [Credential-related source omitted]
  • Network accessline 88
    [Credential-related source omitted]
  • Access to secretsline 88
    [Credential-related source omitted]
  • Network accessline 101
    data = json.loads(http_get(     "https://api.nasa.gov/neo/rest/v1/feed"
  • Network accessline 102
    "https://api.nasa.gov/neo/rest/v1/feed"
  • Access to secretsline 103
    [Credential-related source omitted]
  • Network accessline 135
    [Credential-related source omitted]
  • Network accessline 136
    [Credential-related source omitted]
  • Network accessline 137
    [Credential-related source omitted]
  • Access to secretsline 137
    [Credential-related source omitted]
  • Network accessline 150
    # sol = Martian solar day since landing data = json.loads(http_get(     "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos"
  • Network accessline 151
    [Credential-related source omitted]
  • Network accessline 152
    "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos"
  • Access to secretsline 153
    [Credential-related source omitted]
  • Network accessline 166
    # Filter by camera data = json.loads(http_get(     "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos"
  • Network accessline 167
    [Credential-related source omitted]
  • Network accessline 168
    "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos"
  • Access to secretsline 169
    [Credential-related source omitted]
  • Network accessline 177
    data = json.loads(http_get(     "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/latest_photos"
  • Network accessline 178
    "https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/latest_photos"
  • Access to secretsline 179
    [Credential-related source omitted]
  • Access to secretsline 188
    [Credential-related source omitted]
  • Network accessline 194
    # Latest available images (natural color) images = json.loads(http_get("https://epic.gsfc.nasa.gov/api/natural"))
  • Network accessline 195
    images = json.loads(http_get("https://epic.gsfc.nasa.gov/api/natural"))
  • Network accessline 205
    date_str = img['date'].split(' ')[0]   # '2026-04-16' year, month, day = date_str.split('-') png_url = f"https://epic.gsfc.nasa.gov/archive/natural/{year}/{month}/{day}/png/{img['image']}.png"
  • Network accessline 206
    year, month, day = date_str.split('-') png_url = f"https://epic.gsfc.nasa.gov/archive/natural/{year}/{month}/{day}/png/{img['image']}.png" jpg_thumb = f"https://epic.gsfc.nasa.gov/archive/natural/{year}/{month}/{day}/thumbs/{img['image']}.j
  • Network accessline 207
    png_url = f"https://epic.gsfc.nasa.gov/archive/natural/{year}/{month}/{day}/png/{img['image']}.png"
  • Network accessline 208
    jpg_thumb = f"https://epic.gsfc.nasa.gov/archive/natural/{year}/{month}/{day}/thumbs/{img['image']}.jpg"
  • Network accessline 210
    # Confirmed: https://epic.gsfc.nasa.gov/archive/natural/2026/04/16/png/epic_1b_20260416162050.png
  • Network accessline 214
    # Images for a specific date images = json.loads(http_get("https://epic.gsfc.nasa.gov/api/natural/date/2024-01-15"))
  • Network accessline 215
    images = json.loads(http_get("https://epic.gsfc.nasa.gov/api/natural/date/2024-01-15"))
  • Network accessline 218
    # Enhanced (color-corrected) images — same API, different path enhanced = json.loads(http_get("https://epic.gsfc.nasa.gov/api/enhanced/date/2024-01-15"))
  • Network accessline 219
    enhanced = json.loads(http_get("https://epic.gsfc.nasa.gov/api/enhanced/date/2024-01-15"))
  • Network accessline 222
    date_str = img['date'].split(' ')[0] year, month, day = date_str.split('-') url = f"https://epic.gsfc.nasa.gov/archive/enhanced/{year}/{month}/{day}/png/{img['image']}.png"
  • Network accessline 223
    year, month, day = date_str.split('-') url = f"https://epic.gsfc.nasa.gov/archive/enhanced/{year}/{month}/{day}/png/{img['image']}.png" # e.g. .../archive/enhanced/2024/01/15/png/epic_RGB_20240115005515.png
  • Network accessline 224
    url = f"https://epic.gsfc.nasa.gov/archive/enhanced/{year}/{month}/{day}/png/{img['image']}.png"
  • Network accessline 227
    # All available dates all_dates = json.loads(http_get("https://epic.gsfc.nasa.gov/api/natural/all"))
  • Network accessline 228
    all_dates = json.loads(http_get("https://epic.gsfc.nasa.gov/api/natural/all"))
  • Network accessline 242
    # Short-period planets with known radii planets = json.loads(http_get(     "https://exoplanetarchive.ipac.caltech.edu/TAP/sync"
  • Network accessline 243
    planets = json.loads(http_get(     "https://exoplanetarchive.ipac.caltech.edu/TAP/sync"     "?query=select+pl_name,hostname,pl_orbper+from+ps+where+pl_orbper+%3C+10"
  • Network accessline 244
    "https://exoplanetarchive.ipac.caltech.edu/TAP/sync"
  • Network accessline 254
    # Use 'pscomppars' for one row per planet (composite best-estimate params) planets = json.loads(http_get(     "https://exoplanetarchive.ipac.caltech.edu/TAP/sync"
  • Network accessline 255
    planets = json.loads(http_get(     "https://exoplanetarchive.ipac.caltech.edu/TAP/sync"     "?query=select+pl_name,hostname,disc_year,discoverymethod,pl_orbper,pl_rade,pl_masse,pl_eqt,sy_dist"
  • Network accessline 256
    "https://exoplanetarchive.ipac.caltech.edu/TAP/sync"
  • Network accessline 282
    [Credential-related source omitted]
  • Network accessline 283
    [Credential-related source omitted]
  • Network accessline 284
    [Credential-related source omitted]
  • Access to secretsline 284
    [Credential-related source omitted]
  • Network accessline 286
    [Credential-related source omitted]
  • Network accessline 287
    [Credential-related source omitted]
  • Network accessline 288
    [Credential-related source omitted]
  • Access to secretsline 288
    [Credential-related source omitted]
  • Network accessline 289
    [Credential-related source omitted]
  • Access to secretsline 289
    [Credential-related source omitted]
  • Network accessline 290
    [Credential-related source omitted]
  • Access to secretsline 290
    [Credential-related source omitted]
  • Access to secretsline 291
    [Credential-related source omitted]
  • Network accessline 292
    [Credential-related source omitted]
  • Access to secretsline 292
    [Credential-related source omitted]
  • Network accessline 296
    | Endpoint | URL | |---|---| | Latest natural images | `https://epic.gsfc.nasa.gov/api/natural` |
  • Network accessline 297
    |---|---| | Latest natural images | `https://epic.gsfc.nasa.gov/api/natural` | | Natural by date | `https://epic.gsfc.nasa.gov/api/natural/date/YYYY-MM-DD` |
  • Network accessline 298
    | Latest natural images | `https://epic.gsfc.nasa.gov/api/natural` |
  • Network accessline 299
    | Natural by date | `https://epic.gsfc.nasa.gov/api/natural/date/YYYY-MM-DD` |
  • Network accessline 300
    | Enhanced latest | `https://epic.gsfc.nasa.gov/api/enhanced` |
  • Network accessline 301
    | Enhanced by date | `https://epic.gsfc.nasa.gov/api/enhanced/date/YYYY-MM-DD` |
  • Network accessline 302
    | All available dates | `https://epic.gsfc.nasa.gov/api/natural/all` |
  • Network accessline 303
    | PNG image | `https://epic.gsfc.nasa.gov/archive/natural/YYYY/MM/DD/png/{image}.png` |
  • Network accessline 304
    | Thumbnail (JPEG) | `https://epic.gsfc.nasa.gov/archive/natural/YYYY/MM/DD/thumbs/{image}.jpg` |
  • Network accessline 305
    | Enhanced PNG | `https://epic.gsfc.nasa.gov/archive/enhanced/YYYY/MM/DD/png/{image}.png` |
  • Network accessline 310
    https://exoplanetarchive.ipac.caltech.edu/TAP/sync?query=<ADQL>&format=json&maxrec=<N>
  • Network accessline 315
    - **DEMO_KEY limit is effectively 10/hour per IP, not 30** — The `X-Ratelimit-Limit` header shows `10` in practice. When the daily budget (~50 req) is exhausted, the `retry-after` header is set to ~80,000 seconds (about 22 hours). Register 

agent-workspace/domain-skills/news-aggregation/multi-source.md

  • Network accessline 11
    | Source | Feed URL | Format | Items | Fetch time | |--------|----------|--------|-------|------------| | TechCrunch | `https://techcrunch.com/feed/` | RSS 2.0 | 20 | ~0.08s |
  • Network accessline 12
    |--------|----------|--------|-------|------------| | TechCrunch | `https://techcrunch.com/feed/` | RSS 2.0 | 20 | ~0.08s | | Ars Technica | `https://feeds.arstechnica.com/arstechnica/index` | RSS 2.0 | 20 | ~0.10s |
  • Network accessline 13
    | TechCrunch | `https://techcrunch.com/feed/` | RSS 2.0 | 20 | ~0.08s |
  • Network accessline 14
    | Ars Technica | `https://feeds.arstechnica.com/arstechnica/index` | RSS 2.0 | 20 | ~0.10s |
  • Network accessline 15
    | BBC News | `http://feeds.bbci.co.uk/news/rss.xml` | RSS 2.0 | 37 | ~0.23s |
  • Network accessline 16
    | The Guardian (World) | `https://www.theguardian.com/world/rss` | RSS 2.0 | 45 | ~0.11s |
  • Network accessline 17
    | The Guardian (Tech) | `https://www.theguardian.com/technology/rss` | RSS 2.0 | 32 | ~0.25s |
  • Network accessline 18
    | Wired | `https://www.wired.com/feed/rss` | RSS 2.0 | 50 | ~0.10s |
  • Network accessline 19
    | NPR Top Stories | `https://feeds.npr.org/1001/rss.xml` | RSS 2.0 | 10 | ~0.14s |
  • Network accessline 20
    | Hacker News | `https://news.ycombinator.com/rss` | RSS 2.0 | 30 | ~0.16s |
  • Network accessline 21
    | CNN Top Stories | `http://rss.cnn.com/rss/cnn_topstories.rss` | RSS 2.0 | 69 | ~0.25s |
  • Network accessline 22
    | NYT Homepage | `https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml` | RSS 2.0 | 23 | ~0.12s |
  • Network accessline 23
    | The Verge | `https://www.theverge.com/rss/index.xml` | **Atom** | 10 | ~0.15s |
  • Network accessline 33
    RSS_FEEDS = [     ("TechCrunch",     "https://techcrunch.com/feed/"),
  • Network accessline 34
    ("TechCrunch",     "https://techcrunch.com/feed/"),
  • Network accessline 35
    ("Ars Technica",   "https://feeds.arstechnica.com/arstechnica/index"),
  • Network accessline 36
    ("BBC News",       "http://feeds.bbci.co.uk/news/rss.xml"),
  • Network accessline 37
    ("Guardian World", "https://www.theguardian.com/world/rss"),
  • Network accessline 38
    ("Wired",          "https://www.wired.com/feed/rss"),
  • Network accessline 39
    ("NPR",            "https://feeds.npr.org/1001/rss.xml"),
  • Network accessline 40
    ("Wired",          "https://www.wired.com/feed/rss"),
  • Network accessline 67
    NS = {'atom': 'http://www.w3.org/2005/Atom'}
  • Network accessline 69
    xml_data = http_get("https://www.theverge.com/rss/index.xml")
  • Network accessline 79
    Do NOT use `root.findall('.//{http://www.w3.org/2005/Atom}entry')` with a bare namespace — the explicit `NS` dict approach above is cleaner. Do NOT call `.text` on a `find()` result without checking for `None` first (the naive RSS path hit 
  • Network accessline 96
    headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"} html = http_get("https://www.nytimes.com", headers=headers)  # 1.1MB, works
  • Network accessline 97
    html = http_get("https://www.nytimes.com", headers=headers)  # 1.1MB, works
  • Network accessline 98
    html = http_get("https://news.ycombinator.com")               # 34KB, works without UA
  • Network accessline 103
    import re html = http_get("https://news.ycombinator.com")
  • Network accessline 104
    html = http_get("https://news.ycombinator.com")
  • Network accessline 116
    goto_url("https://www.bbc.com/news")
  • Network accessline 149
    goto_url("https://techcrunch.com")
  • Network accessline 172
    goto_url("https://www.reuters.com")
  • Network accessline 191
    YES → http_get + XML parse (fastest, ~0.1s per feed)          - RSS 2.0: root.findall('.//item')          - Atom:    root.findall('.//atom:entry', {'atom': 'http://www.w3.org/2005/Atom'})
  • Network accessline 192
    - RSS 2.0: root.findall('.//item')          - Atom:    root.findall('.//atom:entry', {'atom': 'http://www.w3.org/2005/Atom'})   NO  → Does http_get return valid HTML (not 403/401/JS shell)?
  • Network accessline 193
    - Atom:    root.findall('.//atom:entry', {'atom': 'http://www.w3.org/2005/Atom'})

agent-workspace/domain-skills/open-library/scraping.md

  • Network accessline 3
    `https://openlibrary.org` — Internet Archive's free book catalog. All endpoints are public JSON APIs — no auth, no browser, no scraping required.
  • Network accessline 13
    # Search by title results = json.loads(http_get("https://openlibrary.org/search.json?q=dune&limit=5"))
  • Network accessline 14
    results = json.loads(http_get("https://openlibrary.org/search.json?q=dune&limit=5"))
  • Network accessline 32
    # Free-text search r = json.loads(http_get("https://openlibrary.org/search.json?q=dune+frank+herbert&limit=5"))
  • Network accessline 33
    r = json.loads(http_get("https://openlibrary.org/search.json?q=dune+frank+herbert&limit=5"))
  • Network accessline 35
    # Author search r = json.loads(http_get(     "https://openlibrary.org/search.json?author=tolkien&limit=5"
  • Network accessline 36
    r = json.loads(http_get(     "https://openlibrary.org/search.json?author=tolkien&limit=5"     "&fields=title,author_name,first_publish_year,isbn"
  • Network accessline 37
    "https://openlibrary.org/search.json?author=tolkien&limit=5"
  • Network accessline 42
    # Title + author combined r = json.loads(http_get(     "https://openlibrary.org/search.json?title=dune&author=frank+herbert&limit=3"
  • Network accessline 43
    r = json.loads(http_get(     "https://openlibrary.org/search.json?title=dune&author=frank+herbert&limit=3"     "&fields=title,author_name,edition_count,first_publish_year"
  • Network accessline 44
    "https://openlibrary.org/search.json?title=dune&author=frank+herbert&limit=3"
  • Network accessline 52
    # ISBN lookup (returns 0–2 results for the same work) r = json.loads(http_get("https://openlibrary.org/search.json?isbn=9780743273565"))
  • Network accessline 53
    r = json.loads(http_get("https://openlibrary.org/search.json?isbn=9780743273565"))
  • Network accessline 121
    def lookup_isbn(isbn):     url = f"https://openlibrary.org/search.json?isbn={isbn}&fields=title,author_name,first_publish_year,key"
  • Network accessline 122
    url = f"https://openlibrary.org/search.json?isbn={isbn}&fields=title,author_name,first_publish_year,key"
  • Network accessline 148
    work_id = 'OL893415W'  # from search doc['key'] = '/works/OL893415W' work = json.loads(http_get(f"https://openlibrary.org/works/{work_id}.json"))
  • Network accessline 149
    work = json.loads(http_get(f"https://openlibrary.org/works/{work_id}.json"))
  • Network accessline 177
    editions_resp = json.loads(http_get(     f"https://openlibrary.org/works/{work_id}/editions.json?limit=10&offset=0"
  • Network accessline 178
    f"https://openlibrary.org/works/{work_id}/editions.json?limit=10&offset=0"
  • Network accessline 211
    edition_id = 'OL7353617M'  # from editions list e['key'] or cover_edition_key in search edition = json.loads(http_get(f"https://openlibrary.org/books/{edition_id}.json"))
  • Network accessline 212
    edition = json.loads(http_get(f"https://openlibrary.org/books/{edition_id}.json"))
  • Network accessline 232
    # jscmd=data: cleaned up dict with cover URLs pre-built r = json.loads(http_get(     "https://openlibrary.org/api/books"
  • Network accessline 233
    r = json.loads(http_get(     "https://openlibrary.org/api/books"     "?bibkeys=ISBN:9780743273565,ISBN:9780451524935"
  • Network accessline 234
    "https://openlibrary.org/api/books"
  • Network accessline 244
    # book['publishers']      == [{'name': 'Independently Published'}] # book['number_of_pages'] == 208 # book['url']             == 'http://openlibrary.org/books/OL46773254M/The_Great_Gatsby'
  • Network accessline 245
    # book['number_of_pages'] == 208 # book['url']             == 'http://openlibrary.org/books/OL46773254M/The_Great_Gatsby' # book['key']             == '/books/OL46773254M'
  • Network accessline 246
    # book['url']             == 'http://openlibrary.org/books/OL46773254M/The_Great_Gatsby'
  • Network accessline 253
    # jscmd=details: raw edition JSON + extra fields r2 = json.loads(http_get(     "https://openlibrary.org/api/books"
  • Network accessline 254
    r2 = json.loads(http_get(     "https://openlibrary.org/api/books"     "?bibkeys=ISBN:9780743273565&format=json&jscmd=details"
  • Network accessline 255
    "https://openlibrary.org/api/books"
  • Network accessline 258
    item = r2['ISBN:9780743273565'] # item['bib_key']      == 'ISBN:9780743273565' # item['info_url']     == 'http://openlibrary.org/books/OL...'
  • Network accessline 259
    # item['bib_key']      == 'ISBN:9780743273565' # item['info_url']     == 'http://openlibrary.org/books/OL...' # item['preview']      == 'noview' | 'restricted' | 'full'
  • Network accessline 260
    # item['info_url']     == 'http://openlibrary.org/books/OL...'
  • Network accessline 261
    # item['preview']      == 'noview' | 'restricted' | 'full' # item['preview_url']  == URL to read on OL or IA # item['thumbnail_url']== 'https://covers.openlibrary.org/b/id/14314120-S.jpg'
  • Network accessline 262
    # item['preview_url']  == URL to read on OL or IA # item['thumbnail_url']== 'https://covers.openlibrary.org/b/id/14314120-S.jpg' # item['details']      → raw edition JSON (same as /books/OL...M.json)
  • Network accessline 263
    # item['thumbnail_url']== 'https://covers.openlibrary.org/b/id/14314120-S.jpg'
  • Network accessline 277
    # Lookup by known author key author = json.loads(http_get("https://openlibrary.org/authors/OL26320A.json"))
  • Network accessline 278
    author = json.loads(http_get("https://openlibrary.org/authors/OL26320A.json"))
  • Network accessline 294
    # Author works (paginated) works = json.loads(http_get("https://openlibrary.org/authors/OL26320A/works.json?limit=5"))
  • Network accessline 295
    works = json.loads(http_get("https://openlibrary.org/authors/OL26320A/works.json?limit=5"))
  • Network accessline 304
    r = json.loads(http_get("https://openlibrary.org/search/authors.json?q=tolkien"))
  • Network accessline 328
    # Book covers — three key types: https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg      # by cover ID (most reliable)
  • Network accessline 329
    https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg      # by cover ID (most reliable)
  • Network accessline 330
    https://covers.openlibrary.org/b/isbn/{isbn}-{size}.jpg        # by ISBN
  • Network accessline 331
    https://covers.openlibrary.org/b/olid/{edition_id}-{size}.jpg  # by edition OLID (unreliable — see gotchas)
  • Network accessline 333
    # Author photos: https://covers.openlibrary.org/a/id/{photo_id}-{size}.jpg
  • Network accessline 334
    https://covers.openlibrary.org/a/id/{photo_id}-{size}.jpg
  • Network accessline 342
    def get_cover_bytes(cover_id: int, size: str = 'M') -> bytes | None:     """Fetch cover image bytes. Returns None if no cover (43-byte GIF placeholder)."""     url = f"https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg"
  • Network accessline 343
    """Fetch cover image bytes. Returns None if no cover (43-byte GIF placeholder)."""     url = f"https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg"     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 344
    url = f"https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg"     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})     with urllib.request.urlopen(req, timeout=15) as resp:
  • Network accessline 345
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 346
    with urllib.request.urlopen(req, timeout=15) as resp:
  • Network accessline 350
    # Or just get the URL for embedding: def cover_url(cover_id: int, size: str = 'M') -> str:     return f"https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg"
  • Network accessline 352
    return f"https://covers.openlibrary.org/b/id/{cover_id}-{size}.jpg"
  • Network accessline 355
    from helpers import http_get import json work = json.loads(http_get("https://openlibrary.org/works/OL893415W.json"))
  • Network accessline 356
    import json work = json.loads(http_get("https://openlibrary.org/works/OL893415W.json")) if work.get('covers'):
  • Network accessline 357
    work = json.loads(http_get("https://openlibrary.org/works/OL893415W.json"))
  • Network accessline 365
    # Medium-size cover by ISBN: url = f"https://covers.openlibrary.org/b/isbn/{isbn}-M.jpg"
  • Network accessline 366
    url = f"https://covers.openlibrary.org/b/isbn/{isbn}-M.jpg"
  • Network accessline 367
    # Redirects to Internet Archive CDN, content-type: image/jpeg # Use ?default=false to get 404 instead of 1×1 GIF placeholder for missing covers url_safe = f"https://covers.openlibrary.org/b/isbn/{isbn}-M.jpg?default=false"
  • Network accessline 369
    url_safe = f"https://covers.openlibrary.org/b/isbn/{isbn}-M.jpg?default=false"
  • Network accessline 380
    # Subject slugs: lowercase, underscores for spaces r = json.loads(http_get("https://openlibrary.org/subjects/science_fiction.json?limit=5"))
  • Network accessline 381
    r = json.loads(http_get("https://openlibrary.org/subjects/science_fiction.json?limit=5"))
  • Network accessline 398
    # Pagination: &offset=N # Place subject: r2 = json.loads(http_get("https://openlibrary.org/subjects/place:london.json?limit=5"))
  • Network accessline 399
    # Place subject: r2 = json.loads(http_get("https://openlibrary.org/subjects/place:london.json?limit=5")) # r2['subject_type'] == 'place', r2['work_count'] == 23927
  • Network accessline 400
    r2 = json.loads(http_get("https://openlibrary.org/subjects/place:london.json?limit=5"))
  • Network accessline 403
    # Person subject: # https://openlibrary.org/subjects/person:napoleon.json?limit=5
  • Network accessline 404
    # https://openlibrary.org/subjects/person:napoleon.json?limit=5
  • Network accessline 406
    # https://openlibrary.org/subjects/time:middle_ages.json?limit=5
  • Network accessline 408
    # Combine with ebooks=true to filter to only freely readable books: r3 = json.loads(http_get("https://openlibrary.org/subjects/science_fiction.json?limit=5&ebooks=true"))
  • Network accessline 409
    r3 = json.loads(http_get("https://openlibrary.org/subjects/science_fiction.json?limit=5&ebooks=true"))
  • Network accessline 421
    for period in ['daily', 'weekly', 'monthly']:     r = json.loads(http_get(f"https://openlibrary.org/trending/{period}.json?limit=10"))
  • Network accessline 422
    r = json.loads(http_get(f"https://openlibrary.org/trending/{period}.json?limit=10"))
  • Network accessline 464
    resp = json.loads(http_get("https://openlibrary.org/works/OL893415W/editions.json?limit=50"))
  • Network accessline 465
    while 'next' in resp.get('links', {}):     resp = json.loads(http_get("https://openlibrary.org" + resp['links']['next']))     # process resp['entries']
  • Network accessline 466
    resp = json.loads(http_get("https://openlibrary.org" + resp['links']['next']))

agent-workspace/domain-skills/openalex/scraping.md

  • Network accessline 3
    `https://api.openalex.org` — open academic knowledge graph covering 260M+ works, 90M+ authors, 110K+ institutions. **Never use the browser for OpenAlex.** The entire API is JSON over HTTPS, completely free, no API key required. Add `mailto=
  • Network accessline 13
    data = json.loads(http_get(     "https://api.openalex.org/works?search=transformer+attention&per-page=5&mailto=you@example.com"
  • Network accessline 14
    "https://api.openalex.org/works?search=transformer+attention&per-page=5&mailto=you@example.com"
  • Network accessline 30
    data = json.loads(http_get(     "https://api.openalex.org/works"
  • Network accessline 31
    "https://api.openalex.org/works"
  • Network accessline 47
    # Confirmed output (2026-04-18): # W3151130473 2021 1887 CrossViT: Cross-Attention Multi-Scale Vision Transformer for I #   doi: https://doi.org/10.1109/iccv48922.2021.00041
  • Network accessline 48
    # W3151130473 2021 1887 CrossViT: Cross-Attention Multi-Scale Vision Transformer for I #   doi: https://doi.org/10.1109/iccv48922.2021.00041 #   open access: False | pdf: None
  • Network accessline 49
    #   doi: https://doi.org/10.1109/iccv48922.2021.00041
  • Network accessline 60
    # By OpenAlex ID (bare or full URL form both work) w = json.loads(http_get("https://api.openalex.org/works/W2626778328?mailto=you@example.com"))
  • Network accessline 61
    w = json.loads(http_get("https://api.openalex.org/works/W2626778328?mailto=you@example.com"))
  • Network accessline 65
    # By DOI (pass the full DOI URL as the entity ID) w = json.loads(http_get(     "https://api.openalex.org/works/https://doi.org/10.1038/nature14539?mailto=you@example.com"
  • Network accessline 66
    w = json.loads(http_get(     "https://api.openalex.org/works/https://doi.org/10.1038/nature14539?mailto=you@example.com" ))
  • Network accessline 67
    "https://api.openalex.org/works/https://doi.org/10.1038/nature14539?mailto=you@example.com"
  • Network accessline 81
    w = json.loads(http_get(     "https://api.openalex.org/works/W2626778328"
  • Network accessline 82
    "https://api.openalex.org/works/W2626778328"
  • Network accessline 100
    # Search by name data = json.loads(http_get(     "https://api.openalex.org/authors?search=geoffrey+hinton&per-page=3&mailto=you@example.com"
  • Network accessline 101
    data = json.loads(http_get(     "https://api.openalex.org/authors?search=geoffrey+hinton&per-page=3&mailto=you@example.com" ))
  • Network accessline 102
    "https://api.openalex.org/authors?search=geoffrey+hinton&per-page=3&mailto=you@example.com"
  • Network accessline 114
    # Fetch by bare ID a = json.loads(http_get("https://api.openalex.org/authors/A5108093963?mailto=you@example.com"))
  • Network accessline 115
    a = json.loads(http_get("https://api.openalex.org/authors/A5108093963?mailto=you@example.com"))
  • Network accessline 119
    # Get all works by this author (sorted by citations) works_data = json.loads(http_get(     "https://api.openalex.org/works"
  • Network accessline 120
    works_data = json.loads(http_get(     "https://api.openalex.org/works"     "?filter=author.id:A5108093963"
  • Network accessline 121
    "https://api.openalex.org/works"
  • Network accessline 141
    data = json.loads(http_get(     "https://api.openalex.org/institutions?search=MIT&per-page=3&mailto=you@example.com"
  • Network accessline 142
    "https://api.openalex.org/institutions?search=MIT&per-page=3&mailto=you@example.com"
  • Network accessline 149
    # Works from an institution works = json.loads(http_get(     "https://api.openalex.org/works"
  • Network accessline 150
    works = json.loads(http_get(     "https://api.openalex.org/works"     "?filter=institutions.id:I63966007"
  • Network accessline 151
    "https://api.openalex.org/works"
  • Network accessline 169
    # Concepts endpoint (Wikidata-linked) data = json.loads(http_get(     "https://api.openalex.org/concepts?search=machine+learning&per-page=5&mailto=you@example.com"
  • Network accessline 170
    data = json.loads(http_get(     "https://api.openalex.org/concepts?search=machine+learning&per-page=5&mailto=you@example.com" ))
  • Network accessline 171
    "https://api.openalex.org/concepts?search=machine+learning&per-page=5&mailto=you@example.com"
  • Network accessline 178
    # Topics endpoint (newer: domain > field > subfield > topic) data2 = json.loads(http_get(     "https://api.openalex.org/topics?search=machine+learning&per-page=3&mailto=you@example.com"
  • Network accessline 179
    data2 = json.loads(http_get(     "https://api.openalex.org/topics?search=machine+learning&per-page=3&mailto=you@example.com" ))
  • Network accessline 180
    "https://api.openalex.org/topics?search=machine+learning&per-page=3&mailto=you@example.com"
  • Network accessline 197
    data = json.loads(http_get(     "https://api.openalex.org/sources?search=nature&per-page=3&mailto=you@example.com"
  • Network accessline 198
    "https://api.openalex.org/sources?search=nature&per-page=3&mailto=you@example.com"
  • Network accessline 205
    # Works in a source works = json.loads(http_get(     "https://api.openalex.org/works?filter=primary_location.source.id:S137773608"
  • Network accessline 206
    works = json.loads(http_get(     "https://api.openalex.org/works?filter=primary_location.source.id:S137773608"     "&per-page=3&sort=cited_by_count:desc"
  • Network accessline 207
    "https://api.openalex.org/works?filter=primary_location.source.id:S137773608"
  • Network accessline 221
    data = json.loads(http_get(     "https://api.openalex.org/funders?search=national+science+foundation&per-page=3&mailto=you@example.com"
  • Network accessline 222
    "https://api.openalex.org/funders?search=national+science+foundation&per-page=3&mailto=you@example.com"
  • Network accessline 238
    # Papers that CITE this paper (forward citations) citing = json.loads(http_get(     f"https://api.openalex.org/works?filter=cites:{paper_id}"
  • Network accessline 239
    citing = json.loads(http_get(     f"https://api.openalex.org/works?filter=cites:{paper_id}"     "&per-page=5&sort=cited_by_count:desc"
  • Network accessline 240
    f"https://api.openalex.org/works?filter=cites:{paper_id}"
  • Network accessline 250
    # Papers THIS paper cites (backward — list of IDs in the work object) paper = json.loads(http_get(     f"https://api.openalex.org/works/{paper_id}?select=referenced_works&mailto=you@example.com"
  • Network accessline 251
    paper = json.loads(http_get(     f"https://api.openalex.org/works/{paper_id}?select=referenced_works&mailto=you@example.com" ))
  • Network accessline 252
    f"https://api.openalex.org/works/{paper_id}?select=referenced_works&mailto=you@example.com"
  • Network accessline 274
    encoded_cursor = urllib.parse.quote(cursor, safe="")         url = (             f"https://api.openalex.org/works"
  • Network accessline 275
    url = (             f"https://api.openalex.org/works"             f"?filter={query_filter}"
  • Network accessline 276
    f"https://api.openalex.org/works"
  • Network accessline 305
    # Publication counts by year for machine learning papers data = json.loads(http_get(     "https://api.openalex.org/works"
  • Network accessline 306
    data = json.loads(http_get(     "https://api.openalex.org/works"     "?filter=concepts.id:C119857082"    # C119857082 = Machine learning concept
  • Network accessline 307
    "https://api.openalex.org/works"
  • Network accessline 374
    | `language` | `language:en` | ISO 639-1 language code | | `cites` | `cites:W2626778328` | Works citing this paper | | `doi` | `doi:10.1038/nature14539` | By DOI (no `https://doi.org/` prefix) |
  • Network accessline 376
    | `doi` | `doi:10.1038/nature14539` | By DOI (no `https://doi.org/` prefix) |
  • Network accessline 383
    https://api.openalex.org/{entity_type}
  • Network accessline 417
    Full entity URLs: `https://openalex.org/{ID}` (canonical form returned in `id` field).
  • Network accessline 444
    - **OpenAlex IDs in the `id` field are full URLs, not bare IDs.** The field returns `https://openalex.org/W2626778328`. Always `.split("/")[-1]` to get the bare `W2626778328` form needed for `filter=cites:`, `filter=author.id:`, etc.
  • Network accessline 446
    - **DOI lookup uses the full DOI URL as the path parameter.** Correct: `GET /works/https://doi.org/10.1038/nature14539`. Incorrect: `GET /works/10.1038/nature14539` (returns 404).

agent-workspace/domain-skills/openstreetmap/scraping.md

  • Network accessline 21
    q = urllib.parse.quote(query)     raw = http_get(         f"https://nominatim.openstreetmap.org/search?q={q}&format=json&limit={limit}&addressdetails=1",
  • Network accessline 22
    raw = http_get(         f"https://nominatim.openstreetmap.org/search?q={q}&format=json&limit={limit}&addressdetails=1",         headers=UA
  • Network accessline 23
    f"https://nominatim.openstreetmap.org/search?q={q}&format=json&limit={limit}&addressdetails=1",
  • Network accessline 56
    raw = http_get(     "https://nominatim.openstreetmap.org/search?q=Eiffel+Tower&format=json&limit=3&addressdetails=1",
  • Network accessline 57
    "https://nominatim.openstreetmap.org/search?q=Eiffel+Tower&format=json&limit=3&addressdetails=1",
  • Network accessline 74
    raw = http_get(     "https://nominatim.openstreetmap.org/reverse?lat=48.8584&lon=2.2945&format=json",
  • Network accessline 75
    "https://nominatim.openstreetmap.org/reverse?lat=48.8584&lon=2.2945&format=json",
  • Network accessline 95
    raw = http_get(     "https://nominatim.openstreetmap.org/search?city=Paris&country=France&format=json&limit=1",
  • Network accessline 96
    "https://nominatim.openstreetmap.org/search?city=Paris&country=France&format=json&limit=1",
  • Network accessline 114
    # Prefix: N=node, W=way, R=relation raw = http_get(     "https://nominatim.openstreetmap.org/lookup?osm_ids=W5013364&format=json",
  • Network accessline 115
    raw = http_get(     "https://nominatim.openstreetmap.org/lookup?osm_ids=W5013364&format=json",     headers=UA
  • Network accessline 116
    "https://nominatim.openstreetmap.org/lookup?osm_ids=W5013364&format=json",
  • Network accessline 154
    **Endpoint**: `https://overpass-api.de/api/interpreter`
  • Network accessline 156
    - `https://overpass.openstreetmap.fr/api/interpreter` — requires non-Mozilla User-Agent
  • Network accessline 166
    UA = {"User-Agent": "browser-harness/1.0"} OVERPASS = "https://overpass.openstreetmap.fr/api/interpreter"
  • Network accessline 167
    OVERPASS = "https://overpass.openstreetmap.fr/api/interpreter"
  • Network accessline 205
    OVERPASS = "https://overpass.openstreetmap.fr/api/interpreter"
  • Network accessline 208
    """POST to Overpass — no URL length limits, preferred for multi-statement QL."""     data = urllib.parse.urlencode({"data": query}).encode()     req = urllib.request.Request(
  • Network accessline 209
    data = urllib.parse.urlencode({"data": query}).encode()     req = urllib.request.Request(         OVERPASS, data=data, method="POST",
  • Network accessline 210
    req = urllib.request.Request(
  • Network accessline 216
    }     )     with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 217
    )     with urllib.request.urlopen(req, timeout=30) as r:         body = r.read()
  • Network accessline 218
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 248
    "phone": "+33 1 45 51 56 74",         "opening_hours": "Mo-Sa 08:00-23:00; Su 09:00-19:00",  # optional         "website": "https://...",                               # optional
  • Network accessline 249
    "opening_hours": "Mo-Sa 08:00-23:00; Su 09:00-19:00",  # optional         "website": "https://...",                               # optional         "wheelchair": "yes"                                     # optional
  • Network accessline 250
    "website": "https://...",                               # optional
  • Network accessline 307
    https://{a,b,c}.tile.openstreetmap.org/{z}/{x}/{y}.png
  • Network accessline 312
    - Returns 256×256 PNG tiles - Policy: max 2 req/s per IP, non-commercial use, must display OSM attribution - Tile coordinate calculator: `https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames`
  • Network accessline 313
    - Policy: max 2 req/s per IP, non-commercial use, must display OSM attribution - Tile coordinate calculator: `https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames` - Bulk tile downloading is prohibited — use Overpass or data extracts in
  • Network accessline 314
    - Tile coordinate calculator: `https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames`
  • Network accessline 327
    x, y = lat_lon_to_tile(48.8582, 2.2945, 14) url = f"https://a.tile.openstreetmap.org/14/{x}/{y}.png"
  • Network accessline 328
    url = f"https://a.tile.openstreetmap.org/14/{x}/{y}.png"
  • Network accessline 329
    # url == 'https://a.tile.openstreetmap.org/14/8281/5646.png'
  • Network accessline 345
    raw = http_get("https://overpass-api.de/api/status", headers={"User-Agent": "browser-harness/1.0"})
  • Network accessline 357
    def overpass_get_with_retry(query: str, max_retries: int = 3) -> dict:     for attempt in range(max_retries):         url = f"https://overpass.openstreetmap.fr/api/interpreter?data={urllib.parse.quote(query)}"
  • Network accessline 358
    for attempt in range(max_retries):         url = f"https://overpass.openstreetmap.fr/api/interpreter?data={urllib.parse.quote(query)}"         raw = http_get(url, headers={"User-Agent": "browser-harness/1.0"})
  • Network accessline 359
    url = f"https://overpass.openstreetmap.fr/api/interpreter?data={urllib.parse.quote(query)}"
  • Network accessline 379
    UA = {"User-Agent": "browser-harness/1.0"} NOMINATIM = "https://nominatim.openstreetmap.org"
  • Network accessline 380
    NOMINATIM = "https://nominatim.openstreetmap.org"
  • Network accessline 381
    OVERPASS   = "https://overpass.openstreetmap.fr/api/interpreter"
  • Network accessline 403
    """POST variant — avoids URL length limits for complex queries."""     data = urllib.parse.urlencode({"data": query}).encode()     req = urllib.request.Request(
  • Network accessline 404
    data = urllib.parse.urlencode({"data": query}).encode()     req = urllib.request.Request(         OVERPASS, data=data, method="POST",
  • Network accessline 405
    req = urllib.request.Request(
  • Network accessline 409
    "Accept-Encoding": "gzip"}     )     with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 410
    )     with urllib.request.urlopen(req, timeout=30) as r:         body = r.read()
  • Network accessline 411
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 490
    **Overpass `http_get` POST workaround**: `http_get` only supports GET. For POST requests (needed to avoid URL length limits for complex multi-statement QL), use `urllib.request.Request` directly as shown in the `overpass_post()` example abo

agent-workspace/domain-skills/outlook/webmail-compose.md

  • Network accessline 5
    - Mail: `https://outlook.office.com/mail/`.

agent-workspace/domain-skills/package-registries/npm-pypi.md

  • Network accessline 3
    `https://registry.npmjs.org` · `https://api.npmjs.org` · `https://pypi.org` · `https://pypistats.org`
  • Network accessline 32
    import json data = json.loads(http_get("https://registry.npmjs.org/react"))
  • Network accessline 33
    data = json.loads(http_get("https://registry.npmjs.org/react"))
  • Network accessline 50
    print(v['license'])                          # 'MIT' print(list(v.get('dependencies', {}).keys())) # [] (react 19 has no runtime deps) print(v.get('homepage'))                     # 'https://react.dev/'
  • Network accessline 51
    print(list(v.get('dependencies', {}).keys())) # [] (react 19 has no runtime deps) print(v.get('homepage'))                     # 'https://react.dev/' print(len(data['versions']))                 # 2785 — all published versions
  • Network accessline 52
    print(v.get('homepage'))                     # 'https://react.dev/'
  • Network accessline 59
    import json # Fetch a specific version v = json.loads(http_get("https://registry.npmjs.org/react/19.2.5"))
  • Network accessline 60
    # Fetch a specific version v = json.loads(http_get("https://registry.npmjs.org/react/19.2.5")) print(v['name'], v['version'], v['description'])
  • Network accessline 61
    v = json.loads(http_get("https://registry.npmjs.org/react/19.2.5"))
  • Network accessline 64
    # Fetch latest directly (no need to resolve dist-tags first) v = json.loads(http_get("https://registry.npmjs.org/react/latest"))
  • Network accessline 65
    v = json.loads(http_get("https://registry.npmjs.org/react/latest"))
  • Network accessline 74
    req = urllib.request.Request(
  • Network accessline 75
    "https://registry.npmjs.org/react",
  • Network accessline 79
    } ) with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 80
    ) with urllib.request.urlopen(req, timeout=20) as r:     raw = r.read()
  • Network accessline 81
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 97
    import json data = json.loads(http_get("https://registry.npmjs.org/@playwright/test"))
  • Network accessline 98
    data = json.loads(http_get("https://registry.npmjs.org/@playwright/test"))
  • Network accessline 106
    # Direct path (preferred) url = f"https://registry.npmjs.org/{pkg}"          # '@playwright/test'
  • Network accessline 107
    url = f"https://registry.npmjs.org/{pkg}"          # '@playwright/test'
  • Network accessline 109
    url = f"https://registry.npmjs.org/{pkg.replace('/', '%2F')}"
  • Network accessline 124
    stats = json.loads(http_get("https://api.npmjs.org/downloads/point/last-week/react"))
  • Network accessline 142
    bulk = json.loads(http_get(     "https://api.npmjs.org/downloads/point/last-week/"
  • Network accessline 143
    "https://api.npmjs.org/downloads/point/last-week/"
  • Network accessline 166
    resp = json.loads(http_get(     "https://api.npmjs.org/downloads/range/2025-01-01:2025-01-07/react"
  • Network accessline 167
    "https://api.npmjs.org/downloads/range/2025-01-01:2025-01-07/react"
  • Network accessline 183
    # Fields: text, size (max ~250), from (offset), quality, popularity, maintenance weights data = json.loads(http_get(     "https://registry.npmjs.org/-/v1/search?text=browser+automation&size=5"
  • Network accessline 184
    data = json.loads(http_get(     "https://registry.npmjs.org/-/v1/search?text=browser+automation&size=5" ))
  • Network accessline 185
    "https://registry.npmjs.org/-/v1/search?text=browser+automation&size=5"
  • Network accessline 216
    try:     data = json.loads(http_get("https://registry.npmjs.org/nonexistent-pkg-xyz")) except urllib.error.HTTPError as e:
  • Network accessline 217
    data = json.loads(http_get("https://registry.npmjs.org/nonexistent-pkg-xyz")) except urllib.error.HTTPError as e:     # 404 for missing packages
  • Network accessline 233
    # Latest version metadata data = json.loads(http_get("https://pypi.org/pypi/requests/json"))
  • Network accessline 234
    data = json.loads(http_get("https://pypi.org/pypi/requests/json"))
  • Network accessline 245
    print(info['home_page'])        # None (may be empty — check project_urls) print(info['project_urls']) # {'Documentation': 'https://requests.readthedocs.io',
  • Network accessline 246
    print(info['project_urls']) # {'Documentation': 'https://requests.readthedocs.io', #  'Source': 'https://github.com/psf/requests'}
  • Network accessline 247
    # {'Documentation': 'https://requests.readthedocs.io',
  • Network accessline 248
    #  'Source': 'https://github.com/psf/requests'}
  • Network accessline 274
    # Fetch a pinned version (not just latest) data = json.loads(http_get("https://pypi.org/pypi/requests/2.32.3/json"))
  • Network accessline 275
    data = json.loads(http_get("https://pypi.org/pypi/requests/2.32.3/json"))
  • Network accessline 285
    data = json.loads(http_get("https://pypi.org/pypi/requests/json"))
  • Network accessline 315
    # Recent (last day/week/month) — fastest, single call stats = json.loads(http_get("https://pypistats.org/api/packages/requests/recent"))
  • Network accessline 316
    stats = json.loads(http_get("https://pypistats.org/api/packages/requests/recent"))
  • Network accessline 322
    # Historical daily totals (overall, going back ~6 months) overall = json.loads(http_get("https://pypistats.org/api/packages/requests/overall"))
  • Network accessline 323
    overall = json.loads(http_get("https://pypistats.org/api/packages/requests/overall"))
  • Network accessline 331
    # Without mirrors (pip installs only, more accurate for real usage): clean = json.loads(http_get(     "https://pypistats.org/api/packages/requests/overall?mirrors=false"
  • Network accessline 332
    clean = json.loads(http_get(     "https://pypistats.org/api/packages/requests/overall?mirrors=false" ))
  • Network accessline 333
    "https://pypistats.org/api/packages/requests/overall?mirrors=false"
  • Network accessline 336
    # By Python major version by_python = json.loads(http_get(     "https://pypistats.org/api/packages/requests/python_major"
  • Network accessline 337
    by_python = json.loads(http_get(     "https://pypistats.org/api/packages/requests/python_major" ))
  • Network accessline 338
    "https://pypistats.org/api/packages/requests/python_major"
  • Network accessline 342
    # By OS by_sys = json.loads(http_get(     "https://pypistats.org/api/packages/requests/system"
  • Network accessline 343
    by_sys = json.loads(http_get(     "https://pypistats.org/api/packages/requests/system" ))
  • Network accessline 344
    "https://pypistats.org/api/packages/requests/system"
  • Network accessline 348
    # By Python minor version by_minor = json.loads(http_get(     "https://pypistats.org/api/packages/requests/python_minor"
  • Network accessline 349
    by_minor = json.loads(http_get(     "https://pypistats.org/api/packages/requests/python_minor" ))
  • Network accessline 350
    "https://pypistats.org/api/packages/requests/python_minor"
  • Network accessline 362
    def get_pypi_info(pkg):     d = json.loads(http_get(f"https://pypi.org/pypi/{pkg}/json"))
  • Network accessline 363
    d = json.loads(http_get(f"https://pypi.org/pypi/{pkg}/json"))
  • Network accessline 388
    try:     data = json.loads(http_get("https://pypi.org/pypi/nonexistent-xyz-abc/json")) except urllib.error.HTTPError as e:
  • Network accessline 389
    data = json.loads(http_get("https://pypi.org/pypi/nonexistent-xyz-abc/json")) except urllib.error.HTTPError as e:     print(e.code)   # 404
  • Network accessline 405
    def npm_info(pkg):     # Use single-version endpoint (1-2KB) not full registry doc (MB)     v = json.loads(http_get(f"https://registry.npmjs.org/{pkg}/latest"))
  • Network accessline 406
    # Use single-version endpoint (1-2KB) not full registry doc (MB)     v = json.loads(http_get(f"https://registry.npmjs.org/{pkg}/latest"))     s = json.loads(http_get(f"https://api.npmjs.org/downloads/point/last-month/{pkg}"))
  • Network accessline 407
    v = json.loads(http_get(f"https://registry.npmjs.org/{pkg}/latest"))
  • Network accessline 408
    s = json.loads(http_get(f"https://api.npmjs.org/downloads/point/last-month/{pkg}"))
  • Network accessline 424
    pkgs = ['react', 'vue', 'angular', 'svelte'] bulk = json.loads(http_get(     f"https://api.npmjs.org/downloads/point/last-week/{','.join(pkgs)}"
  • Network accessline 425
    bulk = json.loads(http_get(     f"https://api.npmjs.org/downloads/point/last-week/{','.join(pkgs)}" ))
  • Network accessline 426
    f"https://api.npmjs.org/downloads/point/last-week/{','.join(pkgs)}"
  • Network accessline 464
    - **PyPI XML-RPC API is dead** — `https://pypi.org/pypi` (XML-RPC) returns a fault for most methods including `package_releases`. Use JSON API only.

agent-workspace/domain-skills/partsouq/vin-lookup.md

  • Network accessline 8
    https://partsouq.com/en/search/all?q=<17-char VIN>

agent-workspace/domain-skills/perplexity/computer.md

  • Network accessline 3
    "Perplexity Computer" is Perplexity's long-running agent product that lives under `https://www.perplexity.ai/computer/*`. It runs multi-step research/build tasks in a cloud sandbox and produces a plan (Todo), tool invocations, and file arti
  • Network accessline 9
    - Dashboard / task list: `https://www.perplexity.ai/computer/tasks`
  • Network accessline 10
    - Task detail (run page): `https://www.perplexity.ai/computer/tasks/<slug>-<id>`
  • Network accessline 16
    # Python: urlparse(href).path.rstrip('/').rsplit('/', 1)[-1][-22:]     ``` - Connectors: `https://www.perplexity.ai/computer/connectors`
  • Network accessline 17
    ``` - Connectors: `https://www.perplexity.ai/computer/connectors` - Custom skills: `https://www.perplexity.ai/computer/skills`
  • Network accessline 18
    - Connectors: `https://www.perplexity.ai/computer/connectors`
  • Network accessline 19
    - Custom skills: `https://www.perplexity.ai/computer/skills`
  • Network accessline 20
    - Public share: the same task URL with `?view=thread` appended (e.g. `https://www.perplexity.ai/computer/tasks/<slug>-<id>?view=thread`). There is **no separate `/share/<id>` path** — the access level is toggled server-side and the `view=th
  • Network accessline 44
    browser-harness <<'PY' new_tab("https://www.perplexity.ai/computer/tasks")
  • Network accessline 45
    new_tab("https://www.perplexity.ai/computer/tasks")
  • Network accessline 64
    browser-harness <<'PY' new_tab("https://www.perplexity.ai/computer/tasks")
  • Network accessline 65
    new_tab("https://www.perplexity.ai/computer/tasks")
  • Network accessline 115
    | Tool label | the only `<button>` direct child of the wrapper | Text = human-readable action, e.g. `"Writing to chart.py"`, `"Generating the comparison chart"`, `"Researching: <query>"`. | | Timestamp + duration | sibling text node with `A
  • Network accessline 116
    | Timestamp + duration | sibling text node with `Apr 17, 4:00 AM · 9s` format | Durations stop updating when the tool completes. | | Inline image artifact | `<img src="https://pplx-res.cloudinary.com/...">` or `<img src="https://d2z0o16i8xm
  • Network accessline 117
    | Inline image artifact | `<img src="https://pplx-res.cloudinary.com/...">` or `<img src="https://d2z0o16i8xm8ak.cloudfront.net/...">` | Cloudinary is the persistent URL; CloudFront URLs are presigned (expire) — if you want to archive, down
  • Network accessline 119
    | Citation favicons | `<img src="https://www.google.com/s2/favicons?domain=...">` | Google's favicon proxy; the hostnames next to them are the actual citation sources. |

agent-workspace/domain-skills/polymarket/scraping.md

  • Network accessline 9
    - Event page: `https://polymarket.com/event/<slug>` — a group of related markets (e.g. "Iran x Israel/US conflict ends by…" holds one market per proposed end-date).
  • Network accessline 10
    - Single market (rare nowadays; most UI routes are events): `https://polymarket.com/market/<slug>`.
  • Network accessline 15
    Base: `https://gamma-api.polymarket.com`. No auth, no key, no rate limit observed under normal use. All data structured JSON. **Use `http_get` from `helpers.py`.**
  • Network accessline 23
    ev = json.loads(http_get(     "https://gamma-api.polymarket.com/events?slug=iran-x-israelus-conflict-ends-by"
  • Network accessline 24
    "https://gamma-api.polymarket.com/events?slug=iran-x-israelus-conflict-ends-by"
  • Network accessline 63
    Endpoint: `https://gamma-api.polymarket.com/comments` (NOT `comments-api.polymarket.com` — that hostname no longer resolves as of Apr 2026).
  • Network accessline 71
    ev = json.loads(http_get("https://gamma-api.polymarket.com/events?slug=iran-x-israelus-conflict-ends-by"))[0]
  • Network accessline 73
    raw = http_get(     f"https://gamma-api.polymarket.com/comments"
  • Network accessline 74
    f"https://gamma-api.polymarket.com/comments"
  • Network accessline 104
    Real-time order book lives on `https://clob.polymarket.com`. Needed when `bestBid`/`bestAsk` on Gamma are stale (rare) or for trade history. Market-data endpoints don't need auth; order placement does.
  • Network accessline 107
    # Mid-price from live order book ob = json.loads(http_get(f"https://clob.polymarket.com/book?token_id={clob_token_id}"))
  • Network accessline 108
    ob = json.loads(http_get(f"https://clob.polymarket.com/book?token_id={clob_token_id}"))
  • Network accessline 132
    browser-harness <<'PY' new_tab("https://polymarket.com/event/iran-x-israelus-conflict-ends-by")
  • Network accessline 133
    new_tab("https://polymarket.com/event/iran-x-israelus-conflict-ends-by")

agent-workspace/domain-skills/poshmark/scraping.md

  • Network accessline 23
    UA = "poshmark-listing-export/1.0 (python-urllib; personal research script)" BASE = "https://poshmark.com"
  • Network accessline 24
    BASE = "https://poshmark.com"
  • Network accessline 52
    def fetch(url, budget_s=120):
  • Network accessline 58
    remaining = deadline - time.monotonic()         try:             req = urllib.request.Request(url, headers={
  • Network accessline 59
    try:             req = urllib.request.Request(url, headers={                 "User-Agent": UA, "Accept-Encoding": "gzip", "Accept-Language": "en-US,en;q=0.9"})
  • Network accessline 60
    req = urllib.request.Request(url, headers={
  • Network accessline 61
    "User-Agent": UA, "Accept-Encoding": "gzip", "Accept-Language": "en-US,en;q=0.9"})             with urllib.request.urlopen(req, timeout=max(0.1, min(30, remaining))) as r:                 body = read_body(r, deadline)
  • Network accessline 62
    with urllib.request.urlopen(req, timeout=max(0.1, min(30, remaining))) as r:
  • Network accessline 138
    for page in range(1, max_pages + 1):         url = browse_url(path, filters, page)         final, html = fetch(url)
  • Network accessline 139
    url = browse_url(path, filters, page)         final, html = fetch(url)         if not same_url(final, url):
  • Network accessline 140
    final, html = fetch(url)
  • Network accessline 183
    page 3: 48 rows, 48 new, total=5000, next=True 144 listings, status: truncated_max_pages {"id": "6add680c8925d3da8fdfd464", "title": "Levis | 712 Slim Fit 28 Distress Jeans", "brand": "Levi's", "size": "US 28", "price": 30.0, "original_pric
  • Network accessline 184
    144 listings, status: truncated_max_pages {"id": "6add680c8925d3da8fdfd464", "title": "Levis | 712 Slim Fit 28 Distress Jeans", "brand": "Levi's", "size": "US 28", "price": 30.0, "original_price": 67.0, "currency": "USD", "department": "Wom
  • Network accessline 185
    {"id": "6add680c8925d3da8fdfd464", "title": "Levis | 712 Slim Fit 28 Distress Jeans", "brand": "Levi's", "size": "US 28", "price": 30.0, "original_price": 67.0, "currency": "USD", "department": "Women", "category": "Denim", "status": "avail
  • Network accessline 187
    page 1: 0 rows, 0 new, total=0, next=False 0 listings for an unknown brand, status: complete refused: server sent us elsewhere: asked https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc, got https://poshmark.com/br
  • Network accessline 188
    0 listings for an unknown brand, status: complete refused: server sent us elsewhere: asked https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc, got https://poshmark.com/brand/lululemon_athletica-Women-Pants_&_Jumps
  • Network accessline 189
    refused: server sent us elsewhere: asked https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc, got https://poshmark.com/brand/lululemon_athletica-Women-Pants_&_Jumpsuits?sort_by=added_desc; call scrape() again with 
  • Network accessline 198
    {"id": "6add6586cbbea541a1f1443a", "title": "Lululemon License to Train High-Rise Pant Army Green Casual Women’s Active Small", "brand": "lululemon athletica", "size": "US S", "price": 85.0, "original_price": 128.0, "currency": "USD", "depa
  • Network accessline 203
    The hydrated page keeps `window.__INITIAL_STATE__`, so the browser path reads the same JSON instead of scraping tiles. `open_page` only accepts `https://poshmark.com/brand/<slug>` and `/category/<slug>` URLs, waits until the tab is on exact
  • Network accessline 245
    u = urllib.parse.urlparse(url)     if u.scheme != "https" or u.netloc != "poshmark.com" or not ALLOWED_PATH.fullmatch(urllib.parse.unquote(u.path)):         raise ValueError(f"refusing {url}: only https://poshmark.com/brand/<slug> and /cate
  • Network accessline 246
    if u.scheme != "https" or u.netloc != "poshmark.com" or not ALLOWED_PATH.fullmatch(urllib.parse.unquote(u.path)):         raise ValueError(f"refusing {url}: only https://poshmark.com/brand/<slug> and /category/<slug> pages are allowed")    
  • Network accessline 247
    raise ValueError(f"refusing {url}: only https://poshmark.com/brand/<slug> and /category/<slug> pages are allowed")
  • Network accessline 267
    MAX_PAGES, SITE_CAP_TOTAL = 3, 5000 base = "https://poshmark.com/category/Men-Shoes?" + urllib.parse.urlencode(
  • Network accessline 268
    base = "https://poshmark.com/category/Men-Shoes?" + urllib.parse.urlencode(
  • Network accessline 290
    time.sleep(2) try:   # this slug 301s to a different canonical path, so open_page() refuses it and names the target     open_page("https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc")
  • Network accessline 291
    try:   # this slug 301s to a different canonical path, so open_page() refuses it and names the target     open_page("https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc") except RuntimeError as e:
  • Network accessline 292
    open_page("https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc")
  • Network accessline 296
    try:   # robots.txt disallows /search: refused before the tab navigates     open_page("https://poshmark.com/search?query=nike")
  • Network accessline 297
    open_page("https://poshmark.com/search?query=nike")
  • Network accessline 315
    "price": 89,   "original_price": null,   "url": "https://poshmark.com/listing/6add6e68441b19999eb53d55"
  • Network accessline 316
    "original_price": null,   "url": "https://poshmark.com/listing/6add6e68441b19999eb53d55"  },
  • Network accessline 317
    "url": "https://poshmark.com/listing/6add6e68441b19999eb53d55"
  • Network accessline 319
    ... ] refused: redirected: asked https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc, got https://poshmark.com/brand/lululemon_athletica-Women-Pants_&_Jumpsuits?sort_by=added_desc; open that URL instead if it is th
  • Network accessline 320
    ] refused: redirected: asked https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc, got https://poshmark.com/brand/lululemon_athletica-Women-Pants_&_Jumpsuits?sort_by=added_desc; open that URL instead if it is the pa
  • Network accessline 321
    refused: redirected: asked https://poshmark.com/brand/Lululemon_Athletica-Women-Pants?sort_by=added_desc, got https://poshmark.com/brand/lululemon_athletica-Women-Pants_&_Jumpsuits?sort_by=added_desc; open that URL instead if it is the page
  • Network accessline 322
    refused: refusing https://poshmark.com/search?query=nike: only https://poshmark.com/brand/<slug> and /category/<slug> pages are allowed
  • Network accessline 354
    | `category` | `category` | e.g. `"Denim"`, `"Pants"` | | `status` | `inventory.status` | `"available"` | | `url` | built from `id`: `https://poshmark.com/listing/<id>` | 301s to the canonical `/listing/<Title-Slug>-<id>`. The slug is left 
  • Network accessline 355
    | `status` | `inventory.status` | `"available"` | | `url` | built from `id`: `https://poshmark.com/listing/<id>` | 301s to the canonical `/listing/<Title-Slug>-<id>`. The slug is left out because it repeats the seller-written title with spa
  • Network accessline 356
    | `url` | built from `id`: `https://poshmark.com/listing/<id>` | 301s to the canonical `/listing/<Title-Slug>-<id>`. The slug is left out because it repeats the seller-written title with spaces turned into `-` and punctuation dropped, so `r

agent-workspace/domain-skills/producthunt/scraping.md

  • Network accessline 3
    Field-tested against https://www.producthunt.com on 2026-04-18.
  • Network accessline 26
    # goto_url() may fail on Product Hunt — use new_tab() reliably tid = new_tab("https://www.producthunt.com")
  • Network accessline 27
    tid = new_tab("https://www.producthunt.com")
  • Network accessline 28
    wait(4)  # React SPA needs time; wait_for_load() alone is insufficient page = page_info() # Verify: url should be 'https://www.producthunt.com/'
  • Network accessline 30
    # Verify: url should be 'https://www.producthunt.com/'
  • Network accessline 90
    URL: https://www.producthunt.com/leaderboard/daily/YYYY/M/D
  • Network accessline 91
    Example: https://www.producthunt.com/leaderboard/daily/2026/4/18
  • Network accessline 110
    URL: https://www.producthunt.com/leaderboard/weekly/YYYY/WW
  • Network accessline 111
    Example: https://www.producthunt.com/leaderboard/weekly/2026/16
  • Network accessline 123
    URL: https://www.producthunt.com/leaderboard/monthly/YYYY/M
  • Network accessline 124
    Example: https://www.producthunt.com/leaderboard/monthly/2026/4
  • Network accessline 131
    URL: `https://www.producthunt.com/topics/developer-tools`
  • Network accessline 136
    # Navigate to topic new_tab("https://www.producthunt.com/topics/developer-tools")
  • Network accessline 137
    new_tab("https://www.producthunt.com/topics/developer-tools")
  • Network accessline 166
    URL: `https://www.producthunt.com/categories/ai-agents`
  • Network accessline 178
    URL: `https://www.producthunt.com/products/claude-opus-4-7`
  • Network accessline 204
    URL: `https://www.producthunt.com/search?q=AI+agent`
  • Network accessline 209
    new_tab("https://www.producthunt.com/search?q=AI+agent")
  • Network accessline 228
    **Note:** Search result elements are `<button>` elements (not `<a>` links), so there is no `href` in the DOM. Product URL must be constructed: `https://www.producthunt.com/products/<slug>` where slug must be derived by other means. The elem
  • Network accessline 275
    # 1. Open Product Hunt in a new tab new_tab("https://www.producthunt.com/leaderboard/daily/2026/4/18")
  • Network accessline 276
    new_tab("https://www.producthunt.com/leaderboard/daily/2026/4/18")

agent-workspace/domain-skills/pubmed/scraping.md

  • Network accessline 3
    `https://pubmed.ncbi.nlm.nih.gov` — 37 M+ biomedical citations. **Never use the browser for PubMed.** All data is reachable via `http_get` using the NCBI E-utilities REST API. No API key required; a free key raises the rate limit from 3 to 
  • Network accessline 13
    # Step 1: search → get PMIDs search = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 14
    search = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"     "?db=pubmed&term=deep+learning+radiology&retmax=10&retmode=json"
  • Network accessline 15
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 21
    # Step 2: fetch lightweight metadata for all PMIDs in one call summary = json.loads(http_get(     f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi"
  • Network accessline 22
    summary = json.loads(http_get(     f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi"     f"?db=pubmed&id={','.join(pmids)}&retmode=json"
  • Network accessline 23
    f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi"
  • Network accessline 50
    data = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 51
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 97
    data = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi"
  • Network accessline 98
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi"
  • Network accessline 137
    raw = http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
  • Network accessline 138
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
  • Network accessline 233
    # Step 1: ESearch with usehistory=y — NCBI holds result set on server search = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 234
    search = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"     "?db=pubmed&term=CRISPR+gene+editing&retmax=0&retmode=json&usehistory=y"
  • Network accessline 235
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 247
    for start in range(0, min(total, 1000), batch_size):  # cap at 1000 for demo     raw = http_get(         f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
  • Network accessline 248
    raw = http_get(         f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"         f"?db=pubmed&query_key={query_key}&WebEnv={webenv}"
  • Network accessline 249
    f"https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi"
  • Network accessline 265
    data = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/einfo.fcgi?retmode=json"
  • Network accessline 266
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/einfo.fcgi?retmode=json"
  • Network accessline 281
    data = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/einfo.fcgi?db=pubmed&retmode=json"
  • Network accessline 282
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/einfo.fcgi?db=pubmed&retmode=json"
  • Network accessline 304
    # linkname=pubmed_pmc — may also hit the server outage; check error field data = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi"
  • Network accessline 305
    data = json.loads(http_get(     "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi"     "?dbfrom=pubmed&id=38325330&linkname=pubmed_pmc&retmode=json"
  • Network accessline 306
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi"
  • Network accessline 329
    **Practical alternative**: If ELink is down, extract DOI from EFetch/ESummary and use `https://doi.org/{doi}` directly for the full-text link.
  • Network accessline 336
    https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi   # search → PMIDs
  • Network accessline 337
    https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi  # PMIDs → JSON summary
  • Network accessline 338
    https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi    # PMIDs → full XML
  • Network accessline 339
    https://eutils.ncbi.nlm.nih.gov/entrez/eutils/elink.fcgi     # cross-db links
  • Network accessline 340
    https://eutils.ncbi.nlm.nih.gov/entrez/eutils/einfo.fcgi     # DB metadata
  • Network accessline 371
    pmid = "41999029" pubmed_url  = f"https://pubmed.ncbi.nlm.nih.gov/{pmid}/"
  • Network accessline 372
    pubmed_url  = f"https://pubmed.ncbi.nlm.nih.gov/{pmid}/"
  • Network accessline 373
    doi         = "10.12659/MSM.951157" doi_url     = f"https://doi.org/{doi}"        # resolves to publisher page pmc_id      = "PMC9876543"                    # from ESummary articleids
  • Network accessline 374
    doi_url     = f"https://doi.org/{doi}"        # resolves to publisher page
  • Network accessline 376
    pmc_url     = f"https://www.ncbi.nlm.nih.gov/pmc/articles/{pmc_id}/"
  • Network accessline 405
    [Credential-related source omitted]
  • Access to secretsline 405
    [Credential-related source omitted]
  • Network accessline 411
    search = json.loads(http_get(       "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"
  • Network accessline 412
    "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi"

agent-workspace/domain-skills/qbo/report-export.md

  • Network accessline 11
    3. Set the required report expansion state. 4. Click QBO report toolbar `Export` -> `Export to PDF`. 5. Wait for the generated `blob:https://qbo.intuit.com/<uuid>` PDF target.
  • Network accessline 12
    4. Click QBO report toolbar `Export` -> `Export to PDF`. 5. Wait for the generated `blob:https://qbo.intuit.com/<uuid>` PDF target. 6. Fetch that blob from the QBO page origin and write the bytes locally.
  • Network accessline 13
    5. Wait for the generated `blob:https://qbo.intuit.com/<uuid>` PDF target. 6. Fetch that blob from the QBO page origin and write the bytes locally. 7. Validate with `pdftotext` when report content matters.
  • Network accessline 29
    BU_NAME=qbo BU_CDP_URL=http://127.0.0.1:9223 browser-harness <<'PY'
  • Network accessline 36
    - Custom reports list route: `https://qbo.intuit.com/app/customreports`.
  • Network accessline 69
    - QBO `Export` -> `Export to PDF` produces the clean report PDF. - This path may not fire a normal Chromium `Browser.downloadProgress` event, so `Browser.setDownloadBehavior` alone is not enough. - QBO opens an in-page PDF modal using Chrom
  • Network accessline 70
    - This path may not fire a normal Chromium `Browser.downloadProgress` event, so `Browser.setDownloadBehavior` alone is not enough. - QBO opens an in-page PDF modal using Chromium's built-in PDF viewer. The actual report PDF appears as a chi
  • Network accessline 71
    - QBO opens an in-page PDF modal using Chromium's built-in PDF viewer. The actual report PDF appears as a child `blob:https://qbo.intuit.com/<uuid>` target.
  • Network accessline 82
    t["url"]         for t in cdp("Target.getTargets")["targetInfos"]         if t.get("url", "").startswith("blob:https://qbo.intuit.com/")
  • Network accessline 83
    for t in cdp("Target.getTargets")["targetInfos"]         if t.get("url", "").startswith("blob:https://qbo.intuit.com/")     ]
  • Network accessline 84
    if t.get("url", "").startswith("blob:https://qbo.intuit.com/")
  • Network accessline 99
    wait(2)  # let the PDF viewer finish loading the blob     meta = js(f"""     return fetch({json.dumps(blob)}).then(async r => {{
  • Network accessline 100
    meta = js(f"""     return fetch({json.dumps(blob)}).then(async r => {{       const b = await r.blob();
  • Network accessline 101
    return fetch({json.dumps(blob)}).then(async r => {{
  • Possible obfuscationline 129
    pdf = base64.b64decode("".join(parts))

agent-workspace/domain-skills/quora/scraping.md

  • Network accessline 3
    `https://www.quora.com` — Q&A platform. One reliable access path: `http_get` with a Chrome UA against question, answer, topic, and profile pages. Quora SSR-renders all public data into `window.ansFrontendGlobals.data.inlineQueryResults` via
  • Network accessline 42
    Requires Chrome/Firefox UA — bare Mozilla/5.0 returns 403.     """     req = urllib.request.Request(url, headers={
  • Network accessline 43
    """     req = urllib.request.Request(url, headers={         "User-Agent": CHROME_UA,
  • Network accessline 44
    req = urllib.request.Request(url, headers={
  • Network accessline 48
    "Accept-Language": "en-US,en;q=0.9",     })     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 49
    })     with urllib.request.urlopen(req, timeout=20) as r:         data = r.read()
  • Network accessline 50
    with urllib.request.urlopen(req, timeout=20) as r:
  • Access to secretsline 96
    [Credential-related source omitted]
  • Network accessline 176
    result = quora_question("https://www.quora.com/What-is-the-meaning-of-life")
  • Network accessline 226
    """     Fetch a single answer by its permalink.     URL format: https://www.quora.com/{question-slug}/answer/{author-profile-slug}
  • Network accessline 227
    Fetch a single answer by its permalink.     URL format: https://www.quora.com/{question-slug}/answer/{author-profile-slug}     Returns answer dict with: aid, num_upvotes, num_views, text, author info.
  • Network accessline 228
    URL format: https://www.quora.com/{question-slug}/answer/{author-profile-slug}
  • Network accessline 251
    # Example: # quora_answer("https://www.quora.com/What-is-the-meaning-of-life/answer/Pararth-Shah")
  • Network accessline 252
    # quora_answer("https://www.quora.com/What-is-the-meaning-of-life/answer/Pararth-Shah")
  • Network accessline 262
    """     Fetch topic metadata from a Quora topic page.     URL format: https://www.quora.com/topic/{topic-slug}
  • Network accessline 263
    Fetch topic metadata from a Quora topic page.     URL format: https://www.quora.com/topic/{topic-slug}     Returns: tid, name, num_followers, url, is_following, has_leaderboard.
  • Network accessline 264
    URL format: https://www.quora.com/topic/{topic-slug}
  • Network accessline 289
    # Example: # quora_topic("https://www.quora.com/topic/Python-programming-language")
  • Network accessline 290
    # quora_topic("https://www.quora.com/topic/Python-programming-language")
  • Network accessline 299
    def quora_profile(profile_url):     """     Fetch user profile data from https://www.quora.com/profile/{username}
  • Network accessline 300
    """     Fetch user profile data from https://www.quora.com/profile/{username}     Returns: uid, name, credential, follower_count, following_count, profile_image_url.
  • Network accessline 301
    Fetch user profile data from https://www.quora.com/profile/{username}
  • Network accessline 330
    # Example: # quora_profile("https://www.quora.com/profile/Pararth-Shah")
  • Network accessline 331
    # quora_profile("https://www.quora.com/profile/Pararth-Shah")
  • Network accessline 356
    - **Search pages do not yield result data** — `https://www.quora.com/search?q=...` returns 3 payloads with viewer/network info only — no search results in the SSR payload. Search results are loaded client-side and are not accessible via htt
  • Network accessline 362
    - **`permaUrl` may be an absolute URL for Spaces answers** — Most answers have `permaUrl: "/Question-slug/answer/Author-Name"` (relative). Answers posted in a Quora Space have a full absolute URL like `"https://spacename.quora.com/Question-

agent-workspace/domain-skills/rawg/scraping.md

  • Network accessline 3
    Field-tested against rawg.io on 2026-04-18. `https://rawg.io` — world's largest video game database with 500K+ games.
  • Network accessline 4
    `https://rawg.io` — world's largest video game database with 500K+ games.
  • Network accessline 10
    `https://api.rawg.io/api/` requires a valid API key on every request.
  • Network accessline 21
    Free API keys are available at `https://rawg.io/apidocs` after signing up at `https://rawg.io/signup` (no credit card, ~1 minute). Free tier: **20,000 requests/month**.
  • Network accessline 22
    `https://rawg.io/signup` (no credit card, ~1 minute). Free tier: **20,000 requests/month**.
  • Access to secretsline 23
    [Credential-related source omitted]
  • Network accessline 44
    Returns game dict or None.     """     resp = http_get(f"https://rawg.io/games/{slug}")
  • Network accessline 45
    """     resp = http_get(f"https://rawg.io/games/{slug}")     idx = resp.find('window.CLIENT_PARAMS = {')
  • Network accessline 46
    resp = http_get(f"https://rawg.io/games/{slug}")
  • Network accessline 85
    # game['updated']          -> '2026-04-17T23:18:04' # game['playtime']         -> 43            (average hours) # game['website']          -> 'https://thewitcher.com/en/witcher3'
  • Network accessline 86
    # game['playtime']         -> 43            (average hours) # game['website']          -> 'https://thewitcher.com/en/witcher3' # game['background_image'] -> 'https://media.rawg.io/media/games/618/618c2031a07bbff6b4f611f10b6bcdbc.jpg'
  • Network accessline 87
    # game['website']          -> 'https://thewitcher.com/en/witcher3'
  • Network accessline 88
    # game['background_image'] -> 'https://media.rawg.io/media/games/618/618c2031a07bbff6b4f611f10b6bcdbc.jpg'
  • Network accessline 145
    def top_games():     """Returns list of 40 game dicts from rawg.io/games listing page."""     resp = http_get("https://rawg.io/games")
  • Network accessline 146
    """Returns list of 40 game dicts from rawg.io/games listing page."""     resp = http_get("https://rawg.io/games")     idx = resp.find('window.CLIENT_PARAMS = {')
  • Network accessline 147
    resp = http_get("https://rawg.io/games")
  • Network accessline 194
    [Credential-related source omitted]
  • Access to secretsline 194
    [Credential-related source omitted]
  • Network accessline 198
    1. Sign up at `https://rawg.io/signup`
  • Network accessline 199
    2. Visit `https://rawg.io/apidocs` — click "Get API key"
  • Access to secretsline 201
    [Credential-related source omitted]
  • Access to secretsline 209
    [Credential-related source omitted]
  • Network accessline 211
    # Search results = json.loads(http_get(     f"https://api.rawg.io/api/games?search=witcher&page_size=5&key={KEY}"
  • Network accessline 212
    results = json.loads(http_get(     f"https://api.rawg.io/api/games?search=witcher&page_size=5&key={KEY}" ))
  • Network accessline 213
    f"https://api.rawg.io/api/games?search=witcher&page_size=5&key={KEY}"
  • Network accessline 219
    # Top-rated top = json.loads(http_get(     f"https://api.rawg.io/api/games?ordering=-metacritic&page_size=10&key={KEY}"
  • Network accessline 220
    top = json.loads(http_get(     f"https://api.rawg.io/api/games?ordering=-metacritic&page_size=10&key={KEY}" ))
  • Network accessline 221
    f"https://api.rawg.io/api/games?ordering=-metacritic&page_size=10&key={KEY}"
  • Network accessline 224
    # By date range recent = json.loads(http_get(     f"https://api.rawg.io/api/games?dates=2024-01-01,2024-12-31&ordering=-added&page_size=20&key={KEY}"
  • Network accessline 225
    recent = json.loads(http_get(     f"https://api.rawg.io/api/games?dates=2024-01-01,2024-12-31&ordering=-added&page_size=20&key={KEY}" ))
  • Network accessline 226
    f"https://api.rawg.io/api/games?dates=2024-01-01,2024-12-31&ordering=-added&page_size=20&key={KEY}"
  • Network accessline 229
    # By platform (PC=4, PS4=18, Xbox One=1, Switch=7) pc_games = json.loads(http_get(     f"https://api.rawg.io/api/games?platforms=4&ordering=-rating&page_size=10&key={KEY}"
  • Network accessline 230
    pc_games = json.loads(http_get(     f"https://api.rawg.io/api/games?platforms=4&ordering=-rating&page_size=10&key={KEY}" ))
  • Network accessline 231
    f"https://api.rawg.io/api/games?platforms=4&ordering=-rating&page_size=10&key={KEY}"
  • Network accessline 238
    # By ID (faster if you have it) game = json.loads(http_get(f"https://api.rawg.io/api/games/3328?key={KEY}"))
  • Network accessline 239
    game = json.loads(http_get(f"https://api.rawg.io/api/games/3328?key={KEY}"))
  • Network accessline 242
    # By slug game = json.loads(http_get(     f"https://api.rawg.io/api/games/the-witcher-3-wild-hunt?key={KEY}"
  • Network accessline 243
    game = json.loads(http_get(     f"https://api.rawg.io/api/games/the-witcher-3-wild-hunt?key={KEY}" ))
  • Network accessline 244
    f"https://api.rawg.io/api/games/the-witcher-3-wild-hunt?key={KEY}"
  • Network accessline 270
    # All platforms platforms = json.loads(http_get(f"https://api.rawg.io/api/platforms?key={KEY}"))
  • Network accessline 271
    platforms = json.loads(http_get(f"https://api.rawg.io/api/platforms?key={KEY}"))
  • Network accessline 274
    # Parent platforms only parents = json.loads(http_get(f"https://api.rawg.io/api/platforms/lists/parents?key={KEY}"))
  • Network accessline 275
    parents = json.loads(http_get(f"https://api.rawg.io/api/platforms/lists/parents?key={KEY}"))
  • Network accessline 277
    # Genres genres = json.loads(http_get(f"https://api.rawg.io/api/genres?key={KEY}"))
  • Network accessline 278
    genres = json.loads(http_get(f"https://api.rawg.io/api/genres?key={KEY}"))

agent-workspace/domain-skills/realtor-com/scraping.md

  • Network accessline 10
    - **Search pages** (`/realestateandhomes-search/<City_ST or ZIP>[/pg-N]`) are a React Router app. All 42 results per page, plus the total count, sit in `window.__reactRouterDataRouter.state.loaderData.srp.search.value`. That object has pric
  • Network accessline 11
    - **Listing pages** (`/realestateandhomes-detail/<slug>`) are a Next.js app. `__NEXT_DATA__` -> `props.pageProps.initialReduxState.propertyDetails` holds the full key facts (year built, HOA, price/sqft, days on MLS, lot, garage, stories, de
  • Network accessline 12
    - From an open realtor.com tab, a same-origin `fetch()` of a listing URL returned 200 with `__NEXT_DATA__` in the HTML. That gives listing facts in batches without navigating the tab.
  • Network accessline 52
    is_foreclosure: !!f.is_foreclosure, is_new_listing: !!f.is_new_listing,         list_date: p.list_date, lat: p.lat, lng: p.lng, broker: p.brokerageName,         url: p.ldpSlug ? 'https://www.realtor.com/realestateandhomes-detail/' + p.ldpSl
  • Network accessline 53
    list_date: p.list_date, lat: p.lat, lng: p.lng, broker: p.brokerageName,         url: p.ldpSlug ? 'https://www.realtor.com/realestateandhomes-detail/' + p.ldpSlug : null       };
  • Network accessline 54
    url: p.ldpSlug ? 'https://www.realtor.com/realestateandhomes-detail/' + p.ldpSlug : null
  • Network accessline 60
    def search_url(location, page=1):     base = "https://www.realtor.com/realestateandhomes-search/" + urllib.parse.quote(location, safe="")
  • Network accessline 61
    base = "https://www.realtor.com/realestateandhomes-search/" + urllib.parse.quote(location, safe="")
  • Network accessline 135
    STOPPED AT MAX_PAGES=3: 126 of 7008 collected; raise MAX_PAGES for the rest 126 listings of 7008 (partial) 1704 Shelbourne Dr 78752 400000 3 2 1556 House for sale https://www.realtor.com/realestateandhomes-detail/1704-Shelbourne-Dr_Austin_T
  • Network accessline 136
    126 listings of 7008 (partial) 1704 Shelbourne Dr 78752 400000 3 2 1556 House for sale https://www.realtor.com/realestateandhomes-detail/1704-Shelbourne-Dr_Austin_TX_78752_M81029-30727 6700 Tulloch Way 78754 439999 4 3.5 3840 Pending https:
  • Network accessline 137
    1704 Shelbourne Dr 78752 400000 3 2 1556 House for sale https://www.realtor.com/realestateandhomes-detail/1704-Shelbourne-Dr_Austin_TX_78752_M81029-30727
  • Network accessline 138
    6700 Tulloch Way 78754 439999 4 3.5 3840 Pending https://www.realtor.com/realestateandhomes-detail/6700-Tulloch-Way_Austin_TX_78754_M83959-32351
  • Network accessline 139
    6305 Leatherwood Cv 78759 720000 4 2.5 2164 House for sale https://www.realtor.com/realestateandhomes-detail/6305-Leatherwood-Cv_Austin_TX_78759_M76134-13530
  • Network accessline 147
    This needs a www.realtor.com tab (block 1 leaves one open), because `fetch()` must be same-origin. It reads the saved `realtor_listings.json`, fetches each listing's HTML from inside the page and parses `__NEXT_DATA__`.
  • Network accessline 165
    const ctl = new AbortController();   const timer = setTimeout(() => ctl.abort(), 30000);   fetch(url, {credentials: 'same-origin', signal: ctl.signal}).then(async res => {
  • Network accessline 166
    const timer = setTimeout(() => ctl.abort(), 30000);   fetch(url, {credentials: 'same-origin', signal: ctl.signal}).then(async res => {     const html = await res.text();
  • Network accessline 167
    fetch(url, {credentials: 'same-origin', signal: ctl.signal}).then(async res => {
  • Network accessline 265
    if not on_realtor():     try:         goto_url("https://www.realtor.com/")
  • Network accessline 266
    try:         goto_url("https://www.realtor.com/")     except TimeoutError:
  • Network accessline 267
    goto_url("https://www.realtor.com/")
  • Network accessline 273
    time.sleep(1)     else:         raise RuntimeError("need a www.realtor.com tab for same-origin fetch()")
  • Network accessline 275
    raise RuntimeError("need a www.realtor.com tab for same-origin fetch()")
  • Network accessline 319
    {'url': 'https://www.realtor.com/realestateandhomes-detail/6700-Tulloch-Way_Austin_TX_78754_M83959-32351', 'property_id': '8395932351', 'listing_id': '3001457163', 'status': 'for_sale', 'flags': ['is_pending'], 'list_price': 439999, 'price_
  • Network accessline 431
    {'name': '1704 Shelbourne Dr, Austin, TX 78752', 'price': 400000, 'availability': 'https://schema.org/InStock', 'beds': 3, 'baths': 2, 'sqft': 1556, 'year_built': 1969, 'type': 'SingleFamilyResidence', 'date_posted': '2026-02-21T14:21:38Z',
  • Network accessline 454
    | `lat`, `lng` | `lat`, `lng` | | | `broker` | `brokerageName` | brokerage business name | | `url` | `ldpSlug` | `https://www.realtor.com/realestateandhomes-detail/<ldpSlug>`; null when there is no slug |
  • Network accessline 456
    | `url` | `ldpSlug` | `https://www.realtor.com/realestateandhomes-detail/<ldpSlug>`; null when there is no slug |
  • Network accessline 490
    - **`__NEXT_DATA__` on search pages is a stub** (`{"props":{"pageProps":{"geo":{"area_type":"city"}}}}`). Search moved to React Router. Listing pages still use Next.js. - **Two apps, two globals.** `window.__reactRouterDataRouter` exists on
  • Network accessline 491
    - **Two apps, two globals.** `window.__reactRouterDataRouter` exists on search pages only. On listing pages, use `#__NEXT_DATA__` or JSON-LD. - **`js()` gives up after about 5 s.** In browser-harness, a slow `Runtime.evaluate` raises `Runti
  • Network accessline 492
    - **`js()` gives up after about 5 s.** In browser-harness, a slow `Runtime.evaluate` raises `RuntimeError("Runtime.evaluate timed out ...")`, and a slow `goto_url()` can raise `TimeoutError` (the daemon's IPC wait is 5 s). The blocks catch 
  • Network accessline 508
    - Pages past the end (`/78704/pg-11` when `total=398`) return 0 rows rather than an error. Block 1 stops at the first short page, so it never requests them. - An unknown location (`Nowhereville_ZZ`): the page loads with the title "For Sale 
  • Network accessline 510
    - An unknown listing slug: `fetch()` returned 200 after a redirect to `/realestateandhomes-search/Austin_TX`, with no `propertyDetails`. Block 2 treats that as a failed listing and does not retry it.

agent-workspace/domain-skills/reddit/scraping.md

  • Network accessline 9
    - Full post: `https://www.reddit.com/r/<sub>/comments/<id>/<slug>/`
  • Network accessline 10
    - Share short-link: `https://www.reddit.com/r/<sub>/s/<hash>` — redirects to the full URL once the page loads. `new_tab(short_url)` + `wait_for_load()` is enough; by the time you read `location.href` it will be the canonical one.
  • Network accessline 11
    - Old Reddit: append `/.json` to any post URL for anonymous JSON: `https://www.reddit.com/r/<sub>/comments/<id>/.json`.
  • Network accessline 12
    - Old UI (simpler DOM, no web components): `https://old.reddit.com/r/<sub>/comments/<id>/` — useful fallback when `shreddit-*` selectors change.
  • Network accessline 20
    url = "https://www.reddit.com/r/cursor/comments/1l0u9y7/claude_code_prompt_to_autogenerate_full_cursor/.json"
  • Network accessline 38
    browser-harness <<'PY' new_tab("https://www.reddit.com/r/vibecoding/comments/1kwuqpz/")
  • Network accessline 39
    new_tab("https://www.reddit.com/r/vibecoding/comments/1kwuqpz/")

agent-workspace/domain-skills/redfin/scraping.md

  • Network accessline 26
    PAUSE = 3.0          # seconds between page loads MAX_SHORT = 0.01     # raise if more than this share of the header count is missing (a live count drifts a little) BASE = "https://www.redfin.com"
  • Network accessline 28
    BASE = "https://www.redfin.com"
  • Network accessline 234
    "price_per_sqft": 683, "hoa_month": null, "days_on_market": 1, "status": "Active",   "neighborhood": "SOUTH PARK SEC 2", "lat": 30.232246, "lon": -97.7638868,   "url": "https://www.redfin.com/TX/Austin/503-S-Park-Dr-78704/home/31703545", "s
  • Network accessline 235
    "neighborhood": "SOUTH PARK SEC 2", "lat": 30.232246, "lon": -97.7638868,   "url": "https://www.redfin.com/TX/Austin/503-S-Park-Dr-78704/home/31703545", "source": "embedded"},  {"property_id": 31205095, "address": "1818 Margaret St", "price
  • Network accessline 236
    "url": "https://www.redfin.com/TX/Austin/503-S-Park-Dr-78704/home/31703545", "source": "embedded"},
  • Network accessline 265
    Reads the first URL saved by block 1; pass any `https://www.redfin.com/.../home/<id>` URL to `listing_details()` instead. Everything comes from the one listing page: its JSON-LD plus the detail data embedded in its HTML.
  • Network accessline 406
    {  "url": "https://www.redfin.com/TX/Austin/503-S-Park-Dr-78704/home/31703545",
  • Network accessline 407
    "url": "https://www.redfin.com/TX/Austin/503-S-Park-Dr-78704/home/31703545",
  • Network accessline 412
    "lat": 30.232246, "lon": -97.7638868,  "amenities": ["Heating & cooling: Has A/C"],  "photos": "22 urls, first: https://ssl.cdn-redfin.com/photo/92/bigphoto/245/3820245_0.jpg",
  • Network accessline 413
    "amenities": ["Heating & cooling: Has A/C"],  "photos": "22 urls, first: https://ssl.cdn-redfin.com/photo/92/bigphoto/245/3820245_0.jpg",  "property_id": 31703545, "listing_id": 224677425, "mls_id": "3820245",
  • Network accessline 414
    "photos": "22 urls, first: https://ssl.cdn-redfin.com/photo/92/bigphoto/245/3820245_0.jpg",
  • Network accessline 446
    | neighborhood | `location.value` | embedded only | `"SOUTH PARK SEC 2"` | | lat / lon | `latLong.value.latitude/longitude` | JSON-LD `geo` | `30.232246`, `-97.7638868` | | url | `"https://www.redfin.com" + url` | card link | `.../home/3170
  • Network accessline 447
    | lat / lon | `latLong.value.latitude/longitude` | JSON-LD `geo` | `30.232246`, `-97.7638868` | | url | `"https://www.redfin.com" + url` | card link | `.../home/31703545` | | source | `"embedded"` | `"card"` | |
  • Network accessline 448
    | url | `"https://www.redfin.com" + url` | card link | `.../home/31703545` |
  • Network accessline 488
    - Plain HTTP is blocked: `curl https://www.redfin.com/robots.txt` was redirected to `ratelimited.redfin.com` with status 429, so even robots.txt was read in the browser.

agent-workspace/domain-skills/rest-countries/scraping.md

  • Network accessline 3
    `https://restcountries.com` — open JSON API for country data. **Never use the browser.** All data is reachable via `http_get`. No auth required, no API key.
  • Network accessline 13
    data = http_get("https://restcountries.com/v3.1/all?fields=name,cca2,capital,population,area,region")
  • Network accessline 40
    # Single code — returns a list (one element) data = http_get("https://restcountries.com/v3.1/alpha/DE")
  • Network accessline 41
    data = http_get("https://restcountries.com/v3.1/alpha/DE")
  • Network accessline 44
    # But: /alpha/CODE?fields=... returns a plain dict, not a list — watch for this data2 = http_get("https://restcountries.com/v3.1/alpha/DE?fields=name,cca2,currencies,languages,flags")
  • Network accessline 45
    data2 = http_get("https://restcountries.com/v3.1/alpha/DE?fields=name,cca2,currencies,languages,flags")
  • Network accessline 52
    languages  = country2["languages"]                                  # {"deu": "German"} lang_names = list(languages.values())                               # ["German"] flag_png   = country2["flags"]["png"]                               # "
  • Network accessline 53
    lang_names = list(languages.values())                               # ["German"] flag_png   = country2["flags"]["png"]                               # "https://flagcdn.com/w320/de.png" flag_svg   = country2["flags"]["svg"]                  
  • Network accessline 54
    flag_png   = country2["flags"]["png"]                               # "https://flagcdn.com/w320/de.png"
  • Network accessline 55
    flag_svg   = country2["flags"]["svg"]                               # "https://flagcdn.com/de.svg"
  • Network accessline 70
    codes = ["US", "GB", "FR", "DE", "JP", "CN", "IN", "BR", "AU", "CA"] data = http_get(f"https://restcountries.com/v3.1/alpha?codes={','.join(codes)}&fields=name,cca2,population")
  • Network accessline 71
    data = http_get(f"https://restcountries.com/v3.1/alpha?codes={','.join(codes)}&fields=name,cca2,population")
  • Network accessline 85
    # Partial match (default) — may return multiple results data = http_get("https://restcountries.com/v3.1/name/united")
  • Network accessline 86
    data = http_get("https://restcountries.com/v3.1/name/united")
  • Network accessline 90
    # Exact match — use fullText=true with the full common or official name data2 = http_get("https://restcountries.com/v3.1/name/united%20kingdom?fullText=true")
  • Network accessline 91
    data2 = http_get("https://restcountries.com/v3.1/name/united%20kingdom?fullText=true")
  • Network accessline 103
    data = http_get("https://restcountries.com/v3.1/region/europe?fields=name,cca2,population")
  • Network accessline 122
    data = http_get("https://restcountries.com/v3.1/subregion/Western%20Europe?fields=name,cca2")
  • Network accessline 134
    data = http_get("https://restcountries.com/v3.1/lang/arabic")
  • Network accessline 149
    data = http_get("https://restcountries.com/v3.1/currency/EUR")
  • Network accessline 164
    data = http_get("https://restcountries.com/v3.1/capital/berlin?fields=name,cca2,capital")
  • Network accessline 177
    data = http_get("https://restcountries.com/v3.1/alpha/US")

agent-workspace/domain-skills/rightmove/scraping.md

  • Network accessline 9
    - Search result pages (`/property-for-sale/find.html`, `/property-to-rent/find.html`) are Next.js pages. Every listing on the page is in `<script id="__NEXT_DATA__">` at `props.pageProps.searchResults.properties`. A plain HTTP GET gets it, 
  • Network accessline 10
    - A free-text place ("Bristol", "Camden Town", "BS8") must first be turned into a `locationIdentifier` like `REGION^219` or `OUTCODE^295` with the public typeahead endpoint `https://los.rightmove.co.uk/typeahead`.
  • Network accessline 11
    - 24 organic listings per page plus 1 "featured" slot (25 objects). Paginate with `index=0, 24, 48 ...`. Hard cap: 42 pages / `index=984` (about 1,000 listings) even when `resultCount` is higher. The code below reports when it hits that cap
  • Network accessline 12
    - Property pages (`/properties/<id>`) embed `window.__PAGE_MODEL`, a flattened JSON graph. Decode it to get key features, full description, tenure, council tax band, nearest stations and (for rentals) deposit / furnishing / available date. 
  • Network accessline 13
    - Plain-HTTP requests (typeahead and search pages only) send a truthful client User-Agent naming this skill. An HTTP 403/429 whose body says the service is "for the use of Rightmove Group Limited only" is an access block: `fetch()` stops an
  • Network accessline 26
    HEADERS = {     "User-Agent": "browser-harness-rightmove-skill/1.0 (+https://github.com/browser-use/browser-harness)",  # truthful client UA
  • Network accessline 27
    "User-Agent": "browser-harness-rightmove-skill/1.0 (+https://github.com/browser-use/browser-harness)",  # truthful client UA
  • Network accessline 58
    def fetch(url, accept="text/html", tries=4):
  • Network accessline 64
    wait = None         try:             req = urllib.request.Request(url, headers={**HEADERS, "Accept": accept})
  • Network accessline 65
    try:             req = urllib.request.Request(url, headers={**HEADERS, "Accept": accept})             with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 66
    req = urllib.request.Request(url, headers={**HEADERS, "Accept": accept})
  • Network accessline 67
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 89
    def find_location(query):     """Free text -> list of (locationIdentifier, displayName), best first. Punctuation breaks the endpoint (HTTP 400)."""     url = "https://los.rightmove.co.uk/typeahead?" + urllib.parse.urlencode({"query": _norm(
  • Network accessline 90
    """Free text -> list of (locationIdentifier, displayName), best first. Punctuation breaks the endpoint (HTTP 400)."""     url = "https://los.rightmove.co.uk/typeahead?" + urllib.parse.urlencode({"query": _norm(query), "limit": 10, "exclude"
  • Network accessline 91
    url = "https://los.rightmove.co.uk/typeahead?" + urllib.parse.urlencode({"query": _norm(query), "limit": 10, "exclude": "STREET"})
  • Network accessline 92
    status, _, text = fetch(url, accept="application/json")  # without this Accept you get XML
  • Network accessline 109
    path = CHANNEL_PATHS[channel]     params = {"locationIdentifier": location_id, "index": index, **filters}     url = f"https://www.rightmove.co.uk/{path}/find.html?" + urllib.parse.urlencode(params)  # ^ -> %5E
  • Network accessline 110
    params = {"locationIdentifier": location_id, "index": index, **filters}     url = f"https://www.rightmove.co.uk/{path}/find.html?" + urllib.parse.urlencode(params)  # ^ -> %5E     status, final_url, html = fetch(url)
  • Network accessline 111
    url = f"https://www.rightmove.co.uk/{path}/find.html?" + urllib.parse.urlencode(params)  # ^ -> %5E
  • Network accessline 112
    status, final_url, html = fetch(url)
  • Network accessline 151
    "first_visible": p.get("firstVisibleDate"),         "featured": p.get("featuredProperty"),         "url": f"https://www.rightmove.co.uk/properties/{pid}" if pid is not None else None,
  • Network accessline 152
    "featured": p.get("featuredProperty"),         "url": f"https://www.rightmove.co.uk/properties/{pid}" if pid is not None else None,     }
  • Network accessline 153
    "url": f"https://www.rightmove.co.uk/properties/{pid}" if pid is not None else None,
  • Network accessline 206
    Bristol REGION^219 results: 1994 pages: 2 stopped: max_pages rows: 50 {'id': 94594029, 'address': 'Bowden Place, Downend', 'price': 285000, 'price_text': '£285,000', 'frequency': 'not specified', 'beds': 2, 'baths': 1, 'type': 'End of Terra
  • Network accessline 207
    {'id': 94594029, 'address': 'Bowden Place, Downend', 'price': 285000, 'price_text': '£285,000', 'frequency': 'not specified', 'beds': 2, 'baths': 1, 'type': 'End of Terrace', 'agent': 'Ocean, Downend', 'added_or_reduced': 'Added yesterday',
  • Network accessline 296
    def get_property(property_id, first=False):     """Decoded property page, or None if the listing is gone (404/410)."""     url = f"https://www.rightmove.co.uk/properties/{property_id}"
  • Network accessline 297
    """Decoded property page, or None if the listing is gone (404/410)."""     url = f"https://www.rightmove.co.uk/properties/{property_id}"     if not open_and_confirm(url, property_check(property_id), first=first):
  • Network accessline 298
    url = f"https://www.rightmove.co.uk/properties/{property_id}"
  • Network accessline 324
    def first_ids(path, location_id, n=2, first=False):     url = f"https://www.rightmove.co.uk/{path}/find.html?" + urllib.parse.urlencode({"locationIdentifier": location_id, "index": 0})
  • Network accessline 325
    url = f"https://www.rightmove.co.uk/{path}/find.html?" + urllib.parse.urlencode({"locationIdentifier": location_id, "index": 0})
  • Network accessline 433
    base = "https://www.rightmove.co.uk/property-to-rent/find.html?"
  • Network accessline 463
    pid = rows[0][0]     time.sleep(1.5)     if not open_and_confirm(f"https://www.rightmove.co.uk/properties/{pid}", property_check(pid)):
  • Network accessline 464
    time.sleep(1.5)     if not open_and_confirm(f"https://www.rightmove.co.uk/properties/{pid}", property_check(pid)):         raise RuntimeError(f"property {pid} answered 404/410")
  • Network accessline 465
    if not open_and_confirm(f"https://www.rightmove.co.uk/properties/{pid}", property_check(pid)):
  • Network accessline 500
    | `first_visible` | `firstVisibleDate` | `"2026-05-15T15:36:54Z"` | | `featured` | `featuredProperty` | `true` on the 1 paid slot per page | | `url` | built from `id` | `https://www.rightmove.co.uk/properties/88550319` |
  • Network accessline 502
    | `url` | built from `id` | `https://www.rightmove.co.uk/properties/88550319` |
  • Network accessline 537
    - **Access block.** Plain-HTTP requests to property pages returned HTTP 429 with a body saying the API "is for the use of Rightmove Group Limited only". That is an access block, not a rate limit: example 1's `fetch()` raises on a 403/429 wi
  • Network accessline 538
    - **Retry-After.** Example 1's `fetch()` honours `Retry-After` (seconds or HTTP-date) up to 120 s and raises if the server asks for longer. It never sleeps after the last attempt.
  • Network accessline 541
    - **Typeahead returns XML unless you send `Accept: application/json`.** - **Ambiguous places.** `Clifton` returns Clifton in Bristol, Nottingham, York and more; `Camden Town` returns the London region first, then the station and Camden Town
  • Network accessline 542
    - **Ambiguous places.** `Clifton` returns Clifton in Bristol, Nottingham, York and more; `Camden Town` returns the London region first, then the station and Camden Town in Gosport. `pick_location()` takes the top-ranked match whose name sta
  • Network accessline 543
    - **Pagination cap.** `pagination.total` never exceeded 42 pages. Page 42 (`index=984`) has no `pagination.next` even when `resultCount` is 3,748, which is why `scrape()` compares `resultCount` with 1,008 to tell the cap from a real last pa
  • Network accessline 556
    - `https://www.rightmove.co.uk/typeAhead/uknostreet/...` (older lookup path) returned the "We couldn't find the place you were looking for" HTML.

agent-workspace/domain-skills/rotten-tomatoes/scraping.md

  • Network accessline 25
    BASE = "https://www.rottentomatoes.com" # No User-Agent override: urllib sends its own truthful "Python-urllib/3.x", which got HTTP 200 on every URL below.
  • Network accessline 46
    for i in range(tries):         try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HDRS), timeout=timeout) as r:
  • Network accessline 47
    try:             with urllib.request.urlopen(urllib.request.Request(url, headers=HDRS), timeout=timeout) as r:                 data = r.read()
  • Network accessline 48
    with urllib.request.urlopen(urllib.request.Request(url, headers=HDRS), timeout=timeout) as r:
  • Network accessline 260
    60 titles, 60 unique urls, complete list: False stopped at max_pages=2; the list has more pages {"ems_id": "5b44daa8-5b70-3a2b-b009-0052edcfc114", "title": "Tenzing", "url": "https://www.rottentomatoes.com/m/tenzing", "type": "Movie", "toma
  • Network accessline 261
    stopped at max_pages=2; the list has more pages {"ems_id": "5b44daa8-5b70-3a2b-b009-0052edcfc114", "title": "Tenzing", "url": "https://www.rottentomatoes.com/m/tenzing", "type": "Movie", "tomatometer": 98, "certified_fresh": true, "popcornm
  • Network accessline 262
    {"ems_id": "5b44daa8-5b70-3a2b-b009-0052edcfc114", "title": "Tenzing", "url": "https://www.rottentomatoes.com/m/tenzing", "type": "Movie", "tomatometer": 98, "certified_fresh": true, "popcornmeter": 91, "release_text": "Streaming Oct 16, 20
  • Network accessline 265
    ... enriched 5 of 5 | failed: [] {"url": "https://www.rottentomatoes.com/m/oppenheimer_2023", "type": "Movie", "title": "Oppenheimer", "tomatometer": 93, "tomatometer_reviews": 510, "tomatometer_avg": "8.60", "certified_fresh": true, "top_c
  • Network accessline 266
    enriched 5 of 5 | failed: [] {"url": "https://www.rottentomatoes.com/m/oppenheimer_2023", "type": "Movie", "title": "Oppenheimer", "tomatometer": 93, "tomatometer_reviews": 510, "tomatometer_avg": "8.60", "certified_fresh": true, "top_criti
  • Network accessline 267
    {"url": "https://www.rottentomatoes.com/m/oppenheimer_2023", "type": "Movie", "title": "Oppenheimer", "tomatometer": 93, "tomatometer_reviews": 510, "tomatometer_avg": "8.60", "certified_fresh": true, "top_critics_score": 95, "top_critics_r
  • Network accessline 268
    {"url": "https://www.rottentomatoes.com/tv/the_bear", "type": "TVSeries", "title": "The Bear", "tomatometer": 93, "tomatometer_reviews": 469, "tomatometer_avg": "8.30", "certified_fresh": false, "top_critics_score": 93, "top_critics_reviews
  • Network accessline 269
    {"url": "https://www.rottentomatoes.com/tv/the_bear/s05", "type": "TVSeason", "title": "Season 5 – The Bear", "tomatometer": 96, "tomatometer_reviews": 83, "tomatometer_avg": "8.10", "certified_fresh": true, "top_critics_score": 97, "top_cr
  • Network accessline 354
    # Title page: read the embedded JSON from the DOM open_page("https://www.rottentomatoes.com/m/oppenheimer_2023", "#media-scorecard-json", first=True)
  • Network accessline 355
    open_page("https://www.rottentomatoes.com/m/oppenheimer_2023", "#media-scorecard-json", first=True)
  • Network accessline 390
    open_page("https://www.rottentomatoes.com/browse/movies_in_theaters/sort:popular", TILE)
  • Network accessline 426
    {"url": "https://www.rottentomatoes.com/m/oppenheimer_2023", "title": "Oppenheimer (2023)", "tomatometer": "93", "reviews": 510, "popcornmeter": "91", "audience": "10,000+ Verified Ratings", "rating": "R", "genres": ["Biography", "History",
  • Network accessline 430
    after Load more: 88 tiles stopped at MAX_CLICKS=2; list not exhausted rows: 88 | url now: https://www.rottentomatoes.com/browse/movies_in_theaters/sort:popular?page=3
  • Network accessline 431
    stopped at MAX_CLICKS=2; list not exhausted rows: 88 | url now: https://www.rottentomatoes.com/browse/movies_in_theaters/sort:popular?page=3 {'title': 'You Can See Everything', 'url': 'https://www.rottentomatoes.com/m/you_can_see_everything
  • Network accessline 432
    rows: 88 | url now: https://www.rottentomatoes.com/browse/movies_in_theaters/sort:popular?page=3
  • Network accessline 433
    {'title': 'You Can See Everything', 'url': 'https://www.rottentomatoes.com/m/you_can_see_everything', 'tomatometer': '98%', 'popcornmeter': '97%', 'date': 'Opened Oct 16, 2026'}
  • Network accessline 440
    | Key | Source | Example / note | |---|---|---| | url | final URL after redirects | `"https://www.rottentomatoes.com/m/oppenheimer_2023"` |
  • Network accessline 441
    |---|---|---| | url | final URL after redirects | `"https://www.rottentomatoes.com/m/oppenheimer_2023"` | | type | JSON-LD `@type` | `"Movie"`, `"TVSeries"`, `"TVSeason"` |
  • Network accessline 442
    | url | final URL after redirects | `"https://www.rottentomatoes.com/m/oppenheimer_2023"` |
  • Network accessline 483
    - **Confirm the page before reading it.** Right after `goto_url` from the title page to a browse page, `location.href` was already the new URL but `readyState` was `loading`, then `interactive`; `wait_for_load()` alone only checks `readySta
  • Network accessline 484
    - **Browser call timeouts.** A slow `cdp` round trip raises a `TimeoutError` subclass, but `js` re-raises a timed-out `Runtime.evaluate` as `RuntimeError("Runtime.evaluate timed out; ...")`, so `except TimeoutError` alone misses it. `is_har
  • Network accessline 485
    - **Region redirects.** Bare `https://rottentomatoes.com/` redirects to `https://www.rottentomatoes.com/`. Title, browse and `/cnapi/` URLs returned HTTP 200 with no redirect from both vantage points used, but both were in the US (the site'

agent-workspace/domain-skills/sec-edgar/scraping.md

  • Network accessline 3
    `https://www.sec.gov` / `https://data.sec.gov` / `https://efts.sec.gov` — all public data, no auth required. Every workflow here is pure `http_get` — no browser needed.
  • Network accessline 20
    import json UA = {"User-Agent": "browser-harness research@example.com"} tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA))
  • Network accessline 21
    UA = {"User-Agent": "browser-harness research@example.com"} tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA)) # 10,391 public companies, ~50KB, always fresh
  • Network accessline 22
    tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA))
  • Network accessline 39
    import json UA = {"User-Agent": "browser-harness research@example.com"} tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA))
  • Network accessline 41
    tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA))
  • Network accessline 56
    UA = {"User-Agent": "browser-harness research@example.com"} cik = "0000320193"  # Apple - always zero-pad to 10 digits data = json.loads(http_get(f"https://data.sec.gov/submissions/CIK{cik}.json", headers=UA))
  • Network accessline 58
    data = json.loads(http_get(f"https://data.sec.gov/submissions/CIK{cik}.json", headers=UA))
  • Network accessline 93
    accn_nodash = accn.replace("-", "") url = f"https://www.sec.gov/Archives/edgar/data/{cik}/{accn_nodash}/{doc}"
  • Network accessline 94
    url = f"https://www.sec.gov/Archives/edgar/data/{cik}/{accn_nodash}/{doc}"
  • Network accessline 95
    # https://www.sec.gov/Archives/edgar/data/320193/000032019325000079/aapl-20250927.htm
  • Network accessline 108
    # companyconcept: one metric, all reported values (quarterly + annual) data = json.loads(http_get(     f"https://data.sec.gov/api/xbrl/companyconcept/CIK{cik_padded}/us-gaap/Assets.json",
  • Network accessline 109
    data = json.loads(http_get(     f"https://data.sec.gov/api/xbrl/companyconcept/CIK{cik_padded}/us-gaap/Assets.json",     headers=UA
  • Network accessline 110
    f"https://data.sec.gov/api/xbrl/companyconcept/CIK{cik_padded}/us-gaap/Assets.json",
  • Network accessline 144
    # companyfacts: all reported XBRL concepts in one ~5MB call data = json.loads(http_get(     "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json",
  • Network accessline 145
    data = json.loads(http_get(     "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json",     headers=UA
  • Network accessline 146
    "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json",
  • Network accessline 201
    # Top companies by annual revenue (2024) data = json.loads(http_get(     "https://data.sec.gov/api/xbrl/frames/us-gaap/RevenueFromContractWithCustomerExcludingAssessedTax/USD/CY2024.json",
  • Network accessline 202
    data = json.loads(http_get(     "https://data.sec.gov/api/xbrl/frames/us-gaap/RevenueFromContractWithCustomerExcludingAssessedTax/USD/CY2024.json",     headers=UA
  • Network accessline 203
    "https://data.sec.gov/api/xbrl/frames/us-gaap/RevenueFromContractWithCustomerExcludingAssessedTax/USD/CY2024.json",
  • Network accessline 216
    # Total assets snapshot end of 2024 (balance sheet = instantaneous) data2 = json.loads(http_get(     "https://data.sec.gov/api/xbrl/frames/us-gaap/Assets/USD/CY2024Q4I.json",
  • Network accessline 217
    data2 = json.loads(http_get(     "https://data.sec.gov/api/xbrl/frames/us-gaap/Assets/USD/CY2024Q4I.json",     headers=UA
  • Network accessline 218
    "https://data.sec.gov/api/xbrl/frames/us-gaap/Assets/USD/CY2024Q4I.json",
  • Network accessline 232
    #         startdt, enddt, size (max 100), from (offset for pagination) url = (     "https://efts.sec.gov/LATEST/search-index"
  • Network accessline 233
    url = (     "https://efts.sec.gov/LATEST/search-index"     "?q=%22climate+risk%22"
  • Network accessline 234
    "https://efts.sec.gov/LATEST/search-index"
  • Network accessline 275
    # Best method: company_tickers.json (fastest, all tickers) tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA))
  • Network accessline 276
    tickers = json.loads(http_get("https://www.sec.gov/files/company_tickers.json", headers=UA))
  • Network accessline 280
    # Alternative: full-text search aggregations (finds CIK from company name) data = json.loads(http_get(     "https://efts.sec.gov/LATEST/search-index?q=%22microsoft+corporation%22&forms=10-K",
  • Network accessline 281
    data = json.loads(http_get(     "https://efts.sec.gov/LATEST/search-index?q=%22microsoft+corporation%22&forms=10-K",     headers=UA
  • Network accessline 282
    "https://efts.sec.gov/LATEST/search-index?q=%22microsoft+corporation%22&forms=10-K",
  • Network accessline 301
    def get_company_meta(ticker_cik):     ticker, cik = ticker_cik     subs = json.loads(http_get(f"https://data.sec.gov/submissions/CIK{cik}.json", headers=UA))
  • Network accessline 302
    ticker, cik = ticker_cik     subs = json.loads(http_get(f"https://data.sec.gov/submissions/CIK{cik}.json", headers=UA))     return {"ticker": ticker, "name": subs['name'], "sic": subs['sic']}
  • Network accessline 303
    subs = json.loads(http_get(f"https://data.sec.gov/submissions/CIK{cik}.json", headers=UA))

agent-workspace/domain-skills/sephora/scraping.md

  • Network accessline 22
    LIST_URL = "https://www.sephora.com/shop/face-serum"   # a /shop/<category> or /brand/<brand> page
  • Network accessline 26
    if not re.fullmatch(r"https://www\.sephora\.com/(shop|brand)/[a-z0-9-]+", LIST_URL):
  • Network accessline 27
    raise SystemExit("LIST_URL must be https://www.sephora.com/shop/<slug> or /brand/<slug>, no query string")
  • Network accessline 63
    "variation_type": p.get("variationType"),        # "Size", "Color", ...         "sponsored": bool(p.get("sponsored")),         "url": "https://www.sephora.com" + p["targetUrl"] if p.get("targetUrl") else None,
  • Network accessline 64
    "sponsored": bool(p.get("sponsored")),         "url": "https://www.sephora.com" + p["targetUrl"] if p.get("targetUrl") else None,     }
  • Network accessline 65
    "url": "https://www.sephora.com" + p["targetUrl"] if p.get("targetUrl") else None,
  • Network accessline 70
    opened_tab = None   # set only if this block opened the tab; it never closes a tab it did not open href = js("location.href") or "" if not href.startswith("https://www.sephora.com/"):
  • Network accessline 71
    href = js("location.href") or "" if not href.startswith("https://www.sephora.com/"):     opened_tab = new_tab("https://www.sephora.com/")
  • Network accessline 72
    if not href.startswith("https://www.sephora.com/"):
  • Network accessline 73
    opened_tab = new_tab("https://www.sephora.com/")
  • Network accessline 140
    "variation_type": "Size",   "sponsored": false,   "url": "https://www.sephora.com/product/vinoperfect-brightening-dark-spot-serum-vitamin-c-alternative-P94421?skuId=2744423"
  • Network accessline 141
    "sponsored": false,   "url": "https://www.sephora.com/product/vinoperfect-brightening-dark-spot-serum-vitamin-c-alternative-P94421?skuId=2744423"  },
  • Network accessline 142
    "url": "https://www.sephora.com/product/vinoperfect-brightening-dark-spot-serum-vitamin-c-alternative-P94421?skuId=2744423"
  • Network accessline 149
    The `status:` line says whether the walk is complete; with the default `MAX_PAGES = 3` it is `PARTIAL`, so never treat those rows as the whole category. With `MAX_PAGES = 20` the same category walked all 9 pages (`?currentPage=2` to `?curre
  • Network accessline 158
    PRODUCT_URL = "https://www.sephora.com/product/studio-fix-powder-plus-foundation-24hr-oil-control-blur-matte-finish-12hr-buildable-coverage-P516457"
  • Network accessline 161
    PRODUCT_URL = PRODUCT_URL.split("?")[0].split("#")[0]   # ?skuId=... from listing URLs is optional m = re.fullmatch(r"https://www\.sephora\.com/product/[^/?#]*?(P\d+)", PRODUCT_URL)
  • Network accessline 162
    m = re.fullmatch(r"https://www\.sephora\.com/product/[^/?#]*?(P\d+)", PRODUCT_URL)
  • Network accessline 163
    if not m:     raise SystemExit("PRODUCT_URL must look like https://www.sephora.com/product/<slug>-P<digits>") PRODUCT_ID = m.group(1)
  • Network accessline 164
    raise SystemExit("PRODUCT_URL must look like https://www.sephora.com/product/<slug>-P<digits>")
  • Network accessline 171
    opened_tab = None   # set only if this block opened the tab; it never closes a tab it did not open href = js("location.href") or "" if not href.startswith("https://www.sephora.com/"):
  • Network accessline 172
    href = js("location.href") or "" if not href.startswith("https://www.sephora.com/"):     opened_tab = new_tab("https://www.sephora.com/")
  • Network accessline 173
    if not href.startswith("https://www.sephora.com/"):
  • Network accessline 174
    opened_tab = new_tab("https://www.sephora.com/")
  • Network accessline 233
    "availability": (offers.get(s.get("skuId")) or {}).get("availability"),         "image": (s.get("skuImages") or {}).get("imageUrl"),         "url": "https://www.sephora.com" + s["targetUrl"] if s.get("targetUrl") else None,
  • Network accessline 234
    "image": (s.get("skuImages") or {}).get("imageUrl"),         "url": "https://www.sephora.com" + s["targetUrl"] if s.get("targetUrl") else None,     })
  • Network accessline 235
    "url": "https://www.sephora.com" + s["targetUrl"] if s.get("targetUrl") else None,
  • Network accessline 279
    "ingredients": "Synthetic Fluorphlogopite, Magnesium Potassium Fluorosilicate, Boron Nitride, ...",  "how_to_use": "Suggested Usage: -Apply powder to prepped skin. ...",  "url": "https://www.sephora.com/product/studio-fix-powder-plus-founda
  • Network accessline 280
    "how_to_use": "Suggested Usage: -Apply powder to prepped skin. ...",  "url": "https://www.sephora.com/product/studio-fix-powder-plus-foundation-24hr-oil-control-blur-matte-finish-12hr-buildable-coverage-P516457",  "variant_count": 71,
  • Network accessline 281
    "url": "https://www.sephora.com/product/studio-fix-powder-plus-foundation-24hr-oil-control-blur-matte-finish-12hr-buildable-coverage-P516457",
  • Network accessline 291
    "few_left": false,    "availability": "InStock",    "image": "https://www.sephora.com/productimages/sku/s3018215-main-zoom.jpg",
  • Network accessline 292
    "availability": "InStock",    "image": "https://www.sephora.com/productimages/sku/s3018215-main-zoom.jpg",    "url": "https://www.sephora.com/product/studio-fix-powder-plus-foundation-24hr-oil-control-blur-matte-finish-12hr-buildable-covera
  • Network accessline 293
    "image": "https://www.sephora.com/productimages/sku/s3018215-main-zoom.jpg",
  • Network accessline 294
    "url": "https://www.sephora.com/product/studio-fix-powder-plus-foundation-24hr-oil-control-blur-matte-finish-12hr-buildable-coverage-P516457?skuId=3018215"
  • Network accessline 320
    | Sponsored | `sponsored` | boolean; `false` on all products seen (Face Serums pages 1 to 3, Foundation page 1, The Ordinary) | | URL | `targetUrl` | relative `/product/<slug>-P<id>?skuId=<sku>` | | Image | `heroImage` | `https://www.sephor
  • Network accessline 321
    | URL | `targetUrl` | relative `/product/<slug>-P<id>?skuId=<sku>` | | Image | `heroImage` | `https://www.sephora.com/productimages/sku/s<sku>-main-zoom.jpg?imwidth=270...` | | Flags | `currentSku.isNew`, `isBestseller`, `isSephoraExclusive
  • Network accessline 322
    | Image | `heroImage` | `https://www.sephora.com/productimages/sku/s<sku>-main-zoom.jpg?imwidth=270...` |
  • Network accessline 338
    | Variants | `regularChildSkus[]` | 71 for P516457 (includes the default SKU); 1 for a single-size serum | | Variant fields | `skuId`, `variationValue`, `variationDesc`, `size`, `listPrice`, `isOutOfStock`, `isOnlyFewLeft`, `skuImages.image
  • Network accessline 340
    | Variant offer | JSON-LD `ProductGroup.hasVariant[].offers` | `price` `"39.00"`, `priceCurrency` `"USD"`, `availability` `https://schema.org/InStock`; matched 71 of 71 SKUs by `sku` |

agent-workspace/domain-skills/shopify-admin/knowledge-base.md

  • Network accessline 8
    https://admin.shopify.com/store/<store-handle>/apps/shopify-knowledge-base/app

agent-workspace/domain-skills/shopify-storefronts/scraping.md

  • Network accessline 12
    - `/products/<handle>.js` adds fields the list endpoint lacks: prices in cents, `barcode`, `inventory_management`, `inventory_policy`, and on some stores `inventory_quantity`. - Headless Shopify stores (Hydrogen/Oxygen, Next.js) do not serv
  • Network accessline 14
    - Browser fallback: open the storefront and call `fetch('/products.json?...')` from the page (same origin). On allbirds.com this returned the same 250/211/0 pages as plain HTTP.
  • Network accessline 37
    STORE = "https://www.deathwishcoffee.com"   # any Shopify storefront origin, no trailing slash
  • Network accessline 62
    if attempt:             time.sleep(delay)         req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json", "Accept-Encoding": "gzip"})
  • Network accessline 63
    time.sleep(delay)         req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json", "Accept-Encoding": "gzip"})         try:
  • Network accessline 64
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json", "Accept-Encoding": "gzip"})
  • Network accessline 65
    try:             with urllib.request.urlopen(req, timeout=30) as r:                 data = r.read()
  • Network accessline 66
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 152
    "available": true,  "grams": 191,  "image": "https://cdn.shopify.com/s/files/1/0271/7209/files/DeathWishCoffee_October26_Product_Silipint_SoloCup_Front_Web.jpg?v=1792676155",
  • Network accessline 153
    "grams": 191,  "image": "https://cdn.shopify.com/s/files/1/0271/7209/files/DeathWishCoffee_October26_Product_Silipint_SoloCup_Front_Web.jpg?v=1792676155",  "all_images": [...],
  • Network accessline 154
    "image": "https://cdn.shopify.com/s/files/1/0271/7209/files/DeathWishCoffee_October26_Product_Silipint_SoloCup_Front_Web.jpg?v=1792676155",
  • Network accessline 160
    Same code against `https://www.allbirds.com` printed `page 1: 250`, `page 2: 211`, then `461 products, 5288 variants`. Each 250-product page took 0.2-1.5 s and was 0.6-4.5 MB.
  • Network accessline 169
    STORE = "https://colourpop.com"
  • Network accessline 172
    def get(url):     req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json", "Accept-Encoding": "gzip"})
  • Network accessline 173
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": "application/json", "Accept-Encoding": "gzip"})
  • Network accessline 174
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 195
    Colour Me Merry | ColourPop | Advent Calendar 2026 | from 99.0 to 99.0   42754994372690 Kit-ColourMeMerry 99.0 available qty 3750 deny barcode FG007713 images: ['https://cdn.shopify.com/s/files/1/1338/0845/files/Kit-ColourMeMerry-Hero.jpg?v
  • Network accessline 197
    images: ['https://cdn.shopify.com/s/files/1/1338/0845/files/Kit-ColourMeMerry-Hero.jpg?v=1792618081', ...]
  • Network accessline 209
    STORE = "https://kith.com"
  • Network accessline 213
    def get(url, accept="application/xml"):     req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": accept, "Accept-Encoding": "gzip"})
  • Network accessline 214
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept": accept, "Accept-Encoding": "gzip"})
  • Network accessline 215
    with urllib.request.urlopen(req, timeout=30) as r:
  • Network accessline 250
    STORE = "https://www.allbirds.com"
  • Network accessline 254
    (async (page) => {   let r;   try { r = await fetch('/products.json?limit=250&page=' + page, {headers: {Accept: 'application/json'}}); }
  • Network accessline 255
    let r;   try { r = await fetch('/products.json?limit=250&page=' + page, {headers: {Accept: 'application/json'}}); }   catch (e) { return JSON.stringify({status: 0, rows: null}); }   // network error
  • Network accessline 256
    try { r = await fetch('/products.json?limit=250&page=' + page, {headers: {Accept: 'application/json'}}); }
  • Network accessline 315
    STORE = "https://www.gymshark.com"
  • Network accessline 381
    gymshark-fit-seamless-cropped-leggings-smokey-grey -> 5 variants gymshark-1-3-litre-water-bottle-black -> 1 variants {'title': 'eGift Card', 'brand': 'Gymshark | We Do Gym', 'group_id': '6453246788', 'variant_name': 'eGift Card', 'sku': 'GS
  • Network accessline 383
    {'title': 'eGift Card', 'brand': 'Gymshark | We Do Gym', 'group_id': '6453246788', 'variant_name': 'eGift Card', 'sku': 'GSGFTCRD-10', 'size': '10.00', 'color': None, 'price': 10, 'currency': 'USD', 'availability': 'InStock', 'image': 'http
  • Network accessline 386
    With `STORE = "https://www.fashionnova.com"` the same block printed `1 product sitemap(s), 37840 product URLs` and rows like `{'title': '00 Inferno Layered Mesh Jersey', 'brand': 'Fashion Nova', 'group_id': 'CLML508F', 'sku': 'CLML508F_Oliv
  • Network accessline 402
    | `body_html` | `<p>Sun on your feet...` | description HTML | | `options` | `[{"name":"Size","position":1,"values":["5","6",...]}]` | single-variant products show `Title` / `Default Title` | | `images[]` | `{id, src, width, height, position
  • Network accessline 403
    | `options` | `[{"name":"Size","position":1,"values":["5","6",...]}]` | single-variant products show `Title` / `Default Title` | | `images[]` | `{id, src, width, height, position, variant_ids}` | `src` is absolute `https://cdn.shopify.com/.
  • Network accessline 404
    | `images[]` | `{id, src, width, height, position, variant_ids}` | `src` is absolute `https://cdn.shopify.com/...` |
  • Network accessline 435
    - `/products.json` on headless stores: fashionnova.com 404 (Hydrogen/Oxygen), gymshark.com 403 from CloudFront. The in-browser `fetch('/products.json')` returned the same 404/403, so the browser is not a workaround there; use JSON-LD.

agent-workspace/domain-skills/slack/files.md

  • Network accessline 22
    so `files.list?user=<USERID>` can come back empty for the file you're after. Use   `search.files?query=<filename>` to resolve real per-file IDs. - Raw bytes live at `https://files.slack.com/files-pri/<TEAMID>-<FILEID>/<name>` and need
  • Network accessline 23
    `search.files?query=<filename>` to resolve real per-file IDs. - Raw bytes live at `https://files.slack.com/files-pri/<TEAMID>-<FILEID>/<name>` and need   cookie auth.
  • Network accessline 24
    - Raw bytes live at `https://files.slack.com/files-pri/<TEAMID>-<FILEID>/<name>` and need

agent-workspace/domain-skills/smartlead/mailbox-warmup.md

  • Network accessline 5
    - Application: `https://app.smartlead.ai/`.

agent-workspace/domain-skills/sofascore/scraping.md

  • Network accessline 25
    BASE = "https://www.sofascore.com"
  • Possible obfuscationline 34
    return json.loads(base64.b64decode(b["body"]) if b.get("base64Encoded") else b["body"])

agent-workspace/domain-skills/soundcloud/scraping.md

  • Network accessline 10
    `https://soundcloud.com/oembed?url=<resource_url>&format=json`
  • Network accessline 21
    Works for:       - https://soundcloud.com/{user}/{track-slug}
  • Network accessline 22
    - https://soundcloud.com/{user}/{track-slug}
  • Network accessline 23
    - https://soundcloud.com/{user}/sets/{playlist-slug}
  • Network accessline 24
    - https://soundcloud.com/{user}
  • Network accessline 25
    """     url = f"https://soundcloud.com/oembed?url={resource_url}&format=json"     return json.loads(http_get(url))
  • Network accessline 26
    url = f"https://soundcloud.com/oembed?url={resource_url}&format=json"
  • Network accessline 29
    # Track track = soundcloud_oembed("https://soundcloud.com/forss/flickermood")
  • Network accessline 30
    track = soundcloud_oembed("https://soundcloud.com/forss/flickermood")
  • Network accessline 33
    #   "type": "rich", #   "provider_name": "SoundCloud", #   "provider_url": "https://soundcloud.com",
  • Network accessline 34
    #   "provider_name": "SoundCloud", #   "provider_url": "https://soundcloud.com", #   "height": 400,
  • Network accessline 35
    #   "provider_url": "https://soundcloud.com",
  • Network accessline 38
    #   "title": "Flickermood by Forss", #   "description": "From the Soulhack album...", #   "thumbnail_url": "https://i1.sndcdn.com/artworks-000067273316-smsiqx-t500x500.jpg",
  • Network accessline 39
    #   "description": "From the Soulhack album...", #   "thumbnail_url": "https://i1.sndcdn.com/artworks-000067273316-smsiqx-t500x500.jpg", #   "html": "<iframe width=\"100%\" height=\"400\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.
  • Network accessline 40
    #   "thumbnail_url": "https://i1.sndcdn.com/artworks-000067273316-smsiqx-t500x500.jpg",
  • Network accessline 41
    #   "html": "<iframe width=\"100%\" height=\"400\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?visual=true&url=...\">",
  • Network accessline 42
    #   "author_name": "Forss", #   "author_url": "https://soundcloud.com/forss" # }
  • Network accessline 43
    #   "author_url": "https://soundcloud.com/forss"
  • Network accessline 46
    # Playlist/set pl = soundcloud_oembed("https://soundcloud.com/forss/sets/soulhack")
  • Network accessline 47
    pl = soundcloud_oembed("https://soundcloud.com/forss/sets/soulhack")
  • Network accessline 50
    # User profile user = soundcloud_oembed("https://soundcloud.com/forss")
  • Network accessline 51
    user = soundcloud_oembed("https://soundcloud.com/forss")
  • Network accessline 93
    # Track page — hydration key is 'sound' track = get_hydration_by_type("https://soundcloud.com/forss/flickermood", "sound")
  • Network accessline 94
    track = get_hydration_by_type("https://soundcloud.com/forss/flickermood", "sound")
  • Network accessline 100
    # track['genre']          = "Electronic" # track['created_at']     = "2007-09-22T14:45:46Z" # track['artwork_url']    = "https://i1.sndcdn.com/artworks-000067273316-smsiqx-large.jpg"
  • Network accessline 101
    # track['created_at']     = "2007-09-22T14:45:46Z" # track['artwork_url']    = "https://i1.sndcdn.com/artworks-000067273316-smsiqx-large.jpg" # track['waveform_url']   = "https://wave.sndcdn.com/cWHNerOLlkUq_m.json"
  • Network accessline 102
    # track['artwork_url']    = "https://i1.sndcdn.com/artworks-000067273316-smsiqx-large.jpg"
  • Network accessline 103
    # track['waveform_url']   = "https://wave.sndcdn.com/cWHNerOLlkUq_m.json"
  • Network accessline 112
    # User page — hydration key is 'user' user = get_hydration_by_type("https://soundcloud.com/forss", "user")
  • Network accessline 113
    user = get_hydration_by_type("https://soundcloud.com/forss", "user")
  • Network accessline 126
    # Playlist/set page — hydration key is 'playlist' playlist = get_hydration_by_type("https://soundcloud.com/forss/sets/soulhack", "playlist")
  • Network accessline 127
    playlist = get_hydration_by_type("https://soundcloud.com/forss/sets/soulhack", "playlist")
  • Network accessline 158
    def get_client_id(page_url="https://soundcloud.com"):
  • Network accessline 173
    params['client_id'] = CLIENT_ID     qs = "&".join(f"{k}={v}" for k, v in params.items())     return json.loads(http_get(f"https://api-v2.soundcloud.com/{path}?{qs}"))
  • Network accessline 175
    return json.loads(http_get(f"https://api-v2.soundcloud.com/{path}?{qs}"))
  • Network accessline 181
    # Resolve a permalink URL to get its resource with full metadata track = sc_api("resolve", url="https://soundcloud.com/forss/flickermood")
  • Network accessline 182
    track = sc_api("resolve", url="https://soundcloud.com/forss/flickermood")
  • Network accessline 185
    user = sc_api("resolve", url="https://soundcloud.com/forss")
  • Network accessline 265
    # Waveform URL comes from track['waveform_url'] waveform_url = "https://wave.sndcdn.com/cWHNerOLlkUq_m.json"
  • Network accessline 266
    waveform_url = "https://wave.sndcdn.com/cWHNerOLlkUq_m.json"
  • Network accessline 296
    download_count   int artwork_url      str     e.g. .../artworks-...-large.jpg (replace 'large' with 't500x500' for 500px) waveform_url     str     https://wave.sndcdn.com/....json
  • Network accessline 297
    artwork_url      str     e.g. .../artworks-...-large.jpg (replace 'large' with 't500x500' for 500px) waveform_url     str     https://wave.sndcdn.com/....json permalink        str     Slug (e.g. "flickermood")
  • Network accessline 298
    waveform_url     str     https://wave.sndcdn.com/....json

agent-workspace/domain-skills/spotify/scraping.md

  • Network accessline 10
    `https://open.spotify.com/oembed?url=<resource_url>`
  • Network accessline 22
    resource_id:   Spotify ID (22-char alphanumeric)     """     resource_url = f"https://open.spotify.com/{resource_type}/{resource_id}"
  • Network accessline 23
    """     resource_url = f"https://open.spotify.com/{resource_type}/{resource_id}"     url = f"https://open.spotify.com/oembed?url={resource_url}"
  • Network accessline 24
    resource_url = f"https://open.spotify.com/{resource_type}/{resource_id}"
  • Network accessline 25
    url = f"https://open.spotify.com/oembed?url={resource_url}"
  • Network accessline 31
    # { #   "title":           "Never Gonna Give You Up", #   "thumbnail_url":   "https://image-cdn-ak.spotifycdn.com/image/ab67616100005174...",
  • Network accessline 32
    #   "title":           "Never Gonna Give You Up", #   "thumbnail_url":   "https://image-cdn-ak.spotifycdn.com/image/ab67616100005174...", #   "thumbnail_width": 320,
  • Network accessline 33
    #   "thumbnail_url":   "https://image-cdn-ak.spotifycdn.com/image/ab67616100005174...",
  • Network accessline 35
    #   "thumbnail_height": 320, #   "type":            "rich", #   "html":            "<iframe ...src=\"https://open.spotify.com/embed/track/4PTG3Z6...\"...>",
  • Network accessline 36
    #   "type":            "rich", #   "html":            "<iframe ...src=\"https://open.spotify.com/embed/track/4PTG3Z6...\"...>", #   "iframe_url":      "https://open.spotify.com/embed/track/4PTG3Z6ehGkBFwjybzWkR8?utm_source=oembed",
  • Network accessline 37
    #   "html":            "<iframe ...src=\"https://open.spotify.com/embed/track/4PTG3Z6...\"...>",
  • Network accessline 38
    #   "iframe_url":      "https://open.spotify.com/embed/track/4PTG3Z6ehGkBFwjybzWkR8?utm_source=oembed",
  • Network accessline 41
    #   "version":         "1.0", #   "provider_name":   "Spotify", #   "provider_url":    "https://spotify.com"
  • Network accessline 42
    #   "provider_name":   "Spotify", #   "provider_url":    "https://spotify.com" # }
  • Network accessline 43
    #   "provider_url":    "https://spotify.com"
  • Network accessline 72
    def fetch_oembed(tid):     url = f"https://open.spotify.com/oembed?url=https://open.spotify.com/track/{tid}"
  • Network accessline 73
    url = f"https://open.spotify.com/oembed?url=https://open.spotify.com/track/{tid}"
  • Network accessline 96
    def scrape_track(track_id):     url = f"https://open.spotify.com/track/{track_id}"
  • Network accessline 97
    url = f"https://open.spotify.com/track/{track_id}"
  • Network accessline 133
    #   "title":         "Never Gonna Give You Up", #   "artist":        "Rick Astley", #   "artist_urls":   ["https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt"],
  • Network accessline 134
    #   "artist":        "Rick Astley", #   "artist_urls":   ["https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt"], #   "album_url":     "https://open.spotify.com/album/6eUW0wxWtzkFdaEFsTJto6",
  • Network accessline 135
    #   "artist_urls":   ["https://open.spotify.com/artist/0gxyHStUsqpMadRV0Di1Qt"],
  • Network accessline 136
    #   "album_url":     "https://open.spotify.com/album/6eUW0wxWtzkFdaEFsTJto6",
  • Network accessline 138
    #   "duration_s":    214, #   "release_date":  "1987-11-12", #   "cover_art":     "https://i.scdn.co/image/ab67616d0000b27315ebbedaacef61af244262a8",
  • Network accessline 139
    #   "release_date":  "1987-11-12", #   "cover_art":     "https://i.scdn.co/image/ab67616d0000b27315ebbedaacef61af244262a8", #   "audio_preview": "https://p.scdn.co/mp3-preview/b4c682084c3fd05538726d0a126b7e14b6e92c83",
  • Network accessline 140
    #   "cover_art":     "https://i.scdn.co/image/ab67616d0000b27315ebbedaacef61af244262a8",
  • Network accessline 141
    #   "audio_preview": "https://p.scdn.co/mp3-preview/b4c682084c3fd05538726d0a126b7e14b6e92c83",
  • Network accessline 142
    #   "spotify_url":   "https://open.spotify.com/track/4PTG3Z6ehGkBFwjybzWkR8",
  • Network accessline 150
    def scrape_artist(artist_id):     url = f"https://open.spotify.com/artist/{artist_id}"
  • Network accessline 151
    url = f"https://open.spotify.com/artist/{artist_id}"
  • Network accessline 172
    #   "name":              "Rick Astley", #   "monthly_listeners": "Artist · 6.7M monthly listeners.", #   "image":             "https://i.scdn.co/image/ab6761610000e5ebe834a63a0cfa3c0f57a9a434",
  • Network accessline 173
    #   "monthly_listeners": "Artist · 6.7M monthly listeners.", #   "image":             "https://i.scdn.co/image/ab6761610000e5ebe834a63a0cfa3c0f57a9a434", # }
  • Network accessline 174
    #   "image":             "https://i.scdn.co/image/ab6761610000e5ebe834a63a0cfa3c0f57a9a434",
  • Network accessline 182
    `https://open.spotify.com/embed/{type}/{id}` returns a small Next.js SSR page. Its `__NEXT_DATA__` script tag contains a fully-parsed entity object. This is the only no-auth route that returns track listings for albums, playlists, and artis
  • Network accessline 191
    Returns the entity dict from __NEXT_DATA__.     """     url = f"https://open.spotify.com/embed/{resource_type}/{resource_id}"
  • Network accessline 192
    """     url = f"https://open.spotify.com/embed/{resource_type}/{resource_id}"     html = http_get(url)
  • Network accessline 193
    url = f"https://open.spotify.com/embed/{resource_type}/{resource_id}"
  • Network accessline 209
    #   "isPlayable": True, #   "isExplicit": False, #   "audioPreview": {"url": "https://p.scdn.co/mp3-preview/b4c682..."},
  • Network accessline 210
    #   "isExplicit": False, #   "audioPreview": {"url": "https://p.scdn.co/mp3-preview/b4c682..."}, #   "visualIdentity": {
  • Network accessline 211
    #   "audioPreview": {"url": "https://p.scdn.co/mp3-preview/b4c682..."},
  • Network accessline 212
    #   "visualIdentity": { #     "image": [ #       {"url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d00001e02...", "maxWidth": 300, "maxHeight": 300},
  • Network accessline 213
    #     "image": [ #       {"url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d00001e02...", "maxWidth": 300, "maxHeight": 300}, #       {"url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d000048...", "maxWidth": 64,  "maxHeight
  • Network accessline 214
    #       {"url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d00001e02...", "maxWidth": 300, "maxHeight": 300},
  • Network accessline 215
    #       {"url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d000048...", "maxWidth": 64,  "maxHeight": 64},
  • Network accessline 216
    #       {"url": "https://image-cdn-fa.spotifycdn.com/image/ab67616d0000b27...", "maxWidth": 640, "maxHeight": 640},
  • Network accessline 228
    #   "duration":     107426, #   "isPlayable":   True, #   "audioPreview": {"url": "https://p.scdn.co/mp3-preview/d03c37..."},
  • Network accessline 229
    #   "isPlayable":   True, #   "audioPreview": {"url": "https://p.scdn.co/mp3-preview/d03c37..."}, #   "entityType":   "track"
  • Network accessline 230
    #   "audioPreview": {"url": "https://p.scdn.co/mp3-preview/d03c37..."},
  • Network accessline 251
    def get_embed_token(resource_type="track", resource_id="4PTG3Z6ehGkBFwjybzWkR8"):     """Extract the anonymous access token from an embed page."""     url = f"https://open.spotify.com/embed/{resource_type}/{resource_id}"
  • Network accessline 252
    """Extract the anonymous access token from an embed page."""     url = f"https://open.spotify.com/embed/{resource_type}/{resource_id}"     html = http_get(url)
  • Network accessline 253
    url = f"https://open.spotify.com/embed/{resource_type}/{resource_id}"
  • Access to secretsline 259
    [Credential-related source omitted]
  • Access to secretsline 266
    [Credential-related source omitted]
  • Network accessline 293
    goto_url("https://open.spotify.com/search")
  • Network accessline 307
    | Resource  | URL pattern                                    | ID format         | |-----------|------------------------------------------------|-------------------| | Track     | `https://open.spotify.com/track/{id}`          | 22-char alp
  • Network accessline 308
    |-----------|------------------------------------------------|-------------------| | Track     | `https://open.spotify.com/track/{id}`          | 22-char alphanum  | | Album     | `https://open.spotify.com/album/{id}`          | 22-char alp
  • Network accessline 309
    | Track     | `https://open.spotify.com/track/{id}`          | 22-char alphanum  |
  • Network accessline 310
    | Album     | `https://open.spotify.com/album/{id}`          | 22-char alphanum  |
  • Network accessline 311
    | Artist    | `https://open.spotify.com/artist/{id}`         | 22-char alphanum  |
  • Network accessline 312
    | Playlist  | `https://open.spotify.com/playlist/{id}`       | 22-char alphanum  |
  • Network accessline 313
    | oEmbed    | `https://open.spotify.com/oembed?url={resource_url}` | any of above |
  • Network accessline 314
    | Embed     | `https://open.spotify.com/embed/{type}/{id}`   | same ID           |
  • Network accessline 332
    - **Embed page for episodes**: The embed page SSR for episodes does not include `state.data.entity` in the expected structure — parse defensively. - **Anonymous token rate limiting**: The access token from embed pages is valid but severely 
  • Network accessline 333
    - **Anonymous token rate limiting**: The access token from embed pages is valid but severely rate-limited for `api.spotify.com/v1`. Observed `Retry-After: 79561` (~22 hours) after 2-3 rapid API calls. Use embed `__NEXT_DATA__` data instead 
  • Network accessline 334
    [Credential-related source omitted]
  • Access to secretsline 334
    [Credential-related source omitted]

agent-workspace/domain-skills/stackoverflow/scraping.md

  • Network accessline 3
    `https://stackoverflow.com` — all public read-only data is available via the Stack Exchange API v2.3. No auth, no browser required for any read operation. API is fast, returns gzip-compressed JSON, and works transparently with `http_get`.
  • Network accessline 40
    import json data = json.loads(http_get("https://api.stackexchange.com/2.3/info?site=stackoverflow"))
  • Network accessline 41
    data = json.loads(http_get("https://api.stackexchange.com/2.3/info?site=stackoverflow"))
  • Network accessline 74
    try:     data = json.loads(http_get("https://api.stackexchange.com/2.3/questions?site=stackoverflow&pagesize=1"))
  • Network accessline 75
    data = json.loads(http_get("https://api.stackexchange.com/2.3/questions?site=stackoverflow&pagesize=1"))
  • Network accessline 89
    # WITHOUT filter=withbody — body field is ABSENT data = json.loads(http_get("https://api.stackexchange.com/2.3/questions?order=desc&sort=votes&tagged=python&site=stackoverflow&pagesize=1"))
  • Network accessline 90
    data = json.loads(http_get("https://api.stackexchange.com/2.3/questions?order=desc&sort=votes&tagged=python&site=stackoverflow&pagesize=1"))
  • Network accessline 98
    # WITH filter=withbody — body field is PRESENT data = json.loads(http_get("https://api.stackexchange.com/2.3/questions?order=desc&sort=votes&tagged=python&site=stackoverflow&pagesize=1&filter=withbody"))
  • Network accessline 99
    data = json.loads(http_get("https://api.stackexchange.com/2.3/questions?order=desc&sort=votes&tagged=python&site=stackoverflow&pagesize=1&filter=withbody"))
  • Network accessline 101
    print("Has body:", 'body' in q)   # True print("Body preview:", q['body'][:60]) # '<p>What functionality does the <a href="https://do...'
  • Network accessline 103
    # '<p>What functionality does the <a href="https://do...'
  • Network accessline 120
    data = json.loads(http_get("https://api.stackexchange.com/2.3/questions/231767?site=stackoverflow&filter=withbody"))
  • Network accessline 152
    import json, html data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions"
  • Network accessline 153
    data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions"     "?order=desc&sort=votes&tagged=python&site=stackoverflow&pagesize=5&filter=withbody"
  • Network accessline 154
    "https://api.stackexchange.com/2.3/questions"
  • Network accessline 173
    import json data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767/answers"
  • Network accessline 174
    data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767/answers"     "?order=desc&sort=votes&site=stackoverflow&filter=withbody&pagesize=3"
  • Network accessline 175
    "https://api.stackexchange.com/2.3/questions/231767/answers"
  • Network accessline 194
    import json data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767;419163;394809"
  • Network accessline 195
    data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767;419163;394809"     "?site=stackoverflow&filter=withbody"
  • Network accessline 196
    "https://api.stackexchange.com/2.3/questions/231767;419163;394809"
  • Network accessline 214
    # search/advanced: keyword in body OR title, filtered by tag, sorted by relevance data = json.loads(http_get(     "https://api.stackexchange.com/2.3/search/advanced"
  • Network accessline 215
    data = json.loads(http_get(     "https://api.stackexchange.com/2.3/search/advanced"     "?q=asyncio+event+loop&tagged=python&site=stackoverflow&pagesize=5&order=desc&sort=relevance"
  • Network accessline 216
    "https://api.stackexchange.com/2.3/search/advanced"
  • Network accessline 224
    # search: title-only keyword search via intitle= data = json.loads(http_get(     "https://api.stackexchange.com/2.3/search"
  • Network accessline 225
    data = json.loads(http_get(     "https://api.stackexchange.com/2.3/search"     "?intitle=asyncio+event+loop&site=stackoverflow&pagesize=5&order=desc&sort=relevance"
  • Network accessline 226
    "https://api.stackexchange.com/2.3/search"
  • Network accessline 238
    # Basic user info user = json.loads(http_get("https://api.stackexchange.com/2.3/users/1?site=stackoverflow"))
  • Network accessline 239
    user = json.loads(http_get("https://api.stackexchange.com/2.3/users/1?site=stackoverflow"))
  • Network accessline 248
    # Timeline (badge, question, answer events) data = json.loads(http_get("https://api.stackexchange.com/2.3/users/1/timeline?site=stackoverflow&pagesize=5"))
  • Network accessline 249
    data = json.loads(http_get("https://api.stackexchange.com/2.3/users/1/timeline?site=stackoverflow&pagesize=5"))
  • Network accessline 253
    # User's top answers answers = json.loads(http_get("https://api.stackexchange.com/2.3/users/1/answers?site=stackoverflow&pagesize=5&order=desc&sort=votes"))
  • Network accessline 254
    answers = json.loads(http_get("https://api.stackexchange.com/2.3/users/1/answers?site=stackoverflow&pagesize=5&order=desc&sort=votes"))
  • Network accessline 258
    # User's questions questions = json.loads(http_get("https://api.stackexchange.com/2.3/users/1/questions?site=stackoverflow&pagesize=3&order=desc&sort=votes"))
  • Network accessline 259
    questions = json.loads(http_get("https://api.stackexchange.com/2.3/users/1/questions?site=stackoverflow&pagesize=3&order=desc&sort=votes"))
  • Network accessline 269
    import json data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767/comments"
  • Network accessline 270
    data = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767/comments"     "?site=stackoverflow&pagesize=5&order=desc&sort=creation&filter=withbody"
  • Network accessline 271
    "https://api.stackexchange.com/2.3/questions/231767/comments"
  • Network accessline 284
    import json related = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767/related?site=stackoverflow&pagesize=5"
  • Network accessline 285
    related = json.loads(http_get(     "https://api.stackexchange.com/2.3/questions/231767/related?site=stackoverflow&pagesize=5" ))
  • Network accessline 286
    "https://api.stackexchange.com/2.3/questions/231767/related?site=stackoverflow&pagesize=5"
  • Network accessline 297
    import json tags = json.loads(http_get("https://api.stackexchange.com/2.3/tags?order=desc&sort=popular&site=stackoverflow&pagesize=5"))
  • Network accessline 298
    tags = json.loads(http_get("https://api.stackexchange.com/2.3/tags?order=desc&sort=popular&site=stackoverflow&pagesize=5"))
  • Network accessline 328
    questions = fetch_all_pages(     "https://api.stackexchange.com/2.3/questions?order=desc&sort=votes"
  • Network accessline 329
    "https://api.stackexchange.com/2.3/questions?order=desc&sort=votes"
  • Network accessline 346
    def fetch_top_answer(qid):     data = json.loads(http_get(         f"https://api.stackexchange.com/2.3/questions/{qid}/answers"
  • Network accessline 347
    data = json.loads(http_get(         f"https://api.stackexchange.com/2.3/questions/{qid}/answers"         "?order=desc&sort=votes&site=stackoverflow&filter=withbody&pagesize=1"
  • Network accessline 348
    f"https://api.stackexchange.com/2.3/questions/{qid}/answers"
  • Network accessline 378
    import re, html as htmllib headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"} page = http_get("https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python", headers=headers
  • Network accessline 379
    headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"} page = http_get("https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python", headers=headers) print("HTML length:", len
  • Network accessline 380
    page = http_get("https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python", headers=headers)

agent-workspace/domain-skills/steam/scraping.md

  • Network accessline 18
    """     resp = http_get(         f"https://store.steampowered.com/api/appdetails?appids={appid}&cc={cc}"
  • Network accessline 19
    resp = http_get(         f"https://store.steampowered.com/api/appdetails?appids={appid}&cc={cc}"     )
  • Network accessline 20
    f"https://store.steampowered.com/api/appdetails?appids={appid}&cc={cc}"
  • Network accessline 35
    # game["about_the_game"]     -> HTML # game["detailed_description"]-> HTML # game["website"]            -> "https://www.thewitcher.com/witcher3"
  • Network accessline 36
    # game["detailed_description"]-> HTML # game["website"]            -> "https://www.thewitcher.com/witcher3" # game["header_image"]       -> URL to 460x215px header image
  • Network accessline 37
    # game["website"]            -> "https://www.thewitcher.com/witcher3"
  • Network accessline 43
    # game["publishers"]         -> ["CD PROJEKT RED"] # game["platforms"]          -> {"windows": True, "mac": False, "linux": False} # game["metacritic"]         -> {"score": 93, "url": "https://www.metacritic.com/..."}
  • Network accessline 44
    # game["platforms"]          -> {"windows": True, "mac": False, "linux": False} # game["metacritic"]         -> {"score": 93, "url": "https://www.metacritic.com/..."} # game["genres"]             -> [{"id": "3", "description": "RPG"}]
  • Network accessline 45
    # game["metacritic"]         -> {"score": 93, "url": "https://www.metacritic.com/..."}
  • Network accessline 125
    def fetch_game(appid, cc="US"):     resp = http_get(         f"https://store.steampowered.com/api/appdetails?appids={appid}&cc={cc}"
  • Network accessline 126
    resp = http_get(         f"https://store.steampowered.com/api/appdetails?appids={appid}&cc={cc}"     )
  • Network accessline 127
    f"https://store.steampowered.com/api/appdetails?appids={appid}&cc={cc}"
  • Network accessline 149
    ## Partial field fetch (filters=)
  • Network accessline 154
    # Price only (tiny response) resp = http_get("https://store.steampowered.com/api/appdetails?appids=292030&filters=price_overview")
  • Network accessline 155
    resp = http_get("https://store.steampowered.com/api/appdetails?appids=292030&filters=price_overview")
  • Network accessline 159
    # Basic metadata (no price, no media) resp = http_get("https://store.steampowered.com/api/appdetails?appids=292030&filters=basic")
  • Network accessline 160
    resp = http_get("https://store.steampowered.com/api/appdetails?appids=292030&filters=basic")
  • Network accessline 166
    # Multiple filters comma-separated resp = http_get("https://store.steampowered.com/api/appdetails?appids=292030&filters=screenshots,price_overview")
  • Network accessline 167
    resp = http_get("https://store.steampowered.com/api/appdetails?appids=292030&filters=screenshots,price_overview")
  • Network accessline 251
    GET https://store.steampowered.com/app/292030/
  • Network accessline 252
    -> 302 -> https://store.steampowered.com/agecheck/app/292030/
  • Network accessline 260
    def get_store_page(appid):     """Fetch game store HTML page, bypassing age gate."""     req = urllib.request.Request(
  • Network accessline 261
    """Fetch game store HTML page, bypassing age gate."""     req = urllib.request.Request(         f"https://store.steampowered.com/app/{appid}/",
  • Network accessline 262
    req = urllib.request.Request(
  • Network accessline 263
    f"https://store.steampowered.com/app/{appid}/",
  • Network accessline 267
    }     )     with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 268
    )     with urllib.request.urlopen(req, timeout=15) as r:         html = r.read().decode("utf-8", errors="replace")
  • Network accessline 269
    with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 293
    q = urllib.parse.quote(term)     resp = http_get(         f"https://store.steampowered.com/api/storesearch/?term={q}&l={lang}&cc={cc}"
  • Network accessline 294
    resp = http_get(         f"https://store.steampowered.com/api/storesearch/?term={q}&l={lang}&cc={cc}"     )
  • Network accessline 295
    f"https://store.steampowered.com/api/storesearch/?term={q}&l={lang}&cc={cc}"
  • Network accessline 302
    #   {"type": "app", "name": "The Witcher 3: Wild Hunt", "id": 292030, #    "price": {"currency": "USD", "initial": 3999, "final": 3999}, #    "tiny_image": "https://...", "metascore": "93",
  • Network accessline 303
    #    "price": {"currency": "USD", "initial": 3999, "final": 3999}, #    "tiny_image": "https://...", "metascore": "93", #    "platforms": {"windows": True, "mac": False, "linux": False},
  • Network accessline 304
    #    "tiny_image": "https://...", "metascore": "93",
  • Network accessline 341
    encoded_cursor = urllib.parse.quote(cursor)     resp = http_get(         f"https://store.steampowered.com/appreviews/{appid}"
  • Network accessline 342
    resp = http_get(         f"https://store.steampowered.com/appreviews/{appid}"         f"?json=1&num_per_page={num}&language={language}"
  • Network accessline 343
    f"https://store.steampowered.com/appreviews/{appid}"
  • Network accessline 418
    for _ in range(max_pages):         resp = http_get(             f"https://store.steampowered.com/appreviews/{appid}"
  • Network accessline 419
    resp = http_get(             f"https://store.steampowered.com/appreviews/{appid}"             f"?json=1&num_per_page={num_per_page}&language={language}"
  • Network accessline 420
    f"https://store.steampowered.com/appreviews/{appid}"             f"?json=1&num_per_page={num_per_page}&language={language}"             f"&filter=recent&cursor={urllib.parse.quote(cursor)}"
  • Network accessline 445
    data = json.loads(http_get("https://store.steampowered.com/api/featured/"))
  • Network accessline 472
    data = json.loads(http_get("https://store.steampowered.com/api/featuredcategories/"))
  • Network accessline 510
    def get_all_store_appids():     data = json.loads(http_get("https://store.steampowered.com/api/featuredcategories/"))
  • Network accessline 511
    data = json.loads(http_get("https://store.steampowered.com/api/featuredcategories/"))
  • Access to secretsline 557
    [Credential-related source omitted]

agent-workspace/domain-skills/stripe/account-sandboxes.md

  • Network accessline 5
    - The account's classic Test mode keeps the main account ID. Its current-account routes use `https://dashboard.stripe.com/test/...`. Account-specific links can include `/{account_id}/test/...`.
  • Network accessline 12
    1. Confirm the intended account in the account switcher and read its ID from account settings. 2. Open Test mode and its API keys page. Do not infer account identity from the URL alone. 3. Use the intended Test mode secret key for an authen
  • Network accessline 13
    [Credential-related source omitted]
  • Network accessline 14
    3. Use the intended Test mode secret key for an authenticated `GET https://api.stripe.com/v1/account` request.

agent-workspace/domain-skills/substack/scraping.md

  • Network accessline 30
    `GET https://{subdomain}.substack.com/api/v1/posts?limit=N&offset=N`
  • Network accessline 41
    Args:         publication_url: Base URL of the publication, e.g.                          'https://www.slowboring.com' or
  • Network accessline 42
    publication_url: Base URL of the publication, e.g.                          'https://www.slowboring.com' or                          'https://simonwillison.substack.com'
  • Network accessline 43
    'https://www.slowboring.com' or
  • Network accessline 44
    'https://simonwillison.substack.com'
  • Network accessline 71
    posts = substack_list_posts("https://www.slowboring.com", limit=10)
  • Network accessline 75
    #     "subtitle":  "Plus ties, Mamdani, the Obama legacy, and fundraising's diminishing returns", #     "slug":      "what-to-make-of-the-generic-ballot", #     "url":       "https://www.slowboring.com/p/what-to-make-of-the-generic-ballot",
  • Network accessline 76
    #     "slug":      "what-to-make-of-the-generic-ballot", #     "url":       "https://www.slowboring.com/p/what-to-make-of-the-generic-ballot", #     "post_date": "2026-04-24T10:03:26.581Z",
  • Network accessline 77
    #     "url":       "https://www.slowboring.com/p/what-to-make-of-the-generic-ballot",
  • Network accessline 115
    `GET https://{subdomain}.substack.com/api/v1/posts/{slug}`
  • Network accessline 157
    post = substack_get_post(     "https://www.slowboring.com",
  • Network accessline 158
    "https://www.slowboring.com",
  • Network accessline 182
    `GET https://{subdomain}.substack.com/api/v1/post/{post_id}/comments?limit=N`
  • Network accessline 219
    comments = substack_get_comments("https://www.slowboring.com", 194950421, limit=10)
  • Network accessline 237
    `GET https://{subdomain}.substack.com/feed`
  • Network accessline 273
    feed = substack_rss("https://www.slowboring.com", max_items=5)
  • Network accessline 275
    #   { #     "title":    "Sunday Mailbag + Thread", #     "link":     "https://www.slowboring.com/p/sunday-mailbag-thread-48b",
  • Network accessline 276
    #     "title":    "Sunday Mailbag + Thread", #     "link":     "https://www.slowboring.com/p/sunday-mailbag-thread-48b", #     "pub_date": "Sun, 26 Apr 2026 17:02:04 GMT",
  • Network accessline 277
    #     "link":     "https://www.slowboring.com/p/sunday-mailbag-thread-48b",
  • Network accessline 292
    # Format 1: native subdomain (older or simpler publications) "https://simonwillison.substack.com"
  • Network accessline 293
    "https://simonwillison.substack.com"
  • Network accessline 295
    # Format 2: custom domain (larger publications, purchased domain) "https://www.slowboring.com"         # Matthew Yglesias — Slow Boring
  • Network accessline 296
    "https://www.slowboring.com"         # Matthew Yglesias — Slow Boring
  • Network accessline 297
    "https://unchartedterritories.tomaspueyo.com"   # Tomas Pueyo
  • Network accessline 306
    If you only know a publication's Substack handle (e.g., `matthewyglesias`), the canonical subdomain URL is `https://matthewyglesias.substack.com`. Custom
  • Network accessline 307
    the canonical subdomain URL is `https://matthewyglesias.substack.com`. Custom

agent-workspace/domain-skills/target/scraping.md

  • Network accessline 22
    CATEGORY_URL = "https://www.target.com/c/air-fryers-kitchen-appliances-dining/-/N-ncrpx"   # any /c/<slug>/-/N-<id> page
  • Network accessline 25
    if not re.fullmatch(r"https://www\.target\.com/c/[^?#]+/-/N-[0-9A-Za-z]+", CATEGORY_URL):
  • Network accessline 26
    raise SystemExit("CATEGORY_URL must be https://www.target.com/c/<slug>/-/N-<id> with no query string")
  • Possible obfuscationline 37
    return json.loads(base64.b64decode(r["body"]) if r.get("base64Encoded") else r["body"])
  • Network accessline 175
    "rating": 4.01,   "rating_count": 761,   "url": "https://www.target.com/p/cuisinart-1800w-air-fryer-toaster-oven-stainless-steel-finish/-/A-92969684",
  • Network accessline 176
    "rating_count": 761,   "url": "https://www.target.com/p/cuisinart-1800w-air-fryer-toaster-oven-stainless-steel-finish/-/A-92969684",   "ship_status": "IN_STOCK",
  • Network accessline 177
    "url": "https://www.target.com/p/cuisinart-1800w-air-fryer-toaster-oven-stainless-steel-finish/-/A-92969684",
  • Network accessline 197
    page = http_get(f"https://www.target.com/p/-/A-{TCIN}", headers={
  • Network accessline 272
    URL = f"https://www.target.com/p/-/A-{TCIN}"
  • Network accessline 342
    | Rating | `ratings_and_reviews.statistics.rating.average` | `4.01`; falls back to `parent.ratings_and_reviews`; `None` on 85 of 270 air fryer rows (unrated) | | Rating count | `ratings_and_reviews.statistics.rating.count` | `761` (star rat
  • Network accessline 343
    | Rating count | `ratings_and_reviews.statistics.rating.count` | `761` (star ratings; written reviews are fewer, see PDP `review_count`) | | URL | `item.enrichment.buy_url` | absolute `https://www.target.com/p/<slug>/-/A-<tcin>` | | Shippin
  • Network accessline 344
    | URL | `item.enrichment.buy_url` | absolute `https://www.target.com/p/<slug>/-/A-<tcin>` |
  • Network accessline 372
    - **Search pages (`/s?searchTerm=...`)**: disallowed for all user agents by robots.txt, so this skill does not use them. Start from a category page (block 1) or from known TCINs or product URLs (blocks 2 and 3). - **Plain HTTP category page
  • Network accessline 373
    - **Plain HTTP category page**: `https://www.target.com/c/air-fryers-kitchen-appliances-dining/-/N-ncrpx` returned 200 and a 164 KB page whose `__NEXT_DATA__` held no products (6 `/p/` links in the whole HTML); the grid is filled client-sid

agent-workspace/domain-skills/tasksquad-ai/agents.md

  • Network accessline 8
    https://tasksquad.ai/dashboard/agents       # Agents list for current project

agent-workspace/domain-skills/tasksquad-ai/auth.md

  • Network accessline 8
    https://tasksquad.ai/auth          # login page (redirects to /dashboard if already signed in)
  • Network accessline 9
    https://tasksquad.ai/auth/cli      # CLI token auth page
  • Network accessline 17
    goto_url("https://tasksquad.ai/auth")

agent-workspace/domain-skills/tasksquad-ai/tasks.md

  • Network accessline 8
    https://tasksquad.ai/dashboard              # Inbox (default view)
  • Network accessline 9
    https://tasksquad.ai/dashboard/<taskId>     # Task thread (individual task)

agent-workspace/domain-skills/tcgplayer/scraping.md

  • Network accessline 28
    raise ValueError("line must be a productLineUrlName like 'magic' and q must be non-empty")     qs = urllib.parse.urlencode({"productLineName": line, "q": q, "view": "grid", "page": page})     url = f"https://www.tcgplayer.com/search/{line}/
  • Network accessline 29
    qs = urllib.parse.urlencode({"productLineName": line, "q": q, "view": "grid", "page": page})     url = f"https://www.tcgplayer.com/search/{line}/product?{qs}"     if "seller=" in url:   # robots.txt: Disallow: /search/*/product?seller=*
  • Network accessline 30
    url = f"https://www.tcgplayer.com/search/{line}/product?{qs}"
  • Possible obfuscationline 67
    data = json.loads(base64.b64decode(b["body"]) if b.get("base64Encoded") else b["body"])
  • Network accessline 88
    "listings": int(it.get("totalListings") or 0),         "sealed": it.get("sealed"),         "url": f"https://www.tcgplayer.com/product/{pid}",
  • Network accessline 89
    "sealed": it.get("sealed"),         "url": f"https://www.tcgplayer.com/product/{pid}",     }
  • Network accessline 90
    "url": f"https://www.tcgplayer.com/product/{pid}",
  • Network accessline 138
    magic 'lightning bolt' page 2: 24 products, 22 new, total=104 46 products of 104 status: truncated_max_pages {"product_id": 1479, "name": "Lightning Bolt", "set": "Revised Edition", "set_code": "3ED", "rarity": "Common", "number": null, "ma
  • Network accessline 139
    46 products of 104 status: truncated_max_pages {"product_id": 1479, "name": "Lightning Bolt", "set": "Revised Edition", "set_code": "3ED", "rarity": "Common", "number": null, "market_price": 2.84, "lowest_price": 0.7, "lowest_price_with_shi
  • Network accessline 140
    {"product_id": 1479, "name": "Lightning Bolt", "set": "Revised Edition", "set_code": "3ED", "rarity": "Common", "number": null, "market_price": 2.84, "lowest_price": 0.7, "lowest_price_with_shipping": 0.7, "listings": 606, "sealed": false, 
  • Network accessline 141
    {"product_id": 719091, "name": "Lightning Bolt", "set": "Commander: Foundations", "set_code": "FDC", "rarity": "Uncommon", "number": "163", "market_price": 0.85, "lowest_price": 0.39, "lowest_price_with_shipping": 0.74, "listings": 51, "sea
  • Network accessline 142
    {"product_id": 697344, "name": "Lightning Bolt", "set": "Commander: Marvel Super Heroes", "set_code": "MSC", "rarity": "Uncommon", "number": "806", "market_price": 0.89, "lowest_price": 0.79, "lowest_price_with_shipping": 0.79, "listings": 
  • Network accessline 143
    pokemon 'charizard ex' page 1: 24 products, 24 new, total=157 24 products of 157 status: truncated_max_pages {"product_id": 124025, "name": "M Charizard EX", "set": "XY - Evolutions", "set_code": "EVO", "rarity": "Ultra Rare", "number": "13
  • Network accessline 144
    24 products of 157 status: truncated_max_pages {"product_id": 124025, "name": "M Charizard EX", "set": "XY - Evolutions", "set_code": "EVO", "rarity": "Ultra Rare", "number": "13/108", "market_price": 38.27, "lowest_price": 6.54, "lowest_pr
  • Network accessline 145
    {"product_id": 124025, "name": "M Charizard EX", "set": "XY - Evolutions", "set_code": "EVO", "rarity": "Ultra Rare", "number": "13/108", "market_price": 38.27, "lowest_price": 6.54, "lowest_price_with_shipping": 6.54, "listings": 239, "sea
  • Possible obfuscationline 201
    got[r["kind"]] = (size, json.loads(base64.b64decode(b["body"]) if b.get("base64Encoded") else b["body"]))
  • Network accessline 237
    } for s in sales.get("data") or []],         "sales_meta": {k: sales.get(k) for k in ("totalResults", "nextPage")},         "url": f"https://www.tcgplayer.com/product/{pid}",
  • Network accessline 238
    "sales_meta": {k: sales.get(k) for k in ("totalResults", "nextPage")},         "url": f"https://www.tcgplayer.com/product/{pid}",     }
  • Network accessline 239
    "url": f"https://www.tcgplayer.com/product/{pid}",
  • Network accessline 248
    time.sleep(CRAWL_DELAY_S)         drain_events()         goto_url(f"https://www.tcgplayer.com/product/{int(pid)}")
  • Network accessline 249
    drain_events()         goto_url(f"https://www.tcgplayer.com/product/{int(pid)}")         out.append(parse(int(pid), read_product(session, int(pid))))
  • Network accessline 250
    goto_url(f"https://www.tcgplayer.com/product/{int(pid)}")
  • Network accessline 266
    {"product_id": 1479, "name": "Lightning Bolt", "set": "Revised Edition", "line": "Magic: The Gathering", "rarity": "Common", "market_price": 2.84, "median_price": 2.84, "lowest_price": 0.7, "lowest_price_with_shipping": 0.7, "listings_total
  • Network accessline 268
    cheapest: [{"condition": "Heavily Played", "printing": "Normal", "language": "English", "price": 0.75, "shipping": 1.49, "quantity": 2, "seller_rating": 100.0, "seller_sales": "1401", "direct": false, "listing_type": "standard"}, {"conditio
  • Network accessline 269
    latest sale: [{"date": "2026-10-31T13:06:45.887+00:00", "condition": "Lightly Played", "variant": "Normal", "price": 2.38, "shipping": 0.0, "quantity": 1}] {"product_id": 719091, "name": "Lightning Bolt", "set": "Commander: Foundations", "l
  • Network accessline 270
    {"product_id": 719091, "name": "Lightning Bolt", "set": "Commander: Foundations", "line": "Magic: The Gathering", "rarity": "Uncommon", "market_price": 0.85, "median_price": 0.96, "lowest_price": 0.39, "lowest_price_with_shipping": 0.74, "l
  • Network accessline 272
    cheapest: [{"condition": "Near Mint", "printing": "Normal", "language": "English", "price": 0.76, "shipping": 3.99, "quantity": 4, "seller_rating": 100.0, "seller_sales": "25000+", "direct": true, "listing_type": "standard"}, {"condition": 
  • Network accessline 273
    latest sale: [{"date": "2026-10-31T18:17:55.253+00:00", "condition": "Near Mint", "variant": "Normal", "price": 0.74, "shipping": 1.49, "quantity": 1}] {"product_id": 1032, "name": "Aspect of Wolf", "set": "Alpha Edition", "line": "Magic: T
  • Network accessline 274
    {"product_id": 1032, "name": "Aspect of Wolf", "set": "Alpha Edition", "line": "Magic: The Gathering", "rarity": "Rare", "market_price": null, "median_price": null, "lowest_price": 375.0, "lowest_price_with_shipping": null, "listings_total"

agent-workspace/domain-skills/thetechgeeks/pricing.md

  • Network accessline 3
    `https://thetechgeeks.com` — Shopify Online Store 2.0, AU Ubiquiti reseller. Prices GST-inclusive ("All Prices Include Australian GST At 10%" in footer).
  • Network accessline 10
    import json d = json.loads(http_get(f"https://thetechgeeks.com/products/{handle}.js"))
  • Network accessline 11
    d = json.loads(http_get(f"https://thetechgeeks.com/products/{handle}.js"))
  • Network accessline 41
    - `https://thetechgeeks.com/search?q=<SKU>` → scrape first `a[href*="/products/"]` link

agent-workspace/domain-skills/ticketmaster/scraping.md

  • Network accessline 25
    BASE = "https://www.ticketmaster.com"
  • Network accessline 27
    # robots.txt, group "User-agent: *", Google-style matching: longest pattern wins, Allow wins a tie. # Read in the browser tab: plain urllib got HTTP 403 for robots.txt (curl got 200), and this skill does not change its UA.
  • Network accessline 28
    # Read in the browser tab: plain urllib got HTTP 403 for robots.txt (curl got 200), and this skill does not change its UA.
  • Network accessline 286
    search jazz: 40 of 3889 truncated_max_pages    2026-10-31 21:00 | Halloween with Sally Baby's Silver Dollars | Snug Harbor Jazz Bistro, New Orleans LA | https://www.ticketweb.com/event/halloween-with-sally-babys-silver-snug-harbor-jazz-bist
  • Network accessline 287
    2026-10-31 21:00 | Halloween with Sally Baby's Silver Dollars | Snug Harbor Jazz Bistro, New Orleans LA | https://www.ticketweb.com/event/halloween-with-sally-babys-silver-snug-harbor-jazz-bistro-tickets/14410584
  • Network accessline 288
    2026-11-01 15:00 | Fresh Takes On Jazz: Ava Preston | Mickey's Black Box, Lititz PA | https://www.ticketmaster.com/fresh-takes-on-jazz-ava-preston-lititz-pennsylvania-11-01-2026/event/0200651B00735077
  • Network accessline 289
    2026-11-01 18:00 | Johnny Britt "You Are Beautiful" Tour | Humphreys Backstage Live, San Diego CA | https://www.ticketmaster.com/johnny-britt-you-are-beautiful-tour-san-diego-california-11-01-2026/event/0A0065159E4494E2
  • Network accessline 290
    discover concerts/Country 2026-11-07..2026-11-08: 40 of 108 truncated_max_pages    2026-11-06 20:00 | Saddle Up: Country Grammar | Diamondback Music Hall, Belleville MI | https://www.ticketweb.com/event/saddle-up-country-grammar-diamondback
  • Network accessline 291
    2026-11-06 20:00 | Saddle Up: Country Grammar | Diamondback Music Hall, Belleville MI | https://www.ticketweb.com/event/saddle-up-country-grammar-diamondback-music-hall-tickets/14407284
  • Network accessline 292
    2026-11-07 12:30 | BACKSTAGE NASHVILLE! DAYTIME HIT SONGWRITERS SHOW featuring  | 3rd and Lindsley, Nashville TN | https://www.ticketweb.com/event/backstage-nashville-daytime-hit-songwriters-3rd-and-lindsley-tickets/14637713
  • Network accessline 293
    discover chicago: 20 of 2425 truncated_max_pages | off-site: 10 slug date == local_date: 32 of 32 | date_display: Counter({'showDateTime': 100}) {"id": "0200651B00735077", "name": "Fresh Takes On Jazz: Ava Preston", "start_local": "2026-11-
  • Network accessline 294
    slug date == local_date: 32 of 32 | date_display: Counter({'showDateTime': 100}) {"id": "0200651B00735077", "name": "Fresh Takes On Jazz: Ava Preston", "start_local": "2026-11-01T15:00", "status": "EventScheduled", "venue": "Mickey's Black 
  • Network accessline 295
    {"id": "0200651B00735077", "name": "Fresh Takes On Jazz: Ava Preston", "start_local": "2026-11-01T15:00", "status": "EventScheduled", "venue": "Mickey's Black Box", "address": "101 Rock Lititz Blvd, Lititz, PA, 17543", "performers": [], "av
  • Network accessline 296
    list row said: 2026-11-01 15:00 | page says: 2026-11-01T15:00 {"id": "010064CB19BF6123", "name": "Huntertones", "start_local": "2026-11-01T19:30:00", "status": "EventScheduled", "venue": "Jimmy's Jazz and Blues Club", "address": "135 Congre
  • Network accessline 297
    {"id": "010064CB19BF6123", "name": "Huntertones", "start_local": "2026-11-01T19:30:00", "status": "EventScheduled", "venue": "Jimmy's Jazz and Blues Club", "address": "135 Congress Street, Portsmouth, NH, 03801", "performers": ["Huntertones
  • Network accessline 298
    list row said: 2026-11-01 19:30 | page says: 2026-11-01T19:30:00 {"id": "Z7r9jZ1AAZd8O", "name": "Jon Pardi w/ Alexandra Kay", "start_local": "2026-11-07T17:30", "status": "EventScheduled", "venue": "Round Rock Amp", "address": "3701 N IH 3
  • Network accessline 299
    {"id": "Z7r9jZ1AAZd8O", "name": "Jon Pardi w/ Alexandra Kay", "start_local": "2026-11-07T17:30", "status": "EventScheduled", "venue": "Round Rock Amp", "address": "3701 N IH 35, Round Rock, TX, 78665", "performers": [], "availability": null
  • Network accessline 346
    - Plain `urllib` with its default User-Agent got HTTP 403 for `/robots.txt` (curl got 200), so the block reads robots.txt in the browser tab instead of changing its User-Agent.

agent-workspace/domain-skills/tiktok/upload.md

  • Network accessline 3
    URL: `https://www.tiktok.com/tiktokstudio/upload?from=upload&lang=en` (always append `&lang=en`)

agent-workspace/domain-skills/tradingview/scraping.md

  • Network accessline 3
    `https://www.tradingview.com` — charting platform with multiple internal REST APIs. Stock/crypto/forex screener and symbol search work without auth. Use `http_get` or raw `urllib` for all workflows except JS-rendered chart pages.
  • Network accessline 12
    def tv_scan(payload, market="america"):     data = json.dumps(payload).encode()     req = urllib.request.Request(
  • Network accessline 13
    data = json.dumps(payload).encode()     req = urllib.request.Request(         f"https://scanner.tradingview.com/{market}/scan",
  • Network accessline 14
    req = urllib.request.Request(
  • Network accessline 15
    f"https://scanner.tradingview.com/{market}/scan",
  • Network accessline 17
    headers={"Content-Type": "application/json", "User-Agent": "Mozilla/5.0"}     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 18
    )     with urllib.request.urlopen(req, timeout=20) as r:         return json.loads(r.read())
  • Network accessline 19
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 40
    data = json.dumps(payload).encode() req = urllib.request.Request(
  • Network accessline 41
    req = urllib.request.Request(
  • Network accessline 42
    "https://scanner.tradingview.com/america/scan",
  • Network accessline 44
    headers={"Content-Type": "application/json", "User-Agent": "Mozilla/5.0"} ) with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 45
    ) with urllib.request.urlopen(req, timeout=20) as r:     resp = json.loads(r.read())
  • Network accessline 46
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 171
    def symbol_search(query, exchange="", type_filter="", limit=50):     url = (         f"https://symbol-search.tradingview.com/symbol_search/v3/"
  • Network accessline 172
    url = (         f"https://symbol-search.tradingview.com/symbol_search/v3/"         f"?text={query}&hl=1&exchange={exchange}&lang=en"
  • Network accessline 173
    f"https://symbol-search.tradingview.com/symbol_search/v3/"
  • Network accessline 175
    f"&search_type={type_filter or 'undefined'}&domain=production"     )     req = urllib.request.Request(url, headers={
  • Network accessline 176
    )     req = urllib.request.Request(url, headers={         "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
  • Network accessline 177
    req = urllib.request.Request(url, headers={
  • Network accessline 178
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",         "Origin": "https://www.tradingview.com",   # REQUIRED — 403 without this     })
  • Network accessline 179
    "Origin": "https://www.tradingview.com",   # REQUIRED — 403 without this     })     with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 180
    })     with urllib.request.urlopen(req, timeout=15) as r:         return json.loads(r.read())
  • Network accessline 181
    with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 193
    **Gotcha**: `symbol-search.tradingview.com` requires `Origin: https://www.tradingview.com`. Referer alone is not enough. The scanner API does NOT need Origin or Referer.
  • Network accessline 209
    # symbol format: "NASDAQ:AAPL", "NYSE:TSLA"     url = (         f"https://news-headlines.tradingview.com/v2/view/headlines/symbol"
  • Network accessline 210
    url = (         f"https://news-headlines.tradingview.com/v2/view/headlines/symbol"         f"?symbol={symbol}&client=web&streaming=false&lang=en&limit={limit}"
  • Network accessline 211
    f"https://news-headlines.tradingview.com/v2/view/headlines/symbol"
  • Network accessline 212
    f"?symbol={symbol}&client=web&streaming=false&lang=en&limit={limit}"     )     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 213
    )     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})     with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 214
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 215
    with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 223
    # items[0]["title"]     = "Apple Clears Major Legal Hurdle..." # items[0]["published"] = 1776472317  (unix timestamp) # items[0]["link"]      = "https://stocktwits.com/..."
  • Network accessline 224
    # items[0]["published"] = 1776472317  (unix timestamp) # items[0]["link"]      = "https://stocktwits.com/..." # items[0]["relatedSymbols"] = [{"symbol": "NASDAQ:AAPL", "logoid": "apple"}]
  • Network accessline 225
    # items[0]["link"]      = "https://stocktwits.com/..."
  • Network accessline 238
    # "trending", "recent", "latest_popular", "week_popular",     # "suggested", "recent_extended", "picked_time"     url = f"https://www.tradingview.com/api/v1/ideas/?lang=en&sort={sort}&page={page}"
  • Network accessline 239
    # "suggested", "recent_extended", "picked_time"     url = f"https://www.tradingview.com/api/v1/ideas/?lang=en&sort={sort}&page={page}"     if symbol:
  • Network accessline 240
    url = f"https://www.tradingview.com/api/v1/ideas/?lang=en&sort={sort}&page={page}"
  • Network accessline 241
    if symbol:         url += f"&symbol={symbol}"  # e.g. "NASDAQ:AAPL"     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 242
    url += f"&symbol={symbol}"  # e.g. "NASDAQ:AAPL"     req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})     with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 243
    req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
  • Network accessline 244
    with urllib.request.urlopen(req, timeout=15) as r:
  • Network accessline 249
    # data["page_size"]  = 20 # data["page_count"] = 50 # data["next"]       = "https://www.tradingview.com/api/v1/ideas/?page=2"
  • Network accessline 250
    # data["page_count"] = 50 # data["next"]       = "https://www.tradingview.com/api/v1/ideas/?page=2" # data["results"]    = list of idea objects
  • Network accessline 251
    # data["next"]       = "https://www.tradingview.com/api/v1/ideas/?page=2"
  • Network accessline 268
    |---|---|---|---| | `scanner.tradingview.com/{market}/scan` | None | None | ~200ms | | `symbol-search.tradingview.com/symbol_search/v3/` | None | `Origin: https://www.tradingview.com` | ~150ms |
  • Network accessline 269
    | `scanner.tradingview.com/{market}/scan` | None | None | ~200ms | | `symbol-search.tradingview.com/symbol_search/v3/` | None | `Origin: https://www.tradingview.com` | ~150ms | | `symbol-search.tradingview.com/symbol_search/` (v1) | None | 
  • Network accessline 270
    | `symbol-search.tradingview.com/symbol_search/v3/` | None | `Origin: https://www.tradingview.com` | ~150ms |
  • Network accessline 271
    | `symbol-search.tradingview.com/symbol_search/` (v1) | None | `Origin: https://www.tradingview.com` | ~100ms |
  • Network accessline 283
    **`data.tradingview.com/quotes/` is dead**: The URL `https://data.tradingview.com/quotes/?symbols=NASDAQ:AAPL` closes the connection without a response. Use the scanner API instead for real-time quotes.
  • Network accessline 304
    # Only if you need a chart screenshot: goto_url("https://www.tradingview.com/chart/?symbol=NASDAQ:AAPL")
  • Network accessline 305
    goto_url("https://www.tradingview.com/chart/?symbol=NASDAQ:AAPL")

agent-workspace/domain-skills/trello/boards-and-lists.md

  • Network accessline 9
    - `https://trello.com/` — marketing home for anonymous; when signed in,
  • Network accessline 10
    redirects to `https://trello.com/u/<username>/boards` (the dashboard).
  • Network accessline 11
    Note: `https://trello.com/boards` (no `/u/<username>`) returns an
  • Network accessline 12
    error page for signed-in users. Always route via `/u/<username>/boards`. - Board URL: `https://trello.com/b/<8-char-boardId>/<slug>`. The `slug`   is cosmetic — the boardId is the canonical identifier.
  • Network accessline 13
    - Board URL: `https://trello.com/b/<8-char-boardId>/<slug>`. The `slug`
  • Network accessline 14
    is cosmetic — the boardId is the canonical identifier. - Card URL: `https://trello.com/c/<8-char-cardId>/<n>-<slug>`, where   `<n>` is the card's 1-based position within its list at creation time.
  • Network accessline 15
    - Card URL: `https://trello.com/c/<8-char-cardId>/<n>-<slug>`, where
  • Network accessline 40
    - `goto_url('https://trello.com/')` redirects asynchronously to the user's
  • Network accessline 85
    Private API endpoints (Trello exposes `https://trello.com/1/...` REST

agent-workspace/domain-skills/tripadvisor/scraping.md

  • Network accessline 27
    new_tab("https://www.tripadvisor.com/")
  • Network accessline 49
    for o in cities:     m = re.search(r"/Tourism-(g\d+)-(.+)-Vacations\.html", o["href"])     o["restaurants_url"] = f"https://www.tripadvisor.com/Restaurants-{m.group(1)}-{m.group(2)}.html"
  • Network accessline 50
    m = re.search(r"/Tourism-(g\d+)-(.+)-Vacations\.html", o["href"])     o["restaurants_url"] = f"https://www.tripadvisor.com/Restaurants-{m.group(1)}-{m.group(2)}.html"     o["hotels_url"] = f"https://www.tripadvisor.com/Hotels-{m.group(1)}-{
  • Network accessline 51
    o["restaurants_url"] = f"https://www.tripadvisor.com/Restaurants-{m.group(1)}-{m.group(2)}.html"
  • Network accessline 52
    o["hotels_url"] = f"https://www.tripadvisor.com/Hotels-{m.group(1)}-{m.group(2)}-Hotels.html"
  • Network accessline 60
    {'label': 'Lisbon | Central Portugal, Portugal', 'href': 'https://www.tripadvisor.com/Tourism-g189158-Lisbon_Lisbon_District_Central_Portugal-Vacations.html', 'restaurants_url': 'https://www.tripadvisor.com/Restaurants-g189158-Lisbon_Lisbon
  • Network accessline 61
    {'label': 'Lisbon | Ohio, United States', 'href': 'https://www.tripadvisor.com/Tourism-g50559-Lisbon_Ohio-Vacations.html', ...}
  • Network accessline 72
    CITY_URL = "https://www.tripadvisor.com/Restaurants-g60745-Boston_Massachusetts.html"
  • Network accessline 139
    "address": addr.get("streetAddress"),             "telephone": j.get("telephone"),             "url": urljoin("https://www.tripadvisor.com", c["href"]).split("?")[0].split("#")[0],
  • Network accessline 140
    "telephone": j.get("telephone"),             "url": urljoin("https://www.tripadvisor.com", c["href"]).split("?")[0].split("#")[0],             "location_id": lid,
  • Network accessline 141
    "url": urljoin("https://www.tripadvisor.com", c["href"]).split("?")[0].split("#")[0],
  • Network accessline 155
    page 1: https://www.tripadvisor.com/Restaurants-g60745-Boston_Massachusetts.html total=2,561 results rows so far=30
  • Network accessline 156
    page 2: https://www.tripadvisor.com/Restaurants-g60745-oa30-Boston_Massachusetts.html total=2,561 results rows so far=60
  • Network accessline 157
    page 3: https://www.tripadvisor.com/Restaurants-g60745-oa60-Boston_Massachusetts.html total=2,561 results rows so far=90
  • Network accessline 166
    "address": "55 Temple Place, Boston, MA 02111",   "telephone": "+1 617-779-0062",   "url": "https://www.tripadvisor.com/Restaurant_Review-g60745-d19799010-Reviews-Cafe_Bonjour-Boston_Massachusetts.html",
  • Network accessline 167
    "telephone": "+1 617-779-0062",   "url": "https://www.tripadvisor.com/Restaurant_Review-g60745-d19799010-Reviews-Cafe_Bonjour-Boston_Massachusetts.html",   "location_id": "19799010"
  • Network accessline 168
    "url": "https://www.tripadvisor.com/Restaurant_Review-g60745-d19799010-Reviews-Cafe_Bonjour-Boston_Massachusetts.html",
  • Network accessline 184
    CITY_URL = "https://www.tripadvisor.com/Hotels-g60745-Boston_Massachusetts-Hotels.html"
  • Network accessline 279
    "price_tier": j.get("priceRange"),             "address": ", ".join(filter(None, [addr.get("streetAddress"), addr.get("addressLocality")])) or None,             "url": urljoin("https://www.tripadvisor.com", c["href"]).split("?")[0].split("#
  • Network accessline 280
    "address": ", ".join(filter(None, [addr.get("streetAddress"), addr.get("addressLocality")])) or None,             "url": urljoin("https://www.tripadvisor.com", c["href"]).split("?")[0].split("#")[0],             "location_id": lid,
  • Network accessline 281
    "url": urljoin("https://www.tripadvisor.com", c["href"]).split("?")[0].split("#")[0],
  • Network accessline 297
    page 1: https://www.tripadvisor.com/Hotels-g60745-Boston_Massachusetts-Hotels.html rows so far=30
  • Network accessline 298
    page 2: https://www.tripadvisor.com/Hotels-g60745-oa30-Boston_Massachusetts-Hotels.html rows so far=60
  • Network accessline 307
    "price_tier": "€",   "address": "6 W Broadway, Boston",   "url": "https://www.tripadvisor.com/Hotel_Review-g60745-d15618152-Reviews-Cambria_Hotel_Boston_Downtown-Boston_Massachusetts.html",
  • Network accessline 308
    "address": "6 W Broadway, Boston",   "url": "https://www.tripadvisor.com/Hotel_Review-g60745-d15618152-Reviews-Cambria_Hotel_Boston_Downtown-Boston_Massachusetts.html",   "location_id": "15618152"
  • Network accessline 309
    "url": "https://www.tripadvisor.com/Hotel_Review-g60745-d15618152-Reviews-Cambria_Hotel_Boston_Downtown-Boston_Massachusetts.html",
  • Network accessline 326
    URLS = [     "https://www.tripadvisor.com/Hotel_Review-g60745-d15618152-Reviews-Cambria_Hotel_Boston_Downtown-Boston_Massachusetts.html",
  • Network accessline 327
    "https://www.tripadvisor.com/Hotel_Review-g60745-d15618152-Reviews-Cambria_Hotel_Boston_Downtown-Boston_Massachusetts.html",
  • Network accessline 328
    "https://www.tripadvisor.com/Restaurant_Review-g60745-d19799010-Reviews-Cafe_Bonjour-Boston_Massachusetts.html",

agent-workspace/domain-skills/trulia/scraping.md

  • Network accessline 45
    def search_url(city, state, mode, page):     slug = quote(city.strip().replace(" ", "_"), safe="_-")     base = (f"https://www.trulia.com/{state.upper()}/{slug}/" if mode == "sale"
  • Network accessline 46
    slug = quote(city.strip().replace(" ", "_"), safe="_-")     base = (f"https://www.trulia.com/{state.upper()}/{slug}/" if mode == "sale"             else f"https://www.trulia.com/for_rent/{slug},{state.upper()}/")
  • Network accessline 47
    base = (f"https://www.trulia.com/{state.upper()}/{slug}/" if mode == "sale"
  • Network accessline 48
    else f"https://www.trulia.com/for_rent/{slug},{state.upper()}/")
  • Network accessline 93
    "sqft": val(h, "floorSpace", "formattedDimension"),         "type": h.get("__typename"),         "url": "https://www.trulia.com" + h["url"] if h.get("url") else None,
  • Network accessline 94
    "type": h.get("__typename"),         "url": "https://www.trulia.com" + h["url"] if h.get("url") else None,     }
  • Network accessline 95
    "url": "https://www.trulia.com" + h["url"] if h.get("url") else None,
  • Network accessline 169
    PARTIAL: 23 of 25 pages not read yet; next run START_PAGE = 3 TRUNCATED: the site links only 25 pages, so at most 1000 of 5634 results are reachable; this cap is a hard stop {"address": "Cloverleaf 1657 Plan in Cloverleaf, Austin, TX 78747"
  • Network accessline 170
    TRUNCATED: the site links only 25 pages, so at most 1000 of 5634 results are reachable; this cap is a hard stop {"address": "Cloverleaf 1657 Plan in Cloverleaf, Austin, TX 78747", "price": "$368,990+", "price_min": 368990, "price_max": null
  • Network accessline 171
    {"address": "Cloverleaf 1657 Plan in Cloverleaf, Austin, TX 78747", "price": "$368,990+", "price_min": 368990, "price_max": null, "beds": "4 Beds", "baths": "2 Baths", "sqft": "1,657 sqft", "type": "HOME_FloorPlan", "url": "https://www.trul
  • Network accessline 172
    {"address": "1900 Barton Springs Rd #2006, Austin, TX 78704", "price": "$419,000", "price_min": 419000, "price_max": 419000, "beds": "1 Bed", "baths": "1 Bath", "sqft": "887 sqft", "type": "HOME_Property", "url": "https://www.trulia.com/hom
  • Network accessline 178
    {"address": "1188 Mission St, San Francisco, CA 94103", "price": "$3,946 - $4,952/mo", "price_min": 3946, "price_max": 4952, "beds": "1 Bed", "baths": "1 Bath", "sqft": "450-688 sqft", "type": "HOME_RentalCommunity", "url": "https://www.tru
  • Network accessline 189
    SEARCH_URL = "https://www.trulia.com/CA/San_Francisco/"   # any for-sale search page
  • Network accessline 223
    if not homes:     raise RuntimeError("no /home/ listings on the search page") detail_url = "https://www.trulia.com" + homes[0]["url"]
  • Network accessline 224
    raise RuntimeError("no /home/ listings on the search page") detail_url = "https://www.trulia.com" + homes[0]["url"] time.sleep(PAUSE_S)
  • Network accessline 225
    detail_url = "https://www.trulia.com" + homes[0]["url"]
  • Network accessline 277
    {  "url": "https://www.trulia.com/home/355-chester-ave-san-francisco-ca-94132-15195820",
  • Network accessline 278
    "url": "https://www.trulia.com/home/355-chester-ave-san-francisco-ca-94132-15195820",
  • Network accessline 306
    RENT_SEARCH_URL = "https://www.trulia.com/for_rent/San_Francisco,CA/"
  • Network accessline 344
    url = "https://www.trulia.com" + buildings[0]

agent-workspace/domain-skills/trustpilot/scraping.md

  • Network accessline 23
    Returns (None, [], {}, {}) if page is beyond the cap or no data.     """     url = f"https://www.trustpilot.com/review/{domain}?languages={languages}&page={page}"
  • Network accessline 24
    """     url = f"https://www.trustpilot.com/review/{domain}?languages={languages}&page={page}"     if stars:
  • Network accessline 25
    url = f"https://www.trustpilot.com/review/{domain}?languages={languages}&page={page}"
  • Network accessline 62
    bu['stars']            # 1.5  (display stars: 1, 1.5, 2, 2.5 … 5) bu['numberOfReviews']  # 45228  — total across all languages bu['websiteUrl']       # 'https://www.amazon.com'
  • Network accessline 63
    bu['numberOfReviews']  # 45228  — total across all languages bu['websiteUrl']       # 'https://www.amazon.com' bu['isClaimed']        # True/False
  • Network accessline 64
    bu['websiteUrl']       # 'https://www.amazon.com'
  • Network accessline 102
    'id':              '5cafe2feb158a8533b443467',         'displayName':     'Baldy Bloke',         'imageUrl':        'https://user-images.trustpilot.com/...',
  • Network accessline 103
    'displayName':     'Baldy Bloke',         'imageUrl':        'https://user-images.trustpilot.com/...',         'numberOfReviews': 17,
  • Network accessline 104
    'imageUrl':        'https://user-images.trustpilot.com/...',
  • Network accessline 146
    delay: seconds between requests (0.5 is safe; tested 5 rapid reqs with no block)     """     base = f"https://www.trustpilot.com/review/{domain}"
  • Network accessline 147
    """     base = f"https://www.trustpilot.com/review/{domain}"     params = f"?languages={languages}"
  • Network accessline 148
    base = f"https://www.trustpilot.com/review/{domain}"
  • Network accessline 204
    All filter params are appended to the base URL `https://www.trustpilot.com/review/{domain}`:
  • Network accessline 254
    GET https://api.trustpilot.com/v1/business-units/find?name=amazon.com  → 403 Forbidden
  • Network accessline 255
    GET https://api.trustpilot.com/v1/business-units/{id}/reviews          → 403 Forbidden
  • Network accessline 307
    """     def _fetch_page(domain, page, stars=None, languages='en'):         url = f"https://www.trustpilot.com/review/{domain}?languages={languages}&page={page}"
  • Network accessline 308
    def _fetch_page(domain, page, stars=None, languages='en'):         url = f"https://www.trustpilot.com/review/{domain}?languages={languages}&page={page}"         if stars:
  • Network accessline 309
    url = f"https://www.trustpilot.com/review/{domain}?languages={languages}&page={page}"

agent-workspace/domain-skills/twitch/scraping.md

  • Network accessline 26
    BASE = "https://www.twitch.tv/directory/category/" + urllib.parse.quote(CATEGORY_SLUG, safe="")
  • Network accessline 43
    """Navigate the attached tab (new tab only if it is not on twitch yet); confirm the exact URL, query included."""     href = safe_js("location.href") or ""     if href.startswith("https://www.twitch.tv/"):
  • Network accessline 44
    href = safe_js("location.href") or ""     if href.startswith("https://www.twitch.tv/"):         goto_url(url)
  • Network accessline 45
    if href.startswith("https://www.twitch.tv/"):
  • Network accessline 163
    c["grid_position"] = pos          # order the cards were appended while scrolling     c["viewers"] = viewers_to_int(c["viewers_text"])     c["url"] = "https://www.twitch.tv/" + c["login"]
  • Network accessline 164
    c["viewers"] = viewers_to_int(c["viewers_text"])     c["url"] = "https://www.twitch.tv/" + c["login"] # Counts change while you scroll, so grid order is only roughly sorted; re-sort by the card counts.
  • Network accessline 165
    c["url"] = "https://www.twitch.tv/" + c["login"]
  • Network accessline 193
    "tags": ["<tag>", "<tag>", "<tag>"],   "verified": false,   "thumbnail": "https://static-cdn.jtvnw.net/previews-ttv/live_user_<login>-640x360.jpg",
  • Network accessline 194
    "verified": false,   "thumbnail": "https://static-cdn.jtvnw.net/previews-ttv/live_user_<login>-640x360.jpg",   "grid_position": 27,
  • Network accessline 195
    "thumbnail": "https://static-cdn.jtvnw.net/previews-ttv/live_user_<login>-640x360.jpg",
  • Network accessline 196
    "grid_position": 27,   "viewers": 6400,   "url": "https://www.twitch.tv/<login>",
  • Network accessline 197
    "viewers": 6400,   "url": "https://www.twitch.tv/<login>",   "rank": 1
  • Network accessline 198
    "url": "https://www.twitch.tv/<login>",
  • Network accessline 233
    """Navigate the attached tab (new tab only if it is not on twitch yet); confirm the exact URL, query included."""     href = safe_js("location.href") or ""     if href.startswith("https://www.twitch.tv/"):
  • Network accessline 234
    href = safe_js("location.href") or ""     if href.startswith("https://www.twitch.tv/"):         goto_url(url)
  • Network accessline 235
    if href.startswith("https://www.twitch.tv/"):
  • Network accessline 286
    open_page("https://www.twitch.tv/directory")
  • Network accessline 320
    cats.append({**c, "rank": rank, "kind": kind, "slug": slug,                  "viewers": viewers_to_int(c["viewers_text"]),                  "url": "https://www.twitch.tv" + c["path"]})
  • Network accessline 322
    "url": "https://www.twitch.tv" + c["path"]})
  • Network accessline 340
    {"name": "Stream-o-Ween", "path": "/directory/event/stream-o-ween-2026", "viewers_text": "34.4K viewers", "tags": [], "kind": "event", "slug": "stream-o-ween-2026", "viewers": 34400, ...},  {"name": "Just Chatting", "path": "/directory/cate
  • Network accessline 341
    {"name": "Just Chatting", "path": "/directory/category/just-chatting", "viewers_text": "200K viewers", "tags": ["IRL"],   "box_art": "https://static-cdn.jtvnw.net/ttv-boxart/509658-285x380.jpg", "rank": 2, "kind": "category", "slug": "just-
  • Network accessline 342
    "box_art": "https://static-cdn.jtvnw.net/ttv-boxart/509658-285x380.jpg", "rank": 2, "kind": "category", "slug": "just-chatting", "viewers": 200000,
  • Network accessline 343
    "url": "https://www.twitch.tv/directory/category/just-chatting"},
  • Network accessline 387
    def fetch(url, deadline):
  • Network accessline 393
    if left <= 0:             raise TimeoutError(f"{url}: deadline reached")         req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Encoding": "gzip", "Accept-Language": "en-US"})
  • Network accessline 394
    raise TimeoutError(f"{url}: deadline reached")         req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Encoding": "gzip", "Accept-Language": "en-US"})         try:
  • Network accessline 395
    req = urllib.request.Request(url, headers={"User-Agent": UA, "Accept-Encoding": "gzip", "Accept-Language": "en-US"})
  • Network accessline 396
    try:             with urllib.request.urlopen(req, timeout=min(20, left)) as r:                 page = body(r.read(), r.headers)
  • Network accessline 397
    with urllib.request.urlopen(req, timeout=min(20, left)) as r:
  • Network accessline 420
    def channel_about(login, attempts=4):     url = "https://www.twitch.tv/" + urllib.parse.quote(login.lower(), safe="")
  • Network accessline 421
    url = "https://www.twitch.tv/" + urllib.parse.quote(login.lower(), safe="")
  • Network accessline 422
    deadline = time.time() + BUDGET          # all requests and waits for one login share this deadline     for attempt in range(attempts):         page = fetch(url, deadline)
  • Network accessline 423
    for attempt in range(attempts):         page = fetch(url, deadline)         graph = []
  • Network accessline 424
    page = fetch(url, deadline)
  • Network accessline 486
    "login": "twitchgaming",   "display_name": "twitchgaming",   "url": "https://www.twitch.tv/twitchgaming",
  • Network accessline 487
    "display_name": "twitchgaming",   "url": "https://www.twitch.tv/twitchgaming",   "bio": "Join /twitchgaming and be a part of the conversation! ...",
  • Network accessline 488
    "url": "https://www.twitch.tv/twitchgaming",
  • Network accessline 489
    "bio": "Join /twitchgaming and be a part of the conversation! ...",   "profile_image": "https://static-cdn.jtvnw.net/jtv_user_pictures/77eb821f-...-profile_image-300x300.jpeg",   "followers": 584895,
  • Network accessline 490
    "profile_image": "https://static-cdn.jtvnw.net/jtv_user_pictures/77eb821f-...-profile_image-300x300.jpeg",
  • Network accessline 491
    "followers": 584895,   "social_links": ["https://twitter.com/twitch", "https://instagram.com/twitch"],   "live": false, "live_title": null, "live_category": null,
  • Network accessline 492
    "social_links": ["https://twitter.com/twitch", "https://instagram.com/twitch"],
  • Network accessline 497
    {   "login": "twitch", "display_name": "Twitch", "followers": 2483231,   "social_links": ["https://twitter.com/twitch", "https://www.instagram.com/twitch/", "https://www.tiktok.com/@twitch", "https://www.youtube.com/twitch"],
  • Network accessline 498
    "login": "twitch", "display_name": "Twitch", "followers": 2483231,   "social_links": ["https://twitter.com/twitch", "https://www.instagram.com/twitch/", "https://www.tiktok.com/@twitch", "https://www.youtube.com/twitch"],   "recent_videos":
  • Network accessline 499
    "social_links": ["https://twitter.com/twitch", "https://www.instagram.com/twitch/", "https://www.tiktok.com/@twitch", "https://www.youtube.com/twitch"],
  • Network accessline 500
    "recent_videos": [    {"title": "Let's Chat Episode 14 | ...", "url": "https://www.twitch.tv/videos/2908640776", "uploaded": "2026-10-23T16:55:16Z", "duration": "PT3353S", "views": 8},    ...
  • Network accessline 501
    {"title": "Let's Chat Episode 14 | ...", "url": "https://www.twitch.tv/videos/2908640776", "uploaded": "2026-10-23T16:55:16Z", "duration": "PT3353S", "views": 8},
  • Network accessline 534
    """Navigate the attached tab (new tab only if it is not on twitch yet); confirm the exact URL, query included."""     href = safe_js("location.href") or ""     if href.startswith("https://www.twitch.tv/"):
  • Network accessline 535
    href = safe_js("location.href") or ""     if href.startswith("https://www.twitch.tv/"):         goto_url(url)
  • Network accessline 536
    if href.startswith("https://www.twitch.tv/"):
  • Network accessline 631
    if i:         time.sleep(PAUSE)     base = "https://www.twitch.tv/" + urllib.parse.quote(login.lower(), safe="")
  • Network accessline 632
    time.sleep(PAUSE)     base = "https://www.twitch.tv/" + urllib.parse.quote(login.lower(), safe="")     open_page(base + "/about")
  • Network accessline 633
    base = "https://www.twitch.tv/" + urllib.parse.quote(login.lower(), safe="")
  • Network accessline 660
    {   "login": "twitchgaming",   "url": "https://www.twitch.tv/twitchgaming",
  • Network accessline 661
    "login": "twitchgaming",   "url": "https://www.twitch.tv/twitchgaming",   "display_name": "twitchgaming",
  • Network accessline 662
    "url": "https://www.twitch.tv/twitchgaming",
  • Network accessline 666
    "bio": "Join /twitchgaming and be a part of the conversation! ...",   "partner": true,   "social_links": [{"label": "Twitter", "url": "https://twitter.com/twitch"}, {"label": "Instagram", "url": "https://instagram.com/twitch"}],
  • Network accessline 667
    "partner": true,   "social_links": [{"label": "Twitter", "url": "https://twitter.com/twitch"}, {"label": "Instagram", "url": "https://instagram.com/twitch"}],   "panels": [{"text": "", "images": [...], "links": []}, ...],
  • Network accessline 668
    "social_links": [{"label": "Twitter", "url": "https://twitter.com/twitch"}, {"label": "Instagram", "url": "https://instagram.com/twitch"}],
  • Network accessline 672
    },  {"login": "twitch", "display_name": "Twitch", "followers_text": "2.5M followers", "partner": true,   "panels": [{"text": "", "images": [{"src": "https://panels.twitch.tv/panel-12826-image-...", "alt": "Panel Content"}], "links": ["https
  • Network accessline 673
    {"login": "twitch", "display_name": "Twitch", "followers_text": "2.5M followers", "partner": true,   "panels": [{"text": "", "images": [{"src": "https://panels.twitch.tv/panel-12826-image-...", "alt": "Panel Content"}], "links": ["https://t
  • Network accessline 674
    "panels": [{"text": "", "images": [{"src": "https://panels.twitch.tv/panel-12826-image-...", "alt": "Panel Content"}], "links": ["https://twitter.com/Twitch"]}, ...],
  • Network accessline 679
    With `LOGINS` set to the top 3 VALORANT channels plus an unknown login, the live part read: `"live": true, "stream_title": "<stream title>", "category": "VALORANT", "category_url": "https://www.twitch.tv/directory/category/valorant", "viewe
  • Network accessline 683
    | Field | Source | Notes | |---|---|---| | `login` | block 1 card `a[data-a-target="preview-card-channel-link"]` href; block 3 JSON-LD `alternateName` | lowercase, unique key; URL is `https://www.twitch.tv/<login>` |
  • Network accessline 684
    |---|---|---| | `login` | block 1 card `a[data-a-target="preview-card-channel-link"]` href; block 3 JSON-LD `alternateName` | lowercase, unique key; URL is `https://www.twitch.tv/<login>` | | `display_name` | card `p[title]`; JSON-LD `mainE
  • Network accessline 685
    | `login` | block 1 card `a[data-a-target="preview-card-channel-link"]` href; block 3 JSON-LD `alternateName` | lowercase, unique key; URL is `https://www.twitch.tv/<login>` |
  • Access to secretsline 718
    [Credential-related source omitted]
  • Network accessline 725
    - **Plain HTTP for live channel lists:** `/directory/category/<slug>` returned 200 with only `BreadcrumbList` and `CollectionPage` JSON-LD and no stream cards. Use the browser (block 1). - **`gql.twitch.tv`** (the endpoint the page itself u
  • Network accessline 726
    - **`gql.twitch.tv`** (the endpoint the page itself uses for the grid) is `Disallow: /` in its robots.txt; this skill does not call it. - **Helix API without credentials:** `GET https://api.twitch.tv/helix/streams?first=5` returned `401 {"e
  • Network accessline 727
    - **Helix API without credentials:** `GET https://api.twitch.tv/helix/streams?first=5` returned `401 {"error":"Unauthorized","message":"OAuth token is missing"}`. The official API needs a registered app and token; not covered here.

agent-workspace/domain-skills/ulta/scraping.md

  • Network accessline 10
    - **Search (`/search?search=...`) is client-rendered.** Over plain HTTP the same module is present but has no items, so block 2 loads the search page in the browser and reads the rendered product cards (`li[data-test="products-list-item"]`)
  • Network accessline 12
    - Category URLs: `https://www.ulta.com/sitemap/shop.xml` listed 288 `/shop/` URLs on 2026-10-23 (`/sitemap/index.xml` lists the other sitemaps, including `brand.xml`).
  • Network accessline 23
    LISTING_URL = "https://www.ulta.com/shop/makeup/face/foundation"   # any /shop/... or /brand/... listing page MAX_PAGES = 3          # 64 products per page; a hard cap: hitting it with pages left prints PARTIAL UA = "browser-harness/1.0 (ul
  • Network accessline 28
    import gzip, json, sys, urllib.error, urllib.request url, ua = sys.argv[1], sys.argv[2] req = urllib.request.Request(url, headers={"User-Agent": ua, "Accept": "text/html", "Accept-Encoding": "gzip"})
  • Network accessline 29
    url, ua = sys.argv[1], sys.argv[2] req = urllib.request.Request(url, headers={"User-Agent": ua, "Accept": "text/html", "Accept-Encoding": "gzip"}) try:
  • Network accessline 30
    req = urllib.request.Request(url, headers={"User-Agent": ua, "Accept": "text/html", "Accept-Encoding": "gzip"})
  • Network accessline 31
    try:     with urllib.request.urlopen(req) as r:         status, final, body, enc = r.status, r.geturl(), r.read(), r.headers.get("Content-Encoding")
  • Network accessline 32
    with urllib.request.urlopen(req) as r:
  • Network accessline 54
    def fetch(url, deadline_s=120):
  • Network accessline 102
    parts = urllib.parse.urlsplit(LISTING_URL) if parts.netloc != "www.ulta.com" or not re.match(r"^/(shop|brand)/", parts.path) or parts.query:     raise SystemExit("LISTING_URL must be https://www.ulta.com/shop/... or /brand/... with no query
  • Network accessline 104
    raise SystemExit("LISTING_URL must be https://www.ulta.com/shop/... or /brand/... with no query string")
  • Network accessline 111
    time.sleep(3)   # polite pacing between pages     url = LISTING_URL if page == 1 else f"{LISTING_URL}?page={page}"     plr = find_module(apollo_state(fetch(url)), "ProductListingResults")
  • Network accessline 112
    url = LISTING_URL if page == 1 else f"{LISTING_URL}?page={page}"     plr = find_module(apollo_state(fetch(url)), "ProductListingResults")     if plr is None:
  • Network accessline 113
    plr = find_module(apollo_state(fetch(url)), "ProductListingResults")
  • Network accessline 114
    if plr is None:         raise RuntimeError(f"{url} has no ProductListingResults module: a department landing page? "                            "Use a deeper /shop/... URL from https://www.ulta.com/sitemap/shop.xml")
  • Network accessline 115
    raise RuntimeError(f"{url} has no ProductListingResults module: a department landing page? "                            "Use a deeper /shop/... URL from https://www.ulta.com/sitemap/shop.xml")     if plr.get("page") != page:
  • Network accessline 116
    "Use a deeper /shop/... URL from https://www.ulta.com/sitemap/shop.xml")
  • Network accessline 174
    page 1: 64 items, 64 unique so far, resultCount 254, next https://www.ulta.com/shop/makeup/face/foundation?page=2
  • Network accessline 175
    page 2: 64 items, 128 unique so far, resultCount 254, next https://www.ulta.com/shop/makeup/face/foundation?page=3
  • Network accessline 176
    page 3: 64 items, 192 unique so far, resultCount 254, next https://www.ulta.com/shop/makeup/face/foundation?page=4
  • Network accessline 177
    PARTIAL: stopped at MAX_PAGES=3 with 192 of 254 rows; more pages exist (next https://www.ulta.com/shop/makeup/face/foundation?page=4). Raise MAX_PAGES to collect them.
  • Network accessline 190
    "promo": "Bundle & Save!",   "sponsored": false,   "url": "https://www.ulta.com/p/double-wear-stay-in-place-longwear-matte-foundation-pimprod2057355?sku=2651970",
  • Network accessline 191
    "sponsored": false,   "url": "https://www.ulta.com/p/double-wear-stay-in-place-longwear-matte-foundation-pimprod2057355?sku=2651970",   "image": "https://media.ultainc.com/i/ulta/2651970"
  • Network accessline 192
    "url": "https://www.ulta.com/p/double-wear-stay-in-place-longwear-matte-foundation-pimprod2057355?sku=2651970",
  • Network accessline 193
    "image": "https://media.ultainc.com/i/ulta/2651970"
  • Network accessline 283
    if "/search/no-results" in href:             return None         if href and not href.startswith(("https://www.ulta.com/search?", "about:blank")):
  • Network accessline 284
    return None         if href and not href.startswith(("https://www.ulta.com/search?", "about:blank")):             raise SystemExit(f"Ulta redirected the search to {href} (brand or category page): "
  • Network accessline 285
    if href and not href.startswith(("https://www.ulta.com/search?", "about:blank")):
  • Network accessline 301
    url = "https://www.ulta.com/search?" + urllib.parse.urlencode({"search": QUERY})
  • Network accessline 344
    page 2: 64 cards, 64 kept, 125 total, heading '400+ results for "mascara"' page 3: 64 cards, 64 kept, 189 total, heading '400+ results for "mascara"' PARTIAL: stopped at MAX_PAGES=3 with 189 rows; the page still has a Load More link (https:
  • Network accessline 345
    page 3: 64 cards, 64 kept, 189 total, heading '400+ results for "mascara"' PARTIAL: stopped at MAX_PAGES=3 with 189 rows; the page still has a Load More link (https://www.ulta.com/search?search=mascara&page=4), heading '400+ results for "ma
  • Network accessline 346
    PARTIAL: stopped at MAX_PAGES=3 with 189 rows; the page still has a Load More link (https://www.ulta.com/search?search=mascara&page=4), heading '400+ results for "mascara"'. Raise MAX_PAGES to collect more.
  • Network accessline 360
    "sponsored": false,   "tags": ["Free Gift with purchase"],   "url": "https://www.ulta.com/p/lash-sensational-sky-high-mascara-pimprod2020260?sku=2574523"
  • Network accessline 361
    "tags": ["Free Gift with purchase"],   "url": "https://www.ulta.com/p/lash-sensational-sky-high-mascara-pimprod2020260?sku=2574523"  },
  • Network accessline 362
    "url": "https://www.ulta.com/p/lash-sensational-sky-high-mascara-pimprod2020260?sku=2574523"
  • Network accessline 368
    The search heading only says `400+`, so with a Load More link still present the block prints `PARTIAL` and sets `complete = False`; it does not guess a total. Earlier runs of the same query gave 73/73/64, 74/75/64, 74/73/64 (2026-10-23) and
  • Network accessline 375
    PRODUCT_URL = "https://www.ulta.com/p/double-wear-stay-in-place-longwear-matte-foundation-pimprod2057355?sku=2651970"   # any /p/... URL from block 1 or 2 UA = "browser-harness/1.0 (ulta domain skill; plain urllib)"
  • Network accessline 379
    import gzip, json, sys, urllib.error, urllib.request url, ua = sys.argv[1], sys.argv[2] req = urllib.request.Request(url, headers={"User-Agent": ua, "Accept": "text/html", "Accept-Encoding": "gzip"})
  • Network accessline 380
    url, ua = sys.argv[1], sys.argv[2] req = urllib.request.Request(url, headers={"User-Agent": ua, "Accept": "text/html", "Accept-Encoding": "gzip"}) try:
  • Network accessline 381
    req = urllib.request.Request(url, headers={"User-Agent": ua, "Accept": "text/html", "Accept-Encoding": "gzip"})
  • Network accessline 382
    try:     with urllib.request.urlopen(req) as r:         status, final, body, enc = r.status, r.geturl(), r.read(), r.headers.get("Content-Encoding")
  • Network accessline 383
    with urllib.request.urlopen(req) as r:
  • Network accessline 404
    def fetch(url, deadline_s=120):
  • Network accessline 445
    if not re.match(r"^https://www\.ulta\.com/p/[^?#]+$", PRODUCT_URL.split("?")[0]):
  • Network accessline 446
    raise SystemExit("PRODUCT_URL must be an https://www.ulta.com/p/... product URL")
  • Network accessline 448
    html = fetch(PRODUCT_URL)
  • Network accessline 536
    "ingredients": "Water\\Aqua\\Eau, Methyl Trimethicone, Dimethicone, Trimethylsiloxysilicate, Niacinamide, ...",  "attributes": {"Face Coverage": ["Medium"], "Face Finish": ["Natural"], "Face Form": ["Liquid"], "Skin Type": ["Combination", "
  • Network accessline 537
    "attributes": {"Face Coverage": ["Medium"], "Face Finish": ["Natural"], "Face Form": ["Liquid"], "Skin Type": ["Combination", "Dry", "Normal", "Oily", "Sensitive"]},  "images": ["https://media.ulta.com/i/ulta/2651970?w=500&h=500", "..._alt0
  • Network accessline 538
    "images": ["https://media.ulta.com/i/ulta/2651970?w=500&h=500", "..._alt01?w=500&h=500", ...],
  • Network accessline 581
    - **Unrated items.** 27 of 254 Foundation rows had no rating; search cards for unrated items have no ratings label, so `rating` and `review_count` are `None`. - **Selector drift (block 2 is the fragile part).** Search cards are read through
  • Network accessline 582
    - **Selector drift (block 2 is the fragile part).** Search cards are read through design-system class names: `.pal-c-ProductCardBody--brandName`, `--title`, `--price`, `.pal-c-Ratings`, `.pal-c-ProductCardHeader__variant`, `.pal-c-Tag__mess
  • Network accessline 583
    - **Region.** Ulta is a US storefront. Every load in this run, from the cloud browser and from plain HTTP, stayed on `https://www.ulta.com/` with no geo redirect, `lang="en-US"`, prices in `$` and JSON-LD `priceCurrency` `USD`; no country o
  • Access to secretsline 584
    [Credential-related source omitted]

agent-workspace/domain-skills/upwork/scraping.md

  • Network accessline 27
    BASE = "https://www.upwork.com"
  • Network accessline 215
    "workload": null,   "duration": "1 to 3 months",   "url": "https://www.upwork.com/freelance-jobs/apply/commerce-Product-Monitoring-System_~022112614550818987209/",
  • Network accessline 216
    "duration": "1 to 3 months",   "url": "https://www.upwork.com/freelance-jobs/apply/commerce-Product-Monitoring-System_~022112614550818987209/",   "detail_error": null
  • Network accessline 217
    "url": "https://www.upwork.com/freelance-jobs/apply/commerce-Product-Monitoring-System_~022112614550818987209/",
  • Network accessline 267
    Opening `https://www.upwork.com/o/jobs/browse/?q=<keyword>` (URL-encode the keyword with `quote(kw, safe='')`) in the browser redirected to the matching skill page for known skills (`shopify` -> `/freelance-jobs/shopify/`, `data entry` -> `
  • Network accessline 286
    | `workload` | detail `job.workload` / card `engagement` | `null` on fixed-price jobs | | `duration` | `durationLabel` | e.g. `"1 to 3 months"` | | `url` | `https://www.upwork.com` + card `url` | `/freelance-jobs/apply/<slug>_~<ciphertext>/
  • Network accessline 287
    | `duration` | `durationLabel` | e.g. `"1 to 3 months"` | | `url` | `https://www.upwork.com` + card `url` | `/freelance-jobs/apply/<slug>_~<ciphertext>/` | | `detail_error` | | `null` when the detail page was read; else why not (`"HTTP 403"
  • Network accessline 288
    | `url` | `https://www.upwork.com` + card `url` | `/freelance-jobs/apply/<slug>_~<ciphertext>/` |
  • Network accessline 300
    - **No consent banner or login wall** appeared on `/freelance-jobs/` pages in the cloud browser. - The HTTP status comes from `performance.getEntriesByType('navigation')[0].responseStatus` (Chrome 109+). - `js()` calls time out after 5 s, s
  • Network accessline 301
    - The HTTP status comes from `performance.getEntriesByType('navigation')[0].responseStatus` (Chrome 109+). - `js()` calls time out after 5 s, so do not run slow multi-request `fetch()` loops inside the page; navigate instead. - Pages are la
  • Network accessline 302
    - `js()` calls time out after 5 s, so do not run slow multi-request `fetch()` loops inside the page; navigate instead.

agent-workspace/domain-skills/vercel/archive-and-audit.md

  • Network accessline 7
    - Team overview: `https://vercel.com/<team>`.
  • Network accessline 8
    - Project overview: `https://vercel.com/<team>/<project>`.
  • Network accessline 9
    - Project analytics: `https://vercel.com/<team>/<project>/analytics`.
  • Network accessline 23
    A `.mp4` URL can return HTTP 200 with `Content-Type: video/mp4` but contain a **Git LFS pointer**, not video. The body starts with `version https://git-lfs.github.com/spec/v1` and is only about 130 bytes. Check bytes/magic and decode media,

agent-workspace/domain-skills/vercel/vercel.md

  • Access to secretsline 3
    [Credential-related source omitted]
  • Access to secretsline 5
    [Credential-related source omitted]
  • Network accessline 8
    import json cookies = cdp("Network.getCookies", urls=["https://vercel.com"])
  • Network accessline 9
    cookies = cdp("Network.getCookies", urls=["https://vercel.com"])
  • Network accessline 33
    resp = http_get(     "https://vercel.com/api/v6/deployments?limit=100&teamId=<team-slug>",
  • Network accessline 34
    "https://vercel.com/api/v6/deployments?limit=100&teamId=<team-slug>",
  • Network accessline 54
    data = json.loads(http_get(     "https://vercel.com/api/v9/projects?teamId=<team-slug>&limit=50",
  • Network accessline 55
    "https://vercel.com/api/v9/projects?teamId=<team-slug>&limit=50",
  • Network accessline 67
    uid = dep["uid"]   # e.g. "dpl_2tySoj6ceJkTgtsWHvd5r1Hpgyd1" — already includes dpl_ prefix resp = http_get(     "https://vercel.com/api/v3/deployments/" + uid + "/events?builds=1&limit=5000&teamId=<team-slug>",
  • Network accessline 68
    resp = http_get(     "https://vercel.com/api/v3/deployments/" + uid + "/events?builds=1&limit=5000&teamId=<team-slug>",     headers=headers
  • Network accessline 69
    "https://vercel.com/api/v3/deployments/" + uid + "/events?builds=1&limit=5000&teamId=<team-slug>",
  • Network accessline 89
    new_tab("https://vercel.com/dashboard")

agent-workspace/domain-skills/vinted/scraping.md

  • Network accessline 23
    BASE = "https://www.vinted.com"
  • Network accessline 106
    u = urllib.parse.urlparse(url)     if u.scheme != "https" or u.netloc != "www.vinted.com" or u.path != "/catalog":         raise ValueError(f"refusing {url}: only https://www.vinted.com/catalog?... pages are used")
  • Network accessline 107
    if u.scheme != "https" or u.netloc != "www.vinted.com" or u.path != "/catalog":         raise ValueError(f"refusing {url}: only https://www.vinted.com/catalog?... pages are used")     goto_url(url) if _tab["open"] else new_tab(url)
  • Network accessline 108
    raise ValueError(f"refusing {url}: only https://www.vinted.com/catalog?... pages are used")
  • Network accessline 168
    try:   # robots.txt disallows /member/: refused before the tab navigates     open_page("https://www.vinted.com/member/12345")
  • Network accessline 169
    open_page("https://www.vinted.com/member/12345")
  • Network accessline 179
    page 3: 96 rows, 84 new, total_entries=960, total_pages=10 269 listings, status: truncated_max_pages {"id": 10611858188, "title": "Nike Zip", "brand": "Nike", "size": "M / US 8-10", "condition": "Good", "price": 4.0, "discounted_price": nul
  • Network accessline 180
    269 listings, status: truncated_max_pages {"id": 10611858188, "title": "Nike Zip", "brand": "Nike", "size": "M / US 8-10", "condition": "Good", "price": 4.0, "discounted_price": null, "total_price": 4.9, "currency": "USD", "promoted": false
  • Network accessline 181
    {"id": 10611858188, "title": "Nike Zip", "brand": "Nike", "size": "M / US 8-10", "condition": "Good", "price": 4.0, "discounted_price": null, "total_price": 4.9, "currency": "USD", "promoted": false, "url": "https://www.vinted.com/items/106
  • Network accessline 182
    {"id": 10611815068, "title": "Nike Dri-Fit Tshirt", "brand": "Nike", "size": "M", "condition": "Very good", "price": 5.0, "discounted_price": null, "total_price": 5.95, "currency": "USD", "promoted": true, "url": "https://www.vinted.com/ite
  • Network accessline 185
    page 1: 96 rows, 96 new, total_entries=960, total_pages=10 96 listings, 23 without a brand {"id": 10610445929, "title": "True vintage handmade dress", "brand": null, "size": "XXS / US 0", "condition": "Very good", "price": 10.0, "discounted
  • Network accessline 186
    96 listings, 23 without a brand {"id": 10610445929, "title": "True vintage handmade dress", "brand": null, "size": "XXS / US 0", "condition": "Very good", "price": 10.0, "discounted_price": null, "total_price": 11.2, "currency": "USD", "pro
  • Network accessline 187
    {"id": 10610445929, "title": "True vintage handmade dress", "brand": null, "size": "XXS / US 0", "condition": "Very good", "price": 10.0, "discounted_price": null, "total_price": 11.2, "currency": "USD", "promoted": false, "url": "https://w
  • Network accessline 188
    page 1: 0 rows, 0 new, total_entries=0, total_pages=1 0 listings for a nonsense query, status: complete refused: refusing https://www.vinted.com/member/12345: only https://www.vinted.com/catalog?... pages are used
  • Network accessline 190
    refused: refusing https://www.vinted.com/member/12345: only https://www.vinted.com/catalog?... pages are used
  • Network accessline 222
    | `currency` | `price.currencyCode` | `USD` on www.vinted.com | | `promoted` | `isPromoted` | 87 of 384 sampled rows were promoted ("bumped") listings mixed into the results | | `url` | built from `id`: `https://www.vinted.com/items/<id>` |
  • Network accessline 223
    | `promoted` | `isPromoted` | 87 of 384 sampled rows were promoted ("bumped") listings mixed into the results | | `url` | built from `id`: `https://www.vinted.com/items/<id>` | redirects to the canonical slug URL; the slug repeats the selle
  • Network accessline 224
    | `url` | built from `id`: `https://www.vinted.com/items/<id>` | redirects to the canonical slug URL; the slug repeats the seller-written title, so it is left out |
  • Network accessline 235
    - Promoted ("bumped") rows sit inside the normal result order (28 of 96 on each of two `nike` pages); filter on `promoted` if you want organic rows only. - `EXTRACT` returns `error` on a DataDome challenge frame (`captcha-delivery.com`); th
  • Network accessline 237
    - The code refuses any URL other than `https://www.vinted.com/catalog?...` before navigating, refuses a page whose URL differs from the one requested, and refuses a row whose label and tile text disagree.

agent-workspace/domain-skills/walmart/scraping.md

  • Network accessline 36
    Raises RuntimeError if PerimeterX bot challenge is returned.     """     req = urllib.request.Request(
  • Network accessline 37
    """     req = urllib.request.Request(         url,
  • Network accessline 38
    req = urllib.request.Request(
  • Network accessline 40
    headers={"User-Agent": "Mozilla/5.0", "Accept-Encoding": "gzip"},     )     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 41
    )     with urllib.request.urlopen(req, timeout=20) as r:         data = r.read()
  • Network accessline 42
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 65
    # Keyword search "https://www.walmart.com/search?q=laptop"
  • Network accessline 66
    "https://www.walmart.com/search?q=laptop"
  • Network accessline 68
    # Pagination — append &page=N "https://www.walmart.com/search?q=laptop&page=2"
  • Network accessline 69
    "https://www.walmart.com/search?q=laptop&page=2"
  • Network accessline 71
    # Sort options (confirmed working) "https://www.walmart.com/search?q=laptop&sort=best_match"    # default
  • Network accessline 72
    "https://www.walmart.com/search?q=laptop&sort=best_match"    # default
  • Network accessline 73
    "https://www.walmart.com/search?q=laptop&sort=best_seller"
  • Network accessline 74
    "https://www.walmart.com/search?q=laptop&sort=price_low"
  • Network accessline 75
    "https://www.walmart.com/search?q=laptop&sort=customer_rating"
  • Network accessline 77
    # Price filter "https://www.walmart.com/search?q=laptop&min_price=200&max_price=500"
  • Network accessline 78
    "https://www.walmart.com/search?q=laptop&min_price=200&max_price=500"
  • Network accessline 80
    # Browse by category (department ID path) "https://www.walmart.com/browse/electronics/laptops/3944_1089430_3951"
  • Network accessline 81
    "https://www.walmart.com/browse/electronics/laptops/3944_1089430_3951"
  • Network accessline 123
    "availability":    avail.get("value"),             # "IN_STOCK" / "OUT_OF_STOCK"                 "isSponsored":     bool(item.get("isSponsoredFlag")),                 "url":             "https://www.walmart.com" + (item.get("canonicalUrl") 
  • Network accessline 124
    "isSponsored":     bool(item.get("isSponsoredFlag")),                 "url":             "https://www.walmart.com" + (item.get("canonicalUrl") or "").split("?")[0],                 "thumbnailUrl":    img.get("thumbnailUrl"),
  • Network accessline 125
    "url":             "https://www.walmart.com" + (item.get("canonicalUrl") or "").split("?")[0],
  • Network accessline 134
    # Usage html = fetch_walmart("https://www.walmart.com/search?q=laptop")
  • Network accessline 135
    html = fetch_walmart("https://www.walmart.com/search?q=laptop")
  • Network accessline 161
    for page in range(1, max_page + 1):     html = fetch_walmart(f"https://www.walmart.com/search?q=laptop&page={page}")
  • Network accessline 162
    html = fetch_walmart(f"https://www.walmart.com/search?q=laptop&page={page}")
  • Network accessline 177
    https://www.walmart.com/ip/{slug}/{usItemId}
  • Network accessline 183
    https://www.walmart.com/ip/anything/19717318352
  • Network accessline 184
    https://www.walmart.com/ip/Apple-MacBook-Neo/19717318352
  • Network accessline 267
    ],         # URL         "canonicalUrl":        "https://www.walmart.com" + (product.get("canonicalUrl") or ""),
  • Network accessline 268
    # URL         "canonicalUrl":        "https://www.walmart.com" + (product.get("canonicalUrl") or ""),         # fulfillment
  • Network accessline 269
    "canonicalUrl":        "https://www.walmart.com" + (product.get("canonicalUrl") or ""),
  • Network accessline 283
    # Usage url = "https://www.walmart.com/ip/Apple-MacBook-Neo/19717318352"
  • Network accessline 284
    url = "https://www.walmart.com/ip/Apple-MacBook-Neo/19717318352"
  • Network accessline 386
    # Browser-based search extraction new_tab("https://www.walmart.com/search?q=laptop")
  • Network accessline 387
    new_tab("https://www.walmart.com/search?q=laptop")
  • Network accessline 428
    new_tab("https://www.walmart.com/search?q=laptop")

agent-workspace/domain-skills/wayback-machine/scraping.md

  • Network accessline 3
    `https://web.archive.org` — all public data, no auth or API key required. Everything here is pure `http_get` — no browser needed.
  • Network accessline 14
    # Find all snapshots of a URL — the minimal starting query r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 15
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=example.com&output=json&limit=10"
  • Network accessline 16
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 22
    # rows[0] is ALWAYS the header row — slice rows[1:] for data for ts, orig, status, mime, length in rows[1:]:     print(f"https://web.archive.org/web/{ts}/{orig}  [{status}]")
  • Network accessline 24
    print(f"https://web.archive.org/web/{ts}/{orig}  [{status}]")
  • Network accessline 38
    r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 39
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 45
    rows = json.loads(r) ts, orig, status = rows[1]   # rows[0] is header snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 46
    ts, orig, status = rows[1]   # rows[0] is header snap_url = f"https://web.archive.org/web/{ts}/{orig}" # Timestamp format: 14-digit YYYYMMDDHHMMSS
  • Network accessline 47
    snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 57
    r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 58
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 65
    rows = json.loads(r) for ts, orig, status in rows[1:]:     print(f"{ts[:4]}-{ts[4:6]}  https://web.archive.org/web/{ts}/{orig}")
  • Network accessline 67
    print(f"{ts[:4]}-{ts[4:6]}  https://web.archive.org/web/{ts}/{orig}")
  • Network accessline 82
    # matchType=prefix — all URLs starting with the given path r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 83
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=example.com/blog/&matchType=prefix&output=json"
  • Network accessline 84
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 106
    # Only successful HTML captures — combine multiple filters r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 107
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=example.com&output=json"
  • Network accessline 108
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 131
    | `urlkey` | SURT-format URL (reversed domain) | `com,example)/` | | `timestamp` | Capture time, 14-digit `YYYYMMDDHHMMSS` | `20230601114925` | | `original` | Original crawled URL (includes port if non-standard) | `https://example.com/` |
  • Network accessline 132
    | `timestamp` | Capture time, 14-digit `YYYYMMDDHHMMSS` | `20230601114925` | | `original` | Original crawled URL (includes port if non-standard) | `https://example.com/` | | `mimetype` | Content-Type at crawl time | `text/html` |
  • Network accessline 133
    | `original` | Original crawled URL (includes port if non-standard) | `https://example.com/` |
  • Network accessline 152
    # Left here for reference only — do not rely on it: r = http_get(     "https://archive.org/wayback/available"
  • Network accessline 153
    r = http_get(     "https://archive.org/wayback/available"     "?url=example.com&timestamp=20240101",
  • Network accessline 154
    "https://archive.org/wayback/available"
  • Network accessline 162
    # CORRECT replacement: r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 163
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=example.com&output=json&limit=1"
  • Network accessline 164
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 171
    if len(rows) > 1:     ts, orig, status = rows[1]     snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 173
    snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 185
    """Yield all CDX rows for a URL, page by page."""     base = (         "https://web.archive.org/cdx/search/cdx"
  • Network accessline 186
    base = (         "https://web.archive.org/cdx/search/cdx"         f"?url={quote(url, safe='')}&output=json"
  • Network accessline 187
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 204
    for ts, orig, status in cdx_all_snapshots("example.com"):     snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 205
    snap_url = f"https://web.archive.org/web/{ts}/{orig}"
  • Network accessline 214
    # Direct snapshot URL: /web/{14-digit-timestamp}/{original-url} snap_url = "https://web.archive.org/web/20230601114925/https://example.com/"
  • Network accessline 215
    snap_url = "https://web.archive.org/web/20230601114925/https://example.com/"
  • Network accessline 221
    # Canonical form for "get latest available" — use 14 zeros: latest = "https://web.archive.org/web/20240101000000*/example.com"
  • Network accessline 222
    latest = "https://web.archive.org/web/20240101000000*/example.com" # The * suffix returns a calendar page (HTML), not the archived page itself. # Use CDX to find the real timestamp, then fetch the direct URL.
  • Network accessline 234
    # Find only snapshots where the content CHANGED — dedup by SHA-1 digest r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 235
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=example.com&output=json"
  • Network accessline 236
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 256
    # Use for estimating result size before a full fetch r = http_get(     "https://web.archive.org/cdx/search/cdx"
  • Network accessline 257
    r = http_get(     "https://web.archive.org/cdx/search/cdx"     "?url=example.com&matchType=prefix"
  • Network accessline 258
    "https://web.archive.org/cdx/search/cdx"
  • Network accessline 274
    |---|---|---|---| | CDX search | 5–40s | 60s | Intermittently slow; retry on timeout | | Snapshot fetch (`/web/`) | 2–10s | 30s | Reliable |
  • Network accessline 275
    | CDX search | 5–40s | 60s | Intermittently slow; retry on timeout | | Snapshot fetch (`/web/`) | 2–10s | 30s | Reliable | | Metadata (`/metadata/`) | <1s | 20s | Fast, stable |
  • Network accessline 276
    | Snapshot fetch (`/web/`) | 2–10s | 30s | Reliable |
  • Network accessline 296
    - **`original` preserves non-standard ports.** Old crawls captured `http://www.example.com:80/` — the `:80` is part of the `original` field. Build playback URLs verbatim: `f"https://web.archive.org/web/{ts}/{orig}"` works correctly with the

agent-workspace/domain-skills/weather/scraping.md

  • Network accessline 23
    import json data = json.loads(http_get("https://wttr.in/San+Francisco?format=j1"))
  • Network accessline 24
    data = json.loads(http_get("https://wttr.in/San+Francisco?format=j1"))
  • Network accessline 71
    import json geo = json.loads(http_get("https://geocoding-api.open-meteo.com/v1/search?name=Chicago&count=1"))
  • Network accessline 72
    geo = json.loads(http_get("https://geocoding-api.open-meteo.com/v1/search?name=Chicago&count=1"))
  • Network accessline 86
    data = json.loads(http_get(     f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 87
    f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 122
    data = json.loads(http_get(     f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 123
    f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 160
    data = json.loads(http_get(     f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 161
    f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 190
    data = json.loads(http_get(     "https://archive-api.open-meteo.com/v1/archive"
  • Network accessline 191
    "https://archive-api.open-meteo.com/v1/archive"
  • Network accessline 225
    "Accept": "application/geo+json",     }     req = urllib.request.Request(url, headers=h)
  • Network accessline 226
    }     req = urllib.request.Request(url, headers=h)     with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 227
    req = urllib.request.Request(url, headers=h)
  • Network accessline 228
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 234
    # Call 1: resolve lat/lon to forecast office + grid cell (~90ms) pts  = json.loads(nws_get("https://api.weather.gov/points/37.7749,-122.4194"))
  • Network accessline 235
    pts  = json.loads(nws_get("https://api.weather.gov/points/37.7749,-122.4194"))
  • Network accessline 303
    # 1. Geocode     geo  = json.loads(http_get(         f"https://geocoding-api.open-meteo.com/v1/search?name={city.replace(' ', '+')}&count=1"
  • Network accessline 304
    geo  = json.loads(http_get(         f"https://geocoding-api.open-meteo.com/v1/search?name={city.replace(' ', '+')}&count=1"     ))
  • Network accessline 305
    f"https://geocoding-api.open-meteo.com/v1/search?name={city.replace(' ', '+')}&count=1"
  • Network accessline 312
    # 2. Forecast (single call: current + daily)     data = json.loads(http_get(         f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 313
    data = json.loads(http_get(         f"https://api.open-meteo.com/v1/forecast"         f"?latitude={lat}&longitude={lon}"
  • Network accessline 314
    f"https://api.open-meteo.com/v1/forecast"
  • Network accessline 352
    def http_get_wttr(url):     req = urllib.request.Request(url, headers={"User-Agent": "Wget/1.21", "Accept": "*/*"})
  • Network accessline 353
    req = urllib.request.Request(url, headers={"User-Agent": "Wget/1.21", "Accept": "*/*"})
  • Network accessline 354
    with urllib.request.urlopen(req, timeout=20) as r:
  • Network accessline 360
    # Text format tokens (URL-encode %): %25l=location, %25C=condition desc, # %25t=temp, %25f=feels-like, %25h=humidity, %25w=wind print(http_get_wttr("https://wttr.in/London?format=%25t"))           # '+55°F'
  • Network accessline 361
    # %25t=temp, %25f=feels-like, %25h=humidity, %25w=wind print(http_get_wttr("https://wttr.in/London?format=%25t"))           # '+55°F' print(http_get_wttr("https://wttr.in/Tokyo?format=3"))               # 'tokyo: ☀<U+FE0F>   +69°F'
  • Network accessline 362
    print(http_get_wttr("https://wttr.in/London?format=%25t"))           # '+55°F'
  • Network accessline 363
    print(http_get_wttr("https://wttr.in/Tokyo?format=3"))               # 'tokyo: ☀<U+FE0F>   +69°F'
  • Network accessline 364
    print(http_get_wttr("https://wttr.in/Berlin?format=%25l:+%25C+%25t+(feels+%25f)+%25h+%25w"))

agent-workspace/domain-skills/wehotel/hotels.md

  • Access to secretsline 16
    [Credential-related source omitted]
  • Network accessline 28
    List page:   https://www.bestwehotel.com/HotelSearch/
  • Network accessline 29
    https://www.bestwehotel.com/HotelSearch/
  • Network accessline 37
    Hotel detail page:   https://www.bestwehotel.com/HotelDetail/
  • Network accessline 38
    https://www.bestwehotel.com/HotelDetail/
  • Network accessline 62
    new_tab("https://www.bestwehotel.com/")
  • Network accessline 80
    url = (     "https://www.bestwehotel.com/HotelSearch/"
  • Network accessline 81
    "https://www.bestwehotel.com/HotelSearch/"
  • Network accessline 236
    url = (     "https://www.bestwehotel.com/HotelSearch/"
  • Network accessline 237
    "https://www.bestwehotel.com/HotelSearch/"

agent-workspace/domain-skills/wellfound/scraping.md

  • Network accessline 60
    new_tab("https://wellfound.com/company/stripe")
  • Network accessline 87
    | Goal | URL | |------|-----| | Company profile | `https://wellfound.com/company/{slug}` |
  • Network accessline 88
    |------|-----| | Company profile | `https://wellfound.com/company/{slug}` | | Company jobs | `https://wellfound.com/company/{slug}/jobs` |
  • Network accessline 89
    | Company profile | `https://wellfound.com/company/{slug}` |
  • Network accessline 90
    | Company jobs | `https://wellfound.com/company/{slug}/jobs` |
  • Network accessline 91
    | Company culture | `https://wellfound.com/company/{slug}/culture` |
  • Network accessline 92
    | Job board (all) | `https://wellfound.com/jobs` |
  • Network accessline 93
    | Job board filtered | `https://wellfound.com/jobs` — then use UI filters (query params are disallowed by robots.txt) |
  • Network accessline 94
    | Investor profile | `https://wellfound.com/investor/{slug}` |
  • Network accessline 95
    | User profile | `https://wellfound.com/u/{username}` (disallowed by robots.txt, login wall) |
  • Network accessline 109
    new_tab("https://wellfound.com/company/stripe")
  • Network accessline 213
    company_slug = "stripe" new_tab(f"https://wellfound.com/company/{company_slug}/jobs")
  • Network accessline 214
    new_tab(f"https://wellfound.com/company/{company_slug}/jobs")
  • Network accessline 260
    new_tab("https://wellfound.com/jobs")
  • Access to secretsline 304
    [Credential-related source omitted]
  • Network accessline 313
    # Step 1: Load any Wellfound page so the session cookie + DataDome cookie are set new_tab("https://wellfound.com/")
  • Network accessline 314
    new_tab("https://wellfound.com/")
  • Network accessline 325
    # Step 3: Execute GraphQL query via fetch() from within the browser
  • Access to secretsline 326
    [Credential-related source omitted]
  • Network accessline 328
    (async function() {{   try {{     var resp = await fetch('/graphql', {{
  • Network accessline 329
    try {{     var resp = await fetch('/graphql', {{       method: 'POST',
  • Network accessline 330
    var resp = await fetch('/graphql', {{
  • Network accessline 370
    result_sync = js(""" var done = false, out = null; fetch('/graphql', {
  • Network accessline 371
    var done = false, out = null; fetch('/graphql', {   method: 'POST',
  • Network accessline 372
    fetch('/graphql', {
  • Network accessline 468
    # Usage new_tab("https://wellfound.com/company/stripe")
  • Network accessline 469
    new_tab("https://wellfound.com/company/stripe")
  • Network accessline 519
    [Credential-related source omitted]
  • Access to secretsline 519
    [Credential-related source omitted]
  • Network accessline 520
    per-session value from `<meta name="csrf-token">`. Cloudflare Bot Management blocks    `POST /graphql` from non-browser sessions. Always fire GraphQL via `fetch()` inside the    browser session (not from Python's `http_get`).
  • Network accessline 521
    `POST /graphql` from non-browser sessions. Always fire GraphQL via `fetch()` inside the
  • Network accessline 546
    <!-- DataDome challenge (page GETs) --> <script>var dd={'rt':'c','cid':'...','t':'bv','host':'geo.captcha-delivery.com',...}</script> <script src="https://ct.captcha-delivery.com/c.js"></script>
  • Network accessline 547
    <script>var dd={'rt':'c','cid':'...','t':'bv','host':'geo.captcha-delivery.com',...}</script> <script src="https://ct.captcha-delivery.com/c.js"></script> <!-- rt='c' = captcha required; rt='i' = invisible solve; rt='b' = blocked -->
  • Network accessline 548
    <script src="https://ct.captcha-delivery.com/c.js"></script>
  • Network accessline 565
    # Open Wellfound company page new_tab("https://wellfound.com/company/openai")
  • Network accessline 566
    new_tab("https://wellfound.com/company/openai")

agent-workspace/domain-skills/weread/read.md

  • Network accessline 30
    | Page | URL | |------|-----| | Home | `https://weread.qq.com/` |
  • Network accessline 31
    |------|-----| | Home | `https://weread.qq.com/` | | Rising | `https://weread.qq.com/web/category/rising` |
  • Network accessline 32
    | Home | `https://weread.qq.com/` |
  • Network accessline 33
    | Rising | `https://weread.qq.com/web/category/rising` |
  • Network accessline 34
    | Hot Search | `https://weread.qq.com/web/category/hot_search` |
  • Network accessline 35
    | New Book | `https://weread.qq.com/web/category/newbook` |
  • Network accessline 36
    | Book Detail | `https://weread.qq.com/web/bookDetail/{BOOK_ID}` |
  • Network accessline 37
    | Reader | `https://weread.qq.com/web/reader/{BOOK_ID}k{CHAPTER_HASH}` |
  • Network accessline 42
    https://weread.qq.com/web/reader/{BOOK_ID}k{CHAPTER_HASH}
  • Network accessline 66
    1. Navigate to `https://weread.qq.com/`
  • Network accessline 165
    def pick_book_from_new_ranking():     # Navigate to New Book ranking     new_tab("https://weread.qq.com/web/category/newbook")
  • Network accessline 166
    # Navigate to New Book ranking     new_tab("https://weread.qq.com/web/category/newbook")     wait_for_load()
  • Network accessline 167
    new_tab("https://weread.qq.com/web/category/newbook")

agent-workspace/domain-skills/wikipedia/scraping.md

  • Network accessline 9
    - **Article page** (`/wiki/<Title>`, block 1): one `js()` call returns title, page id, revision, Wikidata id, short description, lead text, every section (level, heading, anchor, plain text), the infobox as label/value rows under their head
  • Network accessline 10
    - **Redirects, disambiguation, missing pages** are reported, not guessed: `/wiki/Ada_Byron` serves Ada Lovelace with `redirected_from: "Ada_Byron"`; `Mercury` has `disambiguation: true`; an unknown title returns `missing: true` (`wgArticleI
  • Network accessline 11
    - **Official API** (block 2, same-origin `fetch()` from a Wikipedia tab): search, batch metadata for up to 50 titles per call (redirects, disambiguation, short description, Wikidata id), the whole article as plain text split into sections (
  • Network accessline 25
    BASE = "https://en.wikipedia.org"
  • Network accessline 180
    lead: 3186 chars: Augusta Ada King, Countess of Lovelace (née Byron; 10 December 1815 – 27 November 1852), also known as Ada Lovelace, was   sections: 29 [(2, 'Biography', 0), (3, 'Childhood', 3977), (3, 'Adult years', 4032), (3, 'Education
  • Network accessline 181
    sections: 29 [(2, 'Biography', 0), (3, 'Childhood', 3977), (3, 'Adult years', 4032), (3, 'Education', 1721), (3, 'Death', 756)] ... last: [('General and cited sources', 0), ('Further reading', 569), ('External links', 1451)]   infobox: info
  • Network accessline 182
    infobox: infobox biography vcard | 'The Right Honourable\nThe Countess of Lovelace' | 7 rows | image: https://thumb.wikimedia.org/wikipedia/commons/thumb/4/4c/Ada_Lovelace_
  • Network accessline 187
    lead: 3760 chars: Tokyo, officially the Tokyo Metropolis, is the capital and most populous city of Japan. The population of the city prope   sections: 61 [(2, 'Etymology', 910), (2, 'History', 0), (3, 'Pre-Tokugawa period', 1595), (3, '1590
  • Network accessline 188
    sections: 61 [(2, 'Etymology', 910), (2, 'History', 0), (3, 'Pre-Tokugawa period', 1595), (3, '1590–1868: Tokugawa period', 1921), (3, '1868–1941', 3062)] ... last: [('Guides', 258), ('Contemporary', 1395), ('External links', 73)]   infobox
  • Network accessline 189
    infobox: infobox ib-settlement vcard | 'Tokyo\n東京都' | 35 rows | image: https://thumb.wikimedia.org/wikipedia/commons/thumb/b/b2/Skyscrapers_o
  • Network accessline 197
    lead: 4209 chars: Barack Hussein Obama II (born August 4, 1961) is an American retired politician who served as the 44th president of the   sections: 48 [(2, 'Early life and career', 2730), (3, 'Education', 2203), (4, 'College and research 
  • Network accessline 198
    sections: 48 [(2, 'Early life and career', 2730), (3, 'Education', 2203), (4, 'College and research jobs', 1040), (4, 'Community organizer and Harvard Law School', 1701), (4, 'University of Chicago Law School', 682)] ... last: [('External l
  • Network accessline 199
    infobox: infobox vcard | 'Barack Obama' | 20 rows | image: https://thumb.wikimedia.org/wikipedia/commons/thumb/8/8d/President_Bar
  • Network accessline 213
    Self-contained. Opens `/wiki/Main_Page` once so `fetch()` is same-origin, then calls only `/w/api.php` and `/api/rest_v1/`.
  • Network accessline 219
    BASE = "https://en.wikipedia.org"
  • Network accessline 220
    # Wikimedia asks API clients to identify themselves; from a browser, Api-User-Agent is the header for that. # The browser's own User-Agent is left untouched. HEADERS = {"Api-User-Agent": "browser-harness-wikipedia-skill/1.0 (https://github.
  • Network accessline 222
    HEADERS = {"Api-User-Agent": "browser-harness-wikipedia-skill/1.0 (https://github.com/browser-use/browser-harness)"}
  • Network accessline 224
    # Same-origin fetch() needs a tab on en.wikipedia.org; /wiki/Main_Page is allowed by robots.txt.
  • Network accessline 228
    def _fetch(url):     raw = js("""(async () => { const r = await fetch(%s, {headers: %s});
  • Network accessline 229
    raw = js("""(async () => { const r = await fetch(%s, {headers: %s});

agent-workspace/domain-skills/world-bank/scraping.md

  • Network accessline 3
    `https://api.worldbank.org/v2` — free REST API for global development indicators. No API key, no auth, no browser needed. All data via `http_get`.
  • Network accessline 13
    raw = http_get("https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD?format=json")
  • Network accessline 29
    raw = http_get("https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD?format=json")
  • Network accessline 51
    raw = http_get(     "https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD"
  • Network accessline 52
    "https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD"
  • Network accessline 74
    raw = http_get(     "https://api.worldbank.org/v2/country/US;CN;GB/indicator/SP.POP.TOTL"
  • Network accessline 75
    "https://api.worldbank.org/v2/country/US;CN;GB/indicator/SP.POP.TOTL"
  • Network accessline 97
    raw = http_get(     "https://api.worldbank.org/v2/country/all/indicator/NY.GDP.PCAP.CD"
  • Network accessline 98
    "https://api.worldbank.org/v2/country/all/indicator/NY.GDP.PCAP.CD"
  • Network accessline 135
    # Example: all US GDP data (66 years, 2 pages) rows = fetch_all_pages(     "https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD"
  • Network accessline 136
    rows = fetch_all_pages(     "https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD"     "?format=json&per_page=50"
  • Network accessline 137
    "https://api.worldbank.org/v2/country/US/indicator/NY.GDP.MKTP.CD"
  • Network accessline 151
    raw = http_get("https://api.worldbank.org/v2/indicator?format=json&per_page=50")
  • Network accessline 169
    # Topic 3 = Economy & Growth raw = http_get("https://api.worldbank.org/v2/topic/3/indicator?format=json&per_page=50")
  • Network accessline 170
    raw = http_get("https://api.worldbank.org/v2/topic/3/indicator?format=json&per_page=50")
  • Network accessline 184
    raw = http_get("https://api.worldbank.org/v2/country/US?format=json")
  • Network accessline 190
    # Filter countries by income level raw = http_get("https://api.worldbank.org/v2/country?format=json&incomeLevel=LIC&per_page=300")
  • Network accessline 191
    raw = http_get("https://api.worldbank.org/v2/country?format=json&incomeLevel=LIC&per_page=300")
  • Network accessline 202
    raw = http_get("https://api.worldbank.org/v2/topics?format=json")
  • Network accessline 225
    def fetch_indicator(ind_id):     url = (         f"https://api.worldbank.org/v2/country/US/indicator/{ind_id}"
  • Network accessline 226
    url = (         f"https://api.worldbank.org/v2/country/US/indicator/{ind_id}"         f"?format=json&mrv=5"
  • Network accessline 227
    f"https://api.worldbank.org/v2/country/US/indicator/{ind_id}"
  • Network accessline 247
    https://api.worldbank.org/v2
  • Network accessline 293
    Find more: `https://api.worldbank.org/v2/indicator?format=json&per_page=50&page=N`
  • Network accessline 344
    - **HTTP 302 redirects HTTP to HTTPS.** Always use `https://` directly to avoid an extra round trip.

agent-workspace/domain-skills/x/article-source-recovery.md

  • Network accessline 16
    Article cards commonly point to `https://x.com/i/article/<id>`. An anonymous visit to that route may redirect to `x.com/i/jf/onboarding/web?...mode=login`; do not interpret this as evidence that the status itself is private or deleted.
  • Network accessline 35
    LinkedIn wraps external links as `https://www.linkedin.com/redir/redirect?url=<encoded-url>&...`. Decode the `url` query parameter, open that canonical URL directly, and validate the article title and content there.

agent-workspace/domain-skills/x/posting.md

  • Network accessline 5
    Navigate to `https://x.com/i/flow/login` (not `https://x.com/`) to get the full sign-in modal. The homepage may render a truncated version of the auth buttons.
  • Network accessline 15
    Use the standard form on `https://x.com/i/flow/login`. Ask the user for credentials — do not guess or read them from screenshots.
  • Network accessline 19
    Once logged in, the home feed is at `https://x.com/home`.

agent-workspace/domain-skills/xiaohongshu/scraping.md

  • Network accessline 3
    URL patterns: - Home / discovery: `https://www.xiaohongshu.com/explore`
  • Network accessline 4
    - Home / discovery: `https://www.xiaohongshu.com/explore`
  • Network accessline 5
    - Search results: `https://www.xiaohongshu.com/search_result?keyword=...`
  • Network accessline 9
    - Prefer direct navigation to the desktop search results page over automating the home-page search box. - Reliable primary path: `https://www.xiaohongshu.com/search_result?keyword=<url-encoded keyword>&source=web_explore_feed`
  • Network accessline 10
    - Reliable primary path: `https://www.xiaohongshu.com/search_result?keyword=<url-encoded keyword>&source=web_explore_feed`
  • Network accessline 65
    - Do **not** assume a raw results link like `https://www.xiaohongshu.com/explore/<id>` is directly openable.
  • Network accessline 66
    - Opening that raw `/explore/<id>` URL in a fresh tab can redirect to the web `404` / app-only gate even when the same post is openable from search results. - To open a post from search results, click the visible card image / card in-page f
  • Network accessline 67
    [Credential-related source omitted]
  • Network accessline 68
    [Credential-related source omitted]
  • Network accessline 69
    - Once the tokenized URL is obtained from the click flow, it can be revisited in-session for extraction. - If the search results state is already loaded, you can reconstruct the tokenized note URL directly from a feed item without re-clicki
  • Network accessline 71
    [Credential-related source omitted]

agent-workspace/domain-skills/yahoo-finance/scraping.md

  • Network accessline 9
    - **Quote summary**: open `https://finance.yahoo.com/quote/<T>/` in a browser and read the DOM. Price, change and change % are `[data-testid="qsp-price"]`, `qsp-price-change`, `qsp-price-change-percent`; after-hours/pre-market values are th
  • Network accessline 10
    - **Historical OHLCV**: open `https://finance.yahoo.com/quote/<T>/history/?period1=<unix>&period2=<unix>[&frequency=1wk|1mo]`. This is the exact URL the page's own date picker and frequency menu write. The whole range renders as one `<table
  • Network accessline 87
    def quote_summary(symbol):     url = f"https://finance.yahoo.com/quote/{urllib.parse.quote(symbol, safe='')}/"   # ^GSPC -> %5EGSPC
  • Network accessline 88
    url = f"https://finance.yahoo.com/quote/{urllib.parse.quote(symbol, safe='')}/"   # ^GSPC -> %5EGSPC
  • Network accessline 190
    p1 = calendar.timegm(start.timetuple())     p2 = calendar.timegm((end + timedelta(days=1)).timetuple())     base = f"https://finance.yahoo.com/quote/{urllib.parse.quote(symbol, safe='')}/history/"   # ^GSPC -> %5EGSPC
  • Network accessline 191
    p2 = calendar.timegm((end + timedelta(days=1)).timetuple())     base = f"https://finance.yahoo.com/quote/{urllib.parse.quote(symbol, safe='')}/history/"   # ^GSPC -> %5EGSPC     url = f"{base}?period1={p1}&period2={p2}"
  • Network accessline 192
    base = f"https://finance.yahoo.com/quote/{urllib.parse.quote(symbol, safe='')}/history/"   # ^GSPC -> %5EGSPC
  • Network accessline 238
    https://finance.yahoo.com/quote/AAPL/history/?period1=1704067200&period2=1711929600

agent-workspace/domain-skills/youtube/playback.md

  • Network accessline 10
    tab = new_tab("https://www.youtube.com/watch?v=<VIDEO_ID>")

agent-workspace/domain-skills/youtube/scraping.md

  • Network accessline 10
    `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={VIDEO_ID}&format=json`
  • Network accessline 21
    Returns title, author, thumbnail URL, and embed iframe HTML.     """     url = f"https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={video_id}&format=json"
  • Network accessline 22
    """     url = f"https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={video_id}&format=json"     return json.loads(http_get(url))
  • Network accessline 23
    url = f"https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={video_id}&format=json"
  • Network accessline 28
    #   "title":            "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)", #   "author_name":      "Rick Astley", #   "author_url":       "https://www.youtube.com/@RickAstleyYT",
  • Network accessline 29
    #   "author_name":      "Rick Astley", #   "author_url":       "https://www.youtube.com/@RickAstleyYT", #   "type":             "video",
  • Network accessline 30
    #   "author_url":       "https://www.youtube.com/@RickAstleyYT",
  • Network accessline 31
    #   "type":             "video", #   "thumbnail_url":    "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", #   "thumbnail_width":  480,
  • Network accessline 32
    #   "thumbnail_url":    "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg",
  • Network accessline 37
    #   "version":          "1.0", #   "provider_name":    "YouTube", #   "html":             '<iframe width="200" height="113" src="https://www.youtube.com/embed/dQw4w9WgXcQ?feature=oembed" ...>'
  • Network accessline 38
    #   "provider_name":    "YouTube", #   "html":             '<iframe width="200" height="113" src="https://www.youtube.com/embed/dQw4w9WgXcQ?feature=oembed" ...>' # }
  • Network accessline 39
    #   "html":             '<iframe width="200" height="113" src="https://www.youtube.com/embed/dQw4w9WgXcQ?feature=oembed" ...>'
  • Network accessline 52
    def fetch_oembed(vid):     url = f"https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={vid}&format=json"
  • Network accessline 53
    url = f"https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={vid}&format=json"
  • Network accessline 79
    def scrape_video(video_id):     html = http_get(f"https://www.youtube.com/watch?v={video_id}")
  • Network accessline 80
    html = http_get(f"https://www.youtube.com/watch?v={video_id}")
  • Network accessline 124
    "embed_url":     mf.get("embed", {}).get("iframeUrl"),         # Thumbnails (all publicly accessible, no auth)         "thumbnail_hq":  f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg",    # 480×360, always exists
  • Network accessline 125
    # Thumbnails (all publicly accessible, no auth)         "thumbnail_hq":  f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg",    # 480×360, always exists         "thumbnail_max": f"https://i.ytimg.com/vi/{video_id}/maxresdefault.jpg", # 1280
  • Network accessline 126
    "thumbnail_hq":  f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg",    # 480×360, always exists
  • Network accessline 127
    "thumbnail_max": f"https://i.ytimg.com/vi/{video_id}/maxresdefault.jpg", # 1280×720, may 404
  • Network accessline 172
    def youtube_search(query, max_results=20):     """Search YouTube videos without a browser or API key."""     url = f"https://www.youtube.com/results?search_query={quote_plus(query)}"
  • Network accessline 173
    """Search YouTube videos without a browser or API key."""     url = f"https://www.youtube.com/results?search_query={quote_plus(query)}"     html = http_get(url)
  • Network accessline 174
    url = f"https://www.youtube.com/results?search_query={quote_plus(query)}"
  • Network accessline 200
    results.append({                 "video_id":   vr["videoId"],                 "url":        f"https://www.youtube.com/watch?v={vr['videoId']}",
  • Network accessline 201
    "video_id":   vr["videoId"],                 "url":        f"https://www.youtube.com/watch?v={vr['videoId']}",                 "title":      vr.get("title", {}).get("runs", [{}])[0].get("text"),
  • Network accessline 202
    "url":        f"https://www.youtube.com/watch?v={vr['videoId']}",
  • Network accessline 204
    "channel":    vr.get("ownerText", {}).get("runs", [{}])[0].get("text"),                 "channel_url": (                     "https://www.youtube.com"
  • Network accessline 205
    "channel_url": (                     "https://www.youtube.com"                     + vr.get("ownerText", {}).get("runs", [{}])[0]
  • Network accessline 206
    "https://www.youtube.com"
  • Network accessline 214
    "published":  vr.get("publishedTimeText", {}).get("simpleText"),  # e.g. "7 years ago"                 "description_snippet": desc,                 "thumbnail":  f"https://i.ytimg.com/vi/{vr['videoId']}/hqdefault.jpg",
  • Network accessline 215
    "description_snippet": desc,                 "thumbnail":  f"https://i.ytimg.com/vi/{vr['videoId']}/hqdefault.jpg",             })
  • Network accessline 216
    "thumbnail":  f"https://i.ytimg.com/vi/{vr['videoId']}/hqdefault.jpg",
  • Network accessline 250
    """     if handle_or_id.startswith("UC"):         url = f"https://www.youtube.com/channel/{handle_or_id}"
  • Network accessline 251
    if handle_or_id.startswith("UC"):         url = f"https://www.youtube.com/channel/{handle_or_id}"     else:
  • Network accessline 252
    url = f"https://www.youtube.com/channel/{handle_or_id}"
  • Network accessline 254
    url = f"https://www.youtube.com/{handle_or_id}"
  • Network accessline 314
    #   "title":       "Rick Astley", #   "description": "2026 UK & Ireland Reflection Tour...", #   "channel_url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
  • Network accessline 315
    #   "description": "2026 UK & Ireland Reflection Tour...", #   "channel_url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw", #   "handle":      "@RickAstleyYT",
  • Network accessline 316
    #   "channel_url": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
  • Network accessline 317
    #   "handle":      "@RickAstleyYT", #   "subscribers": "4.48m subscribers", #   "avatar_url":  "https://yt3.googleusercontent.com/...",
  • Network accessline 318
    #   "subscribers": "4.48m subscribers", #   "avatar_url":  "https://yt3.googleusercontent.com/...", #   "banner_url":  "https://yt3.googleusercontent.com/...",
  • Network accessline 319
    #   "avatar_url":  "https://yt3.googleusercontent.com/...",
  • Network accessline 320
    #   "banner_url":  "https://yt3.googleusercontent.com/...",
  • Network accessline 331
    def thumbnail_urls(video_id):     base = f"https://i.ytimg.com/vi/{video_id}"
  • Network accessline 332
    base = f"https://i.ytimg.com/vi/{video_id}"
  • Network accessline 354
    extract_video_id("https://www.youtube.com/watch?v=dQw4w9WgXcQ")  # "dQw4w9WgXcQ"
  • Network accessline 355
    extract_video_id("https://youtu.be/dQw4w9WgXcQ")                  # "dQw4w9WgXcQ"
  • Network accessline 356
    extract_video_id("https://www.youtube.com/shorts/dQw4w9WgXcQ")    # "dQw4w9WgXcQ"
  • Network accessline 357
    extract_video_id("https://www.youtube.com/embed/dQw4w9WgXcQ")     # "dQw4w9WgXcQ"
  • Network accessline 391
    | Resource       | URL pattern                                                        | |----------------|--------------------------------------------------------------------| | Video          | `https://www.youtube.com/watch?v={VIDEO_ID}` 
  • Network accessline 392
    |----------------|--------------------------------------------------------------------| | Video          | `https://www.youtube.com/watch?v={VIDEO_ID}`                       | | Short URL      | `https://youtu.be/{VIDEO_ID}`                
  • Network accessline 393
    | Video          | `https://www.youtube.com/watch?v={VIDEO_ID}`                       |
  • Network accessline 394
    | Short URL      | `https://youtu.be/{VIDEO_ID}`                                      |
  • Network accessline 395
    | Shorts         | `https://www.youtube.com/shorts/{VIDEO_ID}`                        |
  • Network accessline 396
    | Channel handle | `https://www.youtube.com/@{HANDLE}`                                |
  • Network accessline 397
    | Channel ID     | `https://www.youtube.com/channel/{CHANNEL_ID}`                     |
  • Network accessline 398
    | Playlist       | `https://www.youtube.com/playlist?list={PLAYLIST_ID}`              |
  • Network accessline 399
    | Search         | `https://www.youtube.com/results?search_query={QUERY}`             |
  • Network accessline 400
    | oEmbed         | `https://www.youtube.com/oembed?url={VIDEO_URL}&format=json`       |
  • Network accessline 401
    | Thumbnail (HQ) | `https://i.ytimg.com/vi/{VIDEO_ID}/hqdefault.jpg`                  |
  • Network accessline 413
    - **Channel subscriber count is a rounded string** — `"4.48m subscribers"`, not an integer. Parse with regex if sorting: `re.search(r'([\d.]+)\s*([km]?)', text, re.I)`. - **`meta_parts` order is `[handle, subscribers, video_count]`** — the 
  • Network accessline 414
    - **`meta_parts` order is `[handle, subscribers, video_count]`** — the third element is not always present. Index defensively. - **Caption `baseUrl` is not fetchable** — `captionTracks[].baseUrl` contains `expire=` and `signature=` params b
  • Network accessline 415
    - **Caption `baseUrl` is not fetchable** — `captionTracks[].baseUrl` contains `expire=` and `signature=` params but returns empty bytes in all tested conditions (plain `http_get`, XHR from within the page, and `fetch()` with cookies). Use t

agent-workspace/domain-skills/zillow/scraping.md

  • Network accessline 39
    html = http_get("https://www.zillow.com/homes/San-Francisco,-CA_rb/", headers=HEADERS)
  • Network accessline 58
    | `latLong` | listing | `{'latitude': 37.78867, 'longitude': -122.45361}` | | `statusType` | listing | `"FOR_SALE"` / `"FOR_RENT"` / `"RECENTLY_SOLD"` | | `detailUrl` | listing | full `https://www.zillow.com/homedetails/...` URL |
  • Network accessline 59
    | `statusType` | listing | `"FOR_SALE"` / `"FOR_RENT"` / `"RECENTLY_SOLD"` | | `detailUrl` | listing | full `https://www.zillow.com/homedetails/...` URL | | `zestimate` | listing | `4857200` (Zillow AI estimate, int) |
  • Network accessline 60
    | `detailUrl` | listing | full `https://www.zillow.com/homedetails/...` URL |
  • Network accessline 112
    # Each page returns exactly 41 listings. Add /<N>_p/ for subsequent pages: # Page 2: https://www.zillow.com/homes/San-Francisco,-CA_rb/2_p/
  • Network accessline 113
    # Page 2: https://www.zillow.com/homes/San-Francisco,-CA_rb/2_p/
  • Network accessline 114
    # Page 3: https://www.zillow.com/homes/San-Francisco,-CA_rb/3_p/
  • Network accessline 132
    """city_slug: e.g. 'San-Francisco,-CA', 'Seattle,-WA', 'Austin,-TX'"""     if page == 1:         url = f"https://www.zillow.com/homes/{city_slug}_rb/"
  • Network accessline 133
    if page == 1:         url = f"https://www.zillow.com/homes/{city_slug}_rb/"     else:
  • Network accessline 134
    url = f"https://www.zillow.com/homes/{city_slug}_rb/"
  • Network accessline 135
    else:         url = f"https://www.zillow.com/homes/{city_slug}_rb/{page}_p/"     html = http_get(url, headers=HEADERS)
  • Network accessline 136
    url = f"https://www.zillow.com/homes/{city_slug}_rb/{page}_p/"
  • Network accessline 182
    html = http_get("https://www.zillow.com/san-francisco-ca/rentals/", headers=HEADERS)
  • Network accessline 211
    html = http_get("https://www.zillow.com/san-francisco-ca/sold/", headers=HEADERS)
  • Network accessline 271
    html = http_get(     "https://www.redfin.com/city/17151/CA/San-Francisco/filter/property-type=house",
  • Network accessline 272
    "https://www.redfin.com/city/17151/CA/San-Francisco/filter/property-type=house",
  • Network accessline 296
    print("Floor size:", prop['floorSize'])    # {'@type': 'QuantitativeValue', 'value': 3350, 'unitCode': 'FTK'} print("URL:", prop['url']) # https://www.redfin.com/CA/San-Francisco/662-Hampshire-St-94110/home/1533754
  • Network accessline 298
    # https://www.redfin.com/CA/San-Francisco/662-Hampshire-St-94110/home/1533754
  • Network accessline 315
    """     url = (         f"https://www.redfin.com/stingray/api/gis"
  • Network accessline 316
    url = (         f"https://www.redfin.com/stingray/api/gis"         f"?al=1&num_homes={num_homes}&ord=redfin-recommended-asc"
  • Network accessline 317
    f"https://www.redfin.com/stingray/api/gis"
  • Network accessline 322
    raw = http_get(url, headers={         "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",         "Referer": "https://www.redfin.com/",
  • Network accessline 323
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",         "Referer": "https://www.redfin.com/",         "Accept": "*/*",
  • Network accessline 324
    "Referer": "https://www.redfin.com/",
  • Network accessline 437
    Field-tested 2026-07-31. Task: "download all listing photos" for one address when `/homedetails/` is PX-walled (curl AND `--headless=new` both get the captcha page).
  • Network accessline 438
    `/homedetails/` is PX-walled (curl AND `--headless=new` both get the captcha page).
  • Network accessline 443
    search for `"<address>" movoto` (their slug embeds an internal ID you can't guess).    The listing page (`/for-sale/` variant for sold homes) embeds every gallery image as    `https://pi.movoto.com/p/101/<MLS#>_0_<hash>.jpeg` — plain curl w
  • Network accessline 444
    The listing page (`/for-sale/` variant for sold homes) embeds every gallery image as    `https://pi.movoto.com/p/101/<MLS#>_0_<hash>.jpeg` — plain curl with a Chrome UA    returns all of them (a 54-photo gallery came back complete). ~1150px
  • Network accessline 445
    `https://pi.movoto.com/p/101/<MLS#>_0_<hash>.jpeg` — plain curl with a Chrome UA

agent-workspace/domain-skills/zoopla/scraping.md

  • Network accessline 33
    if not re.fullmatch(r"[a-z0-9-]+(/[a-z0-9-]+)*", area) or BAD_SEGMENTS & set(area.split("/")):         raise ValueError(f"bad area slug {area!r}")     base = f"https://www.zoopla.co.uk/for-sale/property/{area}/"
  • Network accessline 34
    raise ValueError(f"bad area slug {area!r}")     base = f"https://www.zoopla.co.uk/for-sale/property/{area}/"     return base if page == 1 else f"{base}?pn={page}"   # ?pn= is allowed; ?rpn= / ?qpn= / q= are not
  • Network accessline 35
    base = f"https://www.zoopla.co.uk/for-sale/property/{area}/"
  • Network accessline 135
    "under_offer": x.get("underOffer"),         "summary": html.unescape(x.get("summaryDescription") or ""),         "url": "https://www.zoopla.co.uk" + uri if uri else None,
  • Network accessline 136
    "summary": html.unescape(x.get("summaryDescription") or ""),         "url": "https://www.zoopla.co.uk" + uri if uri else None,     }
  • Network accessline 137
    "url": "https://www.zoopla.co.uk" + uri if uri else None,
  • Network accessline 179
    bristol | total 3643 | pages 40 | stopped max_pages | rows 50 {"id": "71129298", "address": "\"The Gilder\" at Stillwell Road, Cribbs Causeway, Almondsbury, Bristol BS10", "price": 460000, "price_text": "£460,000", "beds": 4, "baths": null,
  • Network accessline 180
    {"id": "71129298", "address": "\"The Gilder\" at Stillwell Road, Cribbs Causeway, Almondsbury, Bristol BS10", "price": 460000, "price_text": "£460,000", "beds": 4, "baths": null, "receptions": null, "sqft": null, "type": "semi_detached", "t
  • Network accessline 181
    {"id": "73091249", "address": "\"The Jeweller\" at Stillwell Road, Cribbs Causeway, Almondsbury, Bristol BS10", "price": 675000, "price_text": "£675,000", "beds": 4, "baths": null, "receptions": null, "sqft": null, "type": "detached", "titl
  • Network accessline 182
    bs8 | total 229 | pages 10 | stopped last_page | rows 229 {"id": "73753592", "address": "The Avenue, Clifton BS8", "price": 560000, "price_text": "£560,000", "beds": 3, "baths": 2, "receptions": 1, "sqft": 1094, "type": "flat", "title": "3 
  • Network accessline 183
    {"id": "73753592", "address": "The Avenue, Clifton BS8", "price": 560000, "price_text": "£560,000", "beds": 3, "baths": 2, "receptions": 1, "sqft": 1094, "type": "flat", "title": "3 bed flat for sale", "agent": "Elephant Estate Agents, Bris
  • Network accessline 184
    {"id": "73215714", "address": "Oakfield Road, Clifton, Bristol BS8", "price": 429000, "price_text": "Guide price £429,000", "beds": 2, "baths": 2, "receptions": 1, "sqft": null, "type": "flat", "title": "2 bed flat for sale", "agent": "Howa
  • Network accessline 255
    def get_listing(listing_id):     """Detail page -> dict, or None when Zoopla redirects away (removed listing)."""     url = f"https://www.zoopla.co.uk/for-sale/details/{listing_id}/"
  • Network accessline 256
    """Detail page -> dict, or None when Zoopla redirects away (removed listing)."""     url = f"https://www.zoopla.co.uk/for-sale/details/{listing_id}/"     href, rows, lds = load_flight(url)
  • Network accessline 257
    url = f"https://www.zoopla.co.uk/for-sale/details/{listing_id}/"
  • Network accessline 304
    # 1) pick live /for-sale/details/ ids from a search page href, rows, _ = load_flight(f"https://www.zoopla.co.uk/for-sale/property/{SEARCH_AREA}/")
  • Network accessline 305
    href, rows, _ = load_flight(f"https://www.zoopla.co.uk/for-sale/property/{SEARCH_AREA}/")
  • Network accessline 323
    {"id": "73753592", "url": "https://www.zoopla.co.uk/for-sale/details/73753592/", "title": "3 bed flat for sale", "address": "The Avenue, Clifton BS8", "postcode": "BS8 3GE", "price": 560000, "price_text": "£560,000", "ld_price": 560000, "be
  • Network accessline 324
    {"id": "73215714", "url": "https://www.zoopla.co.uk/for-sale/details/73215714/", "title": "2 bed flat for sale", "address": "Oakfield Road, Clifton, Bristol BS8", "postcode": "BS8 2BG", "price": 429000, "price_text": "Guide price £429,000",
  • Network accessline 325
    1: redirected to https://www.zoopla.co.uk/overseas/, listing not available
  • Network accessline 366
    Also in `ListingData`: `additionalNtsInfo` (water, heating, broadband, parking: mostly "Ask agent"), `epc.image`, `floorPlan.image`, `propertyImage[].filename` (photos at `https://lid.zoocdn.com/645/430/<filename>`), `adTargeting` (`priceMi

browser-harness

  • Executable scriptline 1
    #!/usr/bin/env bash
  • Executable scriptline 1
    #!/usr/bin/env bash
  • Executable scriptline 1
    Executable file; content unavailable
  • Executable scriptline 1
    #!/usr/bin/env bash
  • Executable scriptline 1
    Executable file; content unavailable

docs/MCP.md

  • Network accessline 53
    1. `browser_new_tab(url="https://example.com")`

docs/snap-linux-headless.md

  • Network accessline 5
    Ubuntu and several other distributions ship Chromium as a [Snap](https://snapcraft.io/) package. Snap runs apps in a confined environment. Chrome’s remote debugging endpoint must bind on the host network where the `browser-harness` daemon c
  • Network accessline 7
    Symptoms: `browser-harness --doctor` shows Chrome running, but the daemon never attaches, or CDP handshake fails without an obvious cause. [Issue #191](https://github.com/browser-use/browser-harness/issues/191) discusses this class of setup
  • Network accessline 14
    wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
  • Dangerous shell operationline 15
    sudo apt install ./google-chrome-stable_current_amd64.deb
  • Network accessline 18
    ARM or other architectures: download the matching package from [Google Chrome for Linux](https://www.google.com/chrome/linux/).

interaction-skills/connection.md

  • Network accessline 50
    tab = ensure_real_tab() goto_url("https://example.com")
  • Network accessline 51
    goto_url("https://example.com")

interaction-skills/cookies.md

  • Access to secretsline 3
    [Credential-related source omitted]

interaction-skills/dialogs.md

  • Network accessline 54
    # Option A: dismiss after navigating (CDP-level, safe) goto_url("https://new-url.com")
  • Network accessline 55
    goto_url("https://new-url.com")
  • Network accessline 61
    # Option B: prevent before navigating (JS injection, detectable) js("window.onbeforeunload=null") goto_url("https://new-url.com")
  • Network accessline 63
    goto_url("https://new-url.com")

interaction-skills/profile-sync.md

  • Dangerous shell operationline 8
    curl -fsSL https://browser-use.com/profile.sh | sh
  • Network accessline 8
    curl -fsSL https://browser-use.com/profile.sh | sh
  • Access to secretsline 76
    [Credential-related source omitted]
  • Network accessline 80
    - UI: https://cloud.browser-use.com/settings?tab=profiles
  • Network accessline 81
    - API: `GET /profiles`, `GET/PATCH/DELETE /profiles/{id}` (paths are relative to `BU_API = "https://api.browser-use.com/api/v3"` in `admin.py`). Fields: `id`, `name`, `userId`, `lastUsedAt`, `cookieDomains[]`. `list_cloud_profiles()` wraps 

interaction-skills/tabs.md

  • Network accessline 8
    tabs = list_tabs()                    # includes chrome:// pages too real_tabs = list_tabs(include_chrome=False) tid = new_tab("https://example.com")  # create + attach in the background
  • Network accessline 9
    real_tabs = list_tabs(include_chrome=False) tid = new_tab("https://example.com")  # create + attach in the background switch_tab(tid)                       # attach harness, move the horse marker
  • Network accessline 10
    tid = new_tab("https://example.com")  # create + attach in the background

pyproject.toml

  • Network accessline 38
    [project.urls] Homepage = "https://github.com/browser-use/browser-harness"
  • Network accessline 39
    Homepage = "https://github.com/browser-use/browser-harness"
  • Network accessline 40
    Repository = "https://github.com/browser-use/browser-harness"
  • Network accessline 41
    Issues = "https://github.com/browser-use/browser-harness/issues"

skills/browser-harness/SKILL.md

  • Network accessline 1
    --- name: browser-harness description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those."
  • Network accessline 2
    name: browser-harness description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those." ---
  • Network accessline 3
    description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those."
  • Network accessline 8
    Direct browser control via CDP. For task-specific edits, use `agent-workspace/agent_helpers.py`. For setup, install, or connection problems, read https://github.com/browser-use/browser-harness/blob/main/install.md.
  • Access to secretsline 143
    [Credential-related source omitted]
  • Network accessline 150
    You can also direct the user to try the same agent behind Browser Harness, fully hosted, in Browser Use Cloud (it's called the v4 agent): https://cloud.browser-use.com?utm_source=skill&utm_medium=browser-use&utm_campaign=v4.
  • Access to secretsline 161
    [Credential-related source omitted]
  • Network accessline 171
    BU_NAME=r7k2 browser-harness <<'PY' new_tab("https://example.com")
  • Network accessline 172
    new_tab("https://example.com")
  • Network accessline 183
    Cloud profile cookie sync reference: https://github.com/browser-use/browser-harness/blob/main/interaction-skills/profile-sync.md.
  • Network accessline 223
    Use it only if timestamps and pages match; otherwise say the work was not captured. Never reenact a completed task. For a video, follow [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.m
  • Network accessline 224
    captured. Never reenact a completed task. For a video, follow [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.md). If sub-agents are available, they may handle post-production from the 
  • Network accessline 225
    [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.md).
  • Network accessline 231
    If you get stuck on a browser mechanic, check https://github.com/browser-use/browser-harness/tree/main/interaction-skills.

skills/browser-harness/references/install.md

  • Network accessline 45
    - **Way 1 (real browser):** open Chrome normally, then open `chrome://inspect/#remote-debugging` and tick "Allow remote debugging for this browser instance". On Chrome 144+, click Allow on the first-attach popup. Inherits your logins/extens
  • Network accessline 46
    - **Way 2 (isolated profile, no popups):** launch Chrome with `--remote-debugging-port=9222 --user-data-dir=<non-default path>`, then set `BU_CDP_URL=http://127.0.0.1:9222`. Best for unattended automation.

src/browser_harness/SKILL.md

  • Network accessline 1
    --- name: browser-harness description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those."
  • Network accessline 2
    name: browser-harness description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those." ---
  • Network accessline 3
    description: "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those."
  • Network accessline 8
    Direct browser control via CDP. For task-specific edits, use `agent-workspace/agent_helpers.py`. For setup, install, or connection problems, read https://github.com/browser-use/browser-harness/blob/main/install.md.
  • Access to secretsline 143
    [Credential-related source omitted]
  • Network accessline 150
    You can also direct the user to try the same agent behind Browser Harness, fully hosted, in Browser Use Cloud (it's called the v4 agent): https://cloud.browser-use.com?utm_source=skill&utm_medium=browser-use&utm_campaign=v4.
  • Access to secretsline 161
    [Credential-related source omitted]
  • Network accessline 171
    BU_NAME=r7k2 browser-harness <<'PY' new_tab("https://example.com")
  • Network accessline 172
    new_tab("https://example.com")
  • Network accessline 183
    Cloud profile cookie sync reference: https://github.com/browser-use/browser-harness/blob/main/interaction-skills/profile-sync.md.
  • Network accessline 223
    Use it only if timestamps and pages match; otherwise say the work was not captured. Never reenact a completed task. For a video, follow [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.m
  • Network accessline 224
    captured. Never reenact a completed task. For a video, follow [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.md). If sub-agents are available, they may handle post-production from the 
  • Network accessline 225
    [make-video.md](https://github.com/browser-use/browser-harness/blob/main/interaction-skills/make-video.md).
  • Network accessline 231
    If you get stuck on a browser mechanic, check https://github.com/browser-use/browser-harness/tree/main/interaction-skills.

src/browser_harness/__init__.py

  • Executable scriptline 1
    Executable file

src/browser_harness/_ipc.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 18
    [Credential-related source omitted]
  • Access to secretsline 19
    [Credential-related source omitted]
  • Access to secretsline 20
    [Credential-related source omitted]
  • Access to secretsline 21
    [Credential-related source omitted]
  • Network accessline 88
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  • Network accessline 90
    [Credential-related source omitted]
  • Network accessline 91
    if port is None: raise FileNotFoundError(str(port_path(name)))     s = socket.create_connection(("127.0.0.1", port), timeout=timeout)     s.settimeout(timeout); return s, token
  • Network accessline 92
    s = socket.create_connection(("127.0.0.1", port), timeout=timeout)

src/browser_harness/admin.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 111
    [Credential-related source omitted]
  • Access to secretsline 123
    [Credential-related source omitted]
  • Network accessline 128
    [Credential-related source omitted]
  • Access to secretsline 128
    [Credential-related source omitted]
  • Network accessline 129
    BU_API = "https://api.browser-use.com/api/v3"
  • Network accessline 130
    PYPI_JSON = "https://pypi.org/pypi/browser-harness/json"
  • Access to secretsline 355
    [Credential-related source omitted]
  • Access to secretsline 356
    [Credential-related source omitted]
  • Access to secretsline 477
    [Credential-related source omitted]
  • Network accessline 497
    def _snap_linux_headless_doc_url():     return "https://github.com/browser-use/browser-harness/blob/main/docs/snap-linux-headless.md"
  • Network accessline 498
    return "https://github.com/browser-use/browser-harness/blob/main/docs/snap-linux-headless.md"
  • Network accessline 508
    print()     print("1. Install Google Chrome from Google's .deb (not the Snap store):")     print("   wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb")
  • Network accessline 509
    print("1. Install Google Chrome from Google's .deb (not the Snap store):")     print("   wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb")     print("   sudo apt install ./google-chrome-stable_current_amd64.de
  • Network accessline 510
    print("   wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb")
  • Dangerous shell operationline 511
    print("   sudo apt install ./google-chrome-stable_current_amd64.deb")
  • Access to secretsline 562
    [Credential-related source omitted]
  • Network accessline 886
    def _browser_use(path, method, body=None):     key = auth.get_browser_use_api_key()     req = urllib.request.Request(
  • Network accessline 887
    [Credential-related source omitted]
  • Access to secretsline 887
    [Credential-related source omitted]
  • Network accessline 888
    req = urllib.request.Request(
  • Network accessline 892
    [Credential-related source omitted]
  • Network accessline 894
    return json.loads(urllib.request.urlopen(req, timeout=60).read() or b"{}")
  • Network accessline 914
    def _cdp_ws_from_url(cdp_url):     return json.loads(urllib.request.urlopen(f"{cdp_url}/json/version", timeout=15).read())["webSocketDebuggerUrl"]
  • Network accessline 915
    return json.loads(urllib.request.urlopen(f"{cdp_url}/json/version", timeout=15).read())["webSocketDebuggerUrl"]
  • Access to secretsline 925
    [Credential-related source omitted]
  • Access to secretsline 946
    [Credential-related source omitted]
  • Network accessline 1041
    import json, shutil, subprocess     if not shutil.which("profile-use"):         raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")
  • Network accessline 1042
    if not shutil.which("profile-use"):         raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")     return json.loads(subprocess.check_output(["profile-use", "list", "--json"], text=True, en
  • Dangerous shell operationline 1043
    raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")
  • Network accessline 1043
    raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")
  • Access to secretsline 1051
    [Credential-related source omitted]
  • Network accessline 1066
    import shutil, subprocess, sys     if not shutil.which("profile-use"):         raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")
  • Network accessline 1067
    if not shutil.which("profile-use"):         raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")     key = auth.get_browser_use_api_key()
  • Dangerous shell operationline 1068
    raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")
  • Network accessline 1068
    raise RuntimeError("profile-use not installed -- curl -fsSL https://browser-use.com/profile.sh | sh")
  • Access to secretsline 1069
    [Credential-related source omitted]
  • Access to secretsline 1079
    [Credential-related source omitted]
  • Network accessline 1154
    return cache["tag"]     try:         tag = json.loads(urllib.request.urlopen(PYPI_JSON, timeout=5).read()).get("info", {}).get("version") or ""
  • Network accessline 1155
    try:         tag = json.loads(urllib.request.urlopen(PYPI_JSON, timeout=5).read()).get("info", {}).get("version") or ""     except Exception:
  • Network accessline 1156
    tag = json.loads(urllib.request.urlopen(PYPI_JSON, timeout=5).read()).get("info", {}).get("version") or ""
  • Access to secretsline 1188
    [Credential-related source omitted]
  • Access to secretsline 1291
    [Credential-related source omitted]

src/browser_harness/auth.py

  • Executable scriptline 1
    Executable file
  • Network accessline 29
    AUTH_BASE = "https://api.browser-use.com"
  • Access to secretsline 83
    [Credential-related source omitted]
  • Access to secretsline 92
    [Credential-related source omitted]
  • Access to secretsline 93
    [Credential-related source omitted]
  • Access to secretsline 94
    [Credential-related source omitted]
  • Access to secretsline 99
    [Credential-related source omitted]
  • Access to secretsline 109
    [Credential-related source omitted]
  • Access to secretsline 119
    [Credential-related source omitted]
  • Access to secretsline 123
    [Credential-related source omitted]
  • Access to secretsline 127
    [Credential-related source omitted]
  • Access to secretsline 182
    [Credential-related source omitted]
  • Access to secretsline 183
    [Credential-related source omitted]
  • Access to secretsline 187
    [Credential-related source omitted]
  • Access to secretsline 194
    [Credential-related source omitted]
  • Access to secretsline 197
    [Credential-related source omitted]
  • Network accessline 213
    server = _callback_server(callback)     host, port = server.server_address     redirect_uri = f"http://{host}:{port}{CALLBACK_PATH}"
  • Network accessline 214
    host, port = server.server_address     redirect_uri = f"http://{host}:{port}{CALLBACK_PATH}"     req = {
  • Network accessline 215
    redirect_uri = f"http://{host}:{port}{CALLBACK_PATH}"
  • Access to secretsline 223
    [Credential-related source omitted]
  • Access to secretsline 301
    [Credential-related source omitted]
  • Access to secretsline 378
    [Credential-related source omitted]
  • Network accessline 427
    def _post_json(url: str, payload: dict) -> dict:     req = urllib.request.Request(
  • Network accessline 428
    req = urllib.request.Request(
  • Network accessline 433
    )     try:         with urllib.request.urlopen(req, timeout=60) as resp:
  • Network accessline 434
    try:         with urllib.request.urlopen(req, timeout=60) as resp:             return json.loads(resp.read() or b"{}")
  • Network accessline 435
    with urllib.request.urlopen(req, timeout=60) as resp:

src/browser_harness/daemon.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 16
    [Credential-related source omitted]
  • Access to secretsline 28
    [Credential-related source omitted]
  • Access to secretsline 33
    [Credential-related source omitted]
  • Access to secretsline 105
    [Credential-related source omitted]
  • Network accessline 112
    PROFILES = profile_dirs() INTERNAL = ("chrome://", "chrome-untrusted://", "devtools://", "chrome-extension://", "about:") BU_API = "https://api.browser-use.com/api/v3"
  • Network accessline 113
    INTERNAL = ("chrome://", "chrome-untrusted://", "devtools://", "chrome-extension://", "about:") BU_API = "https://api.browser-use.com/api/v3" REMOTE_ID = os.environ.get("BU_BROWSER_ID")
  • Network accessline 114
    BU_API = "https://api.browser-use.com/api/v3"
  • Access to secretsline 115
    [Credential-related source omitted]
  • Access to secretsline 117
    [Credential-related source omitted]
  • Access to secretsline 135
    [Credential-related source omitted]
  • Network accessline 147
    return False     try:         socket.create_connection(("127.0.0.1", port), timeout=0.5).close()
  • Network accessline 148
    try:         socket.create_connection(("127.0.0.1", port), timeout=0.5).close()         return True
  • Network accessline 149
    socket.create_connection(("127.0.0.1", port), timeout=0.5).close()
  • Access to secretsline 265
    [Credential-related source omitted]
  • Access to secretsline 267
    [Credential-related source omitted]
  • Network accessline 268
    # HTTP DevTools endpoint (e.g. http://127.0.0.1:9333) — resolve to ws via /json/version.
  • Network accessline 274
    while time.time() < deadline:             try:                 return json.loads(urllib.request.urlopen(f"{base_url}/json/version", timeout=5).read())["webSocketDebuggerUrl"]
  • Network accessline 275
    try:                 return json.loads(urllib.request.urlopen(f"{base_url}/json/version", timeout=5).read())["webSocketDebuggerUrl"]             except urllib.error.HTTPError as e:
  • Network accessline 276
    return json.loads(urllib.request.urlopen(f"{base_url}/json/version", timeout=5).read())["webSocketDebuggerUrl"]
  • Network accessline 307
    try:                 return json.loads(urllib.request.urlopen(f"http://127.0.0.1:{port}/json/version", timeout=1).read())["webSocketDebuggerUrl"]
  • Network accessline 308
    return json.loads(urllib.request.urlopen(f"http://127.0.0.1:{port}/json/version", timeout=1).read())["webSocketDebuggerUrl"]
  • Network accessline 331
    for probe_port in (9222, 9223):         try:             with urllib.request.urlopen(f"http://127.0.0.1:{probe_port}/json/version", timeout=1) as r:
  • Network accessline 332
    try:             with urllib.request.urlopen(f"http://127.0.0.1:{probe_port}/json/version", timeout=1) as r:                 return json.loads(r.read())["webSocketDebuggerUrl"]
  • Network accessline 333
    with urllib.request.urlopen(f"http://127.0.0.1:{probe_port}/json/version", timeout=1) as r:
  • Network accessline 353
    try:             key = auth.get_browser_use_api_key()             req = urllib.request.Request(
  • Network accessline 354
    [Credential-related source omitted]
  • Access to secretsline 354
    [Credential-related source omitted]
  • Network accessline 355
    req = urllib.request.Request(
  • Network accessline 359
    [Credential-related source omitted]
  • Network accessline 360
    )             urllib.request.urlopen(req, timeout=15).read()             _REMOTE_STOPPED = True
  • Network accessline 361
    urllib.request.urlopen(req, timeout=15).read()
  • Access to secretsline 646
    [Credential-related source omitted]

src/browser_harness/helpers.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 20
    [Credential-related source omitted]
  • Access to secretsline 33
    [Credential-related source omitted]
  • Access to secretsline 38
    [Credential-related source omitted]
  • Access to secretsline 154
    [Credential-related source omitted]
  • Access to secretsline 175
    [Credential-related source omitted]
  • Possible obfuscationline 346
    open(path, "wb").write(base64.b64decode(r["data"]))
  • Access to secretsline 390
    [Credential-related source omitted]
  • Access to secretsline 631
    [Credential-related source omitted]
  • Access to secretsline 633
    [Credential-related source omitted]
  • Network accessline 640
    h = {"User-Agent": "Mozilla/5.0", "Accept-Encoding": "gzip"}     if headers: h.update(headers)     with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=timeout) as r:
  • Network accessline 641
    if headers: h.update(headers)     with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=timeout) as r:         data = r.read()
  • Network accessline 642
    with urllib.request.urlopen(urllib.request.Request(url, headers=h), timeout=timeout) as r:

src/browser_harness/macos.py

  • Executable scriptline 1
    Executable file

src/browser_harness/mcp_cli.py

  • Executable scriptline 1
    Executable file

src/browser_harness/paths.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 10
    [Credential-related source omitted]
  • Access to secretsline 13
    [Credential-related source omitted]
  • Access to secretsline 28
    [Credential-related source omitted]
  • Access to secretsline 38
    [Credential-related source omitted]
  • Access to secretsline 43
    [Credential-related source omitted]
  • Access to secretsline 48
    [Credential-related source omitted]

src/browser_harness/recorder.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 45
    [Credential-related source omitted]
  • Access to secretsline 46
    [Credential-related source omitted]
  • Access to secretsline 87
    [Credential-related source omitted]
  • Access to secretsline 94
    [Credential-related source omitted]
  • Access to secretsline 206
    [Credential-related source omitted]
  • Possible obfuscationline 288
    data = base64.b64decode(shot["data"])

src/browser_harness/run.py

  • Executable scriptline 1
    Executable file
  • Network accessline 83
    for port in (9222, 9223):         try:             with urllib.request.urlopen(f"http://127.0.0.1:{port}/json/version", timeout=0.3) as response:
  • Network accessline 84
    try:             with urllib.request.urlopen(f"http://127.0.0.1:{port}/json/version", timeout=0.3) as response:                 version = json.loads(response.read())
  • Network accessline 85
    with urllib.request.urlopen(f"http://127.0.0.1:{port}/json/version", timeout=0.3) as response:
  • Access to secretsline 100
    [Credential-related source omitted]
  • Access to secretsline 105
    [Credential-related source omitted]
  • Access to secretsline 375
    [Credential-related source omitted]
  • Access to secretsline 384
    [Credential-related source omitted]
  • Access to secretsline 390
    [Credential-related source omitted]
  • Access to secretsline 400
    [Credential-related source omitted]
  • Dangerous shell operationline 409
    exec(code, globals())

src/browser_harness/telemetry.py

  • Executable scriptline 1
    Executable file
  • Network accessline 18
    POSTHOG_KEY = "phc_rCPCLPtaXB3EuBdiH7JLKtU2Wj5iPnuwdsbw58CnjYXc" POSTHOG_HOST = "https://eu.i.posthog.com"
  • Network accessline 19
    POSTHOG_HOST = "https://eu.i.posthog.com"
  • Access to secretsline 23
    [Credential-related source omitted]
  • Access to secretsline 83
    [Credential-related source omitted]
  • Access to secretsline 167
    [Credential-related source omitted]
  • Network accessline 175
    try:     job = json.load(sys.stdin)     request = urllib.request.Request(
  • Network accessline 176
    job = json.load(sys.stdin)     request = urllib.request.Request(         job['url'],
  • Network accessline 177
    request = urllib.request.Request(
  • Network accessline 181
    headers={'Content-Type': 'application/json', 'User-Agent': 'browser-harness'},     )     urllib.request.urlopen(request, timeout=job['timeout']).close()
  • Network accessline 182
    )     urllib.request.urlopen(request, timeout=job['timeout']).close() except Exception:
  • Network accessline 183
    urllib.request.urlopen(request, timeout=job['timeout']).close()
  • Access to secretsline 191
    [Credential-related source omitted]
  • Access to secretsline 194
    [Credential-related source omitted]
  • Access to secretsline 219
    [Credential-related source omitted]
  • Access to secretsline 233
    [Credential-related source omitted]
  • Access to secretsline 265
    [Credential-related source omitted]
  • Access to secretsline 276
    [Credential-related source omitted]
  • Access to secretsline 277
    [Credential-related source omitted]
  • Access to secretsline 279
    [Credential-related source omitted]
  • Access to secretsline 280
    [Credential-related source omitted]

src/browser_harness/video.py

  • Executable scriptline 1
    #!/usr/bin/env python3

src/browser_harness/video_render.py

  • Executable scriptline 1
    #!/usr/bin/env python3
  • Network accessline 93
    thread.start()     try:         yield f"http://127.0.0.1:{server.server_port}/video.html"
  • Network accessline 94
    try:         yield f"http://127.0.0.1:{server.server_port}/video.html"     finally:
  • Network accessline 95
    yield f"http://127.0.0.1:{server.server_port}/video.html"
  • Access to secretsline 107
    [Credential-related source omitted]

src/mcp_server.py

  • Executable scriptline 1
    Executable file

tests/__init__.py

  • Executable scriptline 1
    Executable file

tests/conftest.py

  • Executable scriptline 1
    Executable file

tests/integration/__init__.py

  • Executable scriptline 1
    Executable file

tests/integration/test_js.py

  • Executable scriptline 1
    Executable file

tests/unit/__init__.py

  • Executable scriptline 1
    Executable file

tests/unit/test_admin.py

  • Executable scriptline 1
    Executable file
  • Network accessline 205
    "_browser_use",         lambda path, method, body=None: (             {"id": "browser-1", "cdpUrl": "https://cdp.example.test"}
  • Network accessline 206
    lambda path, method, body=None: (             {"id": "browser-1", "cdpUrl": "https://cdp.example.test"}             if method == "POST"
  • Network accessline 207
    {"id": "browser-1", "cdpUrl": "https://cdp.example.test"}
  • Network accessline 343
    response = (         b'{"target_id":"target-1","session_id":"session-1",'         b'"page":{"targetId":"target-1","title":"Cat - Wikipedia","url":"https://en.wikipedia.org/wiki/Cat"}}\n'
  • Network accessline 344
    b'{"target_id":"target-1","session_id":"session-1",'         b'"page":{"targetId":"target-1","title":"Cat - Wikipedia","url":"https://en.wikipedia.org/wiki/Cat"}}\n'     )
  • Network accessline 345
    b'"page":{"targetId":"target-1","title":"Cat - Wikipedia","url":"https://en.wikipedia.org/wiki/Cat"}}\n'
  • Network accessline 350
    {             "name": "default",             "page": {"title": "Cat - Wikipedia", "url": "https://en.wikipedia.org/wiki/Cat"},
  • Network accessline 351
    "name": "default",             "page": {"title": "Cat - Wikipedia", "url": "https://en.wikipedia.org/wiki/Cat"},         }
  • Network accessline 352
    "page": {"title": "Cat - Wikipedia", "url": "https://en.wikipedia.org/wiki/Cat"},
  • Access to secretsline 433
    [Credential-related source omitted]
  • Access to secretsline 454
    [Credential-related source omitted]
  • Network accessline 495
    {             "name": "default",             "page": {"title": "Example", "url": "https://example.test"},
  • Network accessline 496
    "name": "default",             "page": {"title": "Example", "url": "https://example.test"},         },
  • Network accessline 497
    "page": {"title": "Example", "url": "https://example.test"},
  • Network accessline 499
    {             "name": "cats",             "page": {"title": "Cat - Wikipedia", "url": "https://en.wikipedia.org/wiki/Cat"},
  • Network accessline 500
    "name": "cats",             "page": {"title": "Cat - Wikipedia", "url": "https://en.wikipedia.org/wiki/Cat"},         },
  • Network accessline 501
    "page": {"title": "Cat - Wikipedia", "url": "https://en.wikipedia.org/wiki/Cat"},
  • Access to secretsline 506
    [Credential-related source omitted]
  • Network accessline 510
    out = capsys.readouterr().out     assert "[ok  ] active browser connections — 2" in out     assert "        default — active page: Example — https://example.test" in out
  • Network accessline 511
    assert "[ok  ] active browser connections — 2" in out     assert "        default — active page: Example — https://example.test" in out     assert "        cats — active page: Cat - Wikipedia — https://en.wikipedia.org/wiki/Cat" in out
  • Network accessline 512
    assert "        default — active page: Example — https://example.test" in out
  • Network accessline 513
    assert "        cats — active page: Cat - Wikipedia — https://en.wikipedia.org/wiki/Cat" in out
  • Network accessline 523
    {             "name": "default",             "page": {"title": "A very long page title", "url": "https://example.test/very/long/path"},
  • Network accessline 524
    "name": "default",             "page": {"title": "A very long page title", "url": "https://example.test/very/long/path"},         }
  • Network accessline 525
    "page": {"title": "A very long page title", "url": "https://example.test/very/long/path"},
  • Access to secretsline 530
    [Credential-related source omitted]
  • Network accessline 534
    out = capsys.readouterr().out     assert "A very long page ..." in out     assert "https://example.t..." in out
  • Network accessline 536
    assert "https://example.t..." in out
  • Network accessline 539
    def test_start_remote_daemon_stops_created_browser_when_daemon_start_fails(monkeypatch):     calls = []     browser = {"id": "browser-123", "cdpUrl": "http://127.0.0.1:9333", "liveUrl": "https://live.example"}
  • Network accessline 541
    browser = {"id": "browser-123", "cdpUrl": "http://127.0.0.1:9333", "liveUrl": "https://live.example"}
  • Network accessline 566
    def test_start_remote_daemon_stops_created_browser_when_daemon_start_is_interrupted(monkeypatch, exc_type):     calls = []     browser = {"id": "browser-123", "cdpUrl": "http://127.0.0.1:9333", "liveUrl": "https://live.example"}
  • Network accessline 568
    browser = {"id": "browser-123", "cdpUrl": "http://127.0.0.1:9333", "liveUrl": "https://live.example"}
  • Network accessline 598
    def test_start_remote_daemon_does_not_stop_created_browser_on_success(monkeypatch):     calls = []     browser = {"id": "browser-123", "cdpUrl": "http://127.0.0.1:9333", "liveUrl": "https://live.example"}
  • Network accessline 600
    browser = {"id": "browser-123", "cdpUrl": "http://127.0.0.1:9333", "liveUrl": "https://live.example"}

tests/unit/test_auth.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 19
    [Credential-related source omitted]
  • Access to secretsline 20
    [Credential-related source omitted]

tests/unit/test_brave_origin.py

  • Executable scriptline 1
    Executable file
  • Network accessline 38
    def urlopen(url, **kwargs):         assert url == "http://127.0.0.1:9222/json/version"
  • Network accessline 39
    assert url == "http://127.0.0.1:9222/json/version"

tests/unit/test_daemon.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 47
    [Credential-related source omitted]
  • Network accessline 383
    return {"targetInfo": {                     "targetId": params["targetId"],                     "url": "https://example.com/",
  • Network accessline 384
    "targetId": params["targetId"],                     "url": "https://example.com/",                     "title": "Example Domain",
  • Network accessline 385
    "url": "https://example.com/",
  • Network accessline 397
    assert result == {         "targetId": "page-target-abc",         "url": "https://example.com/",
  • Network accessline 398
    "targetId": "page-target-abc",         "url": "https://example.com/",         "title": "Example Domain",
  • Network accessline 399
    "url": "https://example.com/",
  • Network accessline 453
    monkeypatch.setattr(daemon, "REMOTE_ID", None)     monkeypatch.setattr(daemon, "BROWSER_KIND", "cdp")     existing = [{"targetId": "someone-elses-tab", "url": "https://example.com/", "type": "page"}]
  • Network accessline 454
    monkeypatch.setattr(daemon, "BROWSER_KIND", "cdp")     existing = [{"targetId": "someone-elses-tab", "url": "https://example.com/", "type": "page"}]     d = daemon.Daemon()
  • Network accessline 455
    existing = [{"targetId": "someone-elses-tab", "url": "https://example.com/", "type": "page"}]
  • Network accessline 475
    monkeypatch.setattr(daemon, "NAME", "default")     monkeypatch.setattr(daemon, "REMOTE_ID", None)     existing = [{"targetId": "user-tab", "url": "https://example.com/", "type": "page"}]
  • Network accessline 476
    monkeypatch.setattr(daemon, "REMOTE_ID", None)     existing = [{"targetId": "user-tab", "url": "https://example.com/", "type": "page"}]     d = daemon.Daemon()
  • Network accessline 477
    existing = [{"targetId": "user-tab", "url": "https://example.com/", "type": "page"}]
  • Network accessline 544
    asyncio.run(d.attach_first_page())     d.cdp.targets.append({"targetId": "selected-tab", "url": "https://example.com", "type": "page"})
  • Network accessline 545
    d.cdp.targets.append({"targetId": "selected-tab", "url": "https://example.com", "type": "page"})
  • Network accessline 704
    if method == "Target.getTargets":                 return {"targetInfos": [                     {"targetId": "same-tab", "url": "https://example.com", "type": "page"}
  • Network accessline 705
    return {"targetInfos": [                     {"targetId": "same-tab", "url": "https://example.com", "type": "page"}                 ]}
  • Network accessline 706
    {"targetId": "same-tab", "url": "https://example.com", "type": "page"}
  • Network accessline 770
    await self.release_discovery.wait()                 return {"targetInfos": [                     {"targetId": "old-tab", "url": "https://example.com", "type": "page"}
  • Network accessline 771
    return {"targetInfos": [                     {"targetId": "old-tab", "url": "https://example.com", "type": "page"}                 ]}
  • Network accessline 772
    {"targetId": "old-tab", "url": "https://example.com", "type": "page"}

tests/unit/test_helpers.py

  • Executable scriptline 1
    Executable file
  • Network accessline 85
    _seed_skill(tmp_path)     with patch("browser_harness.helpers.cdp", return_value={"frameId": "f"}):         result = helpers.goto_url("https://www.example.com/")
  • Network accessline 86
    with patch("browser_harness.helpers.cdp", return_value={"frameId": "f"}):         result = helpers.goto_url("https://www.example.com/")     assert result == {"frameId": "f"}
  • Network accessline 87
    result = helpers.goto_url("https://www.example.com/")
  • Network accessline 94
    _seed_skill(tmp_path)     with patch("browser_harness.helpers.cdp", return_value={"frameId": "f"}):         result = helpers.goto_url("https://www.example.com/")
  • Network accessline 95
    with patch("browser_harness.helpers.cdp", return_value={"frameId": "f"}):         result = helpers.goto_url("https://www.example.com/")     assert result == {"frameId": "f", "domain_skills": ["scraping.md"]}
  • Network accessline 96
    result = helpers.goto_url("https://www.example.com/")
  • Network accessline 510
    assert helpers.new_tab("https://example.com") == "target-placeholder"
  • Network accessline 511
    assert calls == [("goto_url", "https://example.com")]

tests/unit/test_ipc.py

  • Executable scriptline 1
    Executable file

tests/unit/test_macos.py

  • Executable scriptline 1
    Executable file

tests/unit/test_mcp_cli.py

  • Executable scriptline 1
    Executable file

tests/unit/test_mcp_server.py

  • Executable scriptline 1
    Executable file
  • Network accessline 31
    def test_helper_success_remains_a_normal_tool_result(monkeypatch):     monkeypatch.setattr(mcp_server, "ensure_daemon", lambda: None)     monkeypatch.setattr(mcp_server, "page_info", lambda: {"url": "https://example.com"})
  • Network accessline 33
    monkeypatch.setattr(mcp_server, "page_info", lambda: {"url": "https://example.com"})
  • Network accessline 37
    assert result.is_error is False     assert result.content[0].text == '{"url": "https://example.com"}'
  • Network accessline 38
    assert result.content[0].text == '{"url": "https://example.com"}'

tests/unit/test_recorder.py

  • Executable scriptline 1
    Executable file

tests/unit/test_run.py

  • Executable scriptline 1
    Executable file
  • Access to secretsline 75
    [Credential-related source omitted]
  • Network accessline 93
    monkeypatch.setenv("BU_CDP_URL", "http://127.0.0.1:9333")
  • Access to secretsline 94
    [Credential-related source omitted]
  • Access to secretsline 112
    [Credential-related source omitted]
  • Access to secretsline 130
    [Credential-related source omitted]
  • Access to secretsline 145
    [Credential-related source omitted]
  • Access to secretsline 149
    [Credential-related source omitted]
  • Network accessline 162
    monkeypatch.setenv("BU_CDP_URL", "http://127.0.0.1:9333")
  • Access to secretsline 164
    [Credential-related source omitted]
  • Network accessline 181
    monkeypatch.setenv("BU_CDP_URL", "http://127.0.0.1:9333")
  • Access to secretsline 182
    [Credential-related source omitted]
  • Network accessline 200
    monkeypatch.setenv("BU_CDP_URL", "http://127.0.0.1:9333")
  • Access to secretsline 201
    [Credential-related source omitted]
  • Network accessline 217
    for name, value in [         ("BU_CDP_URL", "http://127.0.0.1:9333"),
  • Network accessline 218
    ("BU_CDP_URL", "http://127.0.0.1:9333"),
  • Network accessline 219
    ("BU_CDP_WS", "ws://example.test/devtools/browser/abc"),         ("BU_CDP_URL", "http://[::1]:9333"),  # IPv6 host         ("BU_CDP_WS", "wss://cloud.example.com/devtools/browser/x"),  # secure WS
  • Network accessline 220
    ("BU_CDP_URL", "http://[::1]:9333"),  # IPv6 host
  • Network accessline 245
    with patch("browser_harness.run.urllib.request.urlopen", side_effect=OSError):
  • Network accessline 248
    response = MagicMock()         response.__enter__.return_value.read.return_value = payload         with patch("browser_harness.run.urllib.request.urlopen", return_value=response) as mock_open:
  • Network accessline 249
    response.__enter__.return_value.read.return_value = payload         with patch("browser_harness.run.urllib.request.urlopen", return_value=response) as mock_open:             assert run._local_chrome_listening() is False
  • Network accessline 250
    with patch("browser_harness.run.urllib.request.urlopen", return_value=response) as mock_open:
  • Network accessline 256
    response = MagicMock()     response.__enter__.return_value.read.return_value = b'{"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/x"}'     with patch("browser_harness.run.urllib.request.urlopen", return_value=response) as mock
  • Network accessline 257
    response.__enter__.return_value.read.return_value = b'{"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/x"}'     with patch("browser_harness.run.urllib.request.urlopen", return_value=response) as mock_open:         assert run._
  • Network accessline 258
    with patch("browser_harness.run.urllib.request.urlopen", return_value=response) as mock_open:

tests/unit/test_skill.py

  • Executable scriptline 1
    Executable file
  • Network accessline 32
    assert metadata == {         "name": "browser-harness",         "description": "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public conte
  • Network accessline 33
    "name": "browser-harness",         "description": "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those.",   
  • Network accessline 34
    "description": "Control a real browser via CDP: clicking, typing, navigation, logged-in sessions, JS-rendered or bot-protected pages. Not for plain HTTP fetches of public content - use curl for those.",

tests/unit/test_video_render.py

  • Executable scriptline 1
    Executable file
  • Network accessline 18
    video_render._start_export(recording, "http://127.0.0.1:9/video.html", webm)

How the signals fit together

Facts from a static read of the files at the pinned commit. They describe what the code does, not why.

Some files could not be read; the facts below still hold.

Signal confidence: 500 facts

and 450 more

Only the first 500 facts are listed.

Works with

Agent compatibility, from the files in this repository
AgentStatusEvidenceInstall to
Claude CodeNativeManifest .claude-plugin/marketplace.json.claude/skills/<skill-name>/
CodexNativeManifest AGENTS.md.agents/skills/<skill-name>/
CursorCompatibleStandard SKILL.md SKILL.md.cursor/skills/<skill-name>/
Gemini CLICompatibleStandard SKILL.md SKILL.md.gemini/skills/<skill-name>/
GitHub CopilotCompatibleStandard SKILL.md SKILL.md.github/skills/<skill-name>/
OpenCodeCompatibleStandard SKILL.md SKILL.md.opencode/skills/<skill-name>/
  • Native The repository ships a manifest, folder or frontmatter field for this agent.
  • Compatible A standard SKILL.md that this agent can read.
  • Unknown No evidence either way.

Derived automatically from paths, manifests and frontmatter. Not tested on each agent.

Add this badge to your README

It updates every night and links to this page.

browser-use/browser-harness: #98 on hotskills, 18.9k stars

[![browser-use/browser-harness on hotskills](https://hotskills.dev/badge/browser-use-browser-harness.svg)](https://hotskills.dev/skill/browser-use-browser-harness/)