#236 by GitHub stars
Oldcircle/geo-sleuth
Geolocate or chronolocate a photo with tool-verified reasoning (where was this taken / when was it taken / photo geolocation / geo-guessing). Given one or more photos, intake.py does metadata, OCR and reverse image search (Baidu/Yandex) in one command; clues and candidates go on a candidate board (b
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
skills/geo-sleuth/SKILL.md
Week of Nov 2, 2026 · +0 / −0 lines
Before Network or broad shell → After Network or broad shell
9a29a51cbe89 → 1a9ecee153b0
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → 9a29a51cbe89
No earlier version was observed for comparison.
Heat
8.6- Star growth, last 7 daysAhead of 100% of tracked repositories
- Star growth, last 24 hoursAhead of 99% of tracked repositories
- Rank movement, last 7 daysAhead of 97% of tracked repositories
- Commits, last 30 daysAhead of 93% 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
Individual skills in this repository
- geo-sleuth
skills/geo-sleuth
How it works
geo-sleuth
When your agent uses it
Geolocate or chronolocate a photo with tool-verified reasoning (where was this taken / when was it taken / photo geolocation / geo-guessing). Given one or more photos, intake.py does metadata, OCR and reverse image search (Baidu/Yandex) in one command; clues and candidates go on a candidate board (board.py) that ranks them and gives the next step; clues.py looks up calling codes, driving side, plates and area codes from region packs; for satellite and street view the machine ranks first and you look only at the top few (CLIP in sat_scan.py, DINOv2+SIFT in match.py); plus sun and shadow math, OSM Overpass and DEM skylines. Every conclusion is checked against real data; output is coordinates + error radius, evidence images and tiered confidence. Use when the user shares a photo and asks where was this taken / geolocate this / when was this taken / 这是哪 / 在哪拍的 / 帮我定位这张照片 / 网络迷踪 / 图寻 / 几点拍的.
What it loads into context
Frontmatter
235 tokensAlways available to the agent
SKILL.md
6,367 tokensWhen the skill is activated
Reference documents
49,579 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- Hard rules (always in force; ★ = enforced by board.py, just follow it)
- Flow
- Budget and stopping conditions
- Runtime environment
Scripts executed separately
scripts/_browser.pyscripts/_device.pyscripts/_image.pyscripts/_net.pyscripts/baidu_pano.pyscripts/board.pyscripts/clues.pyscripts/doctor.pyscripts/evidence.pyscripts/exif.pyscripts/gazetteer.pyscripts/geo.pyscripts/gsv.pyscripts/imgprep.pyscripts/intake.pyscripts/match.pyscripts/ocr.pyscripts/osm.pyscripts/poi.pyscripts/pose.pyscripts/refresh.pyscripts/regions.pyscripts/revimg.pyscripts/sat_scan.pyscripts/sun.pyscripts/terrain.pyscripts/tiles.pytests/test_board.pytests/test_gazetteer.pytests/test_match.pytests/test_regions.pytests/test_runtime.pytests/test_sun.pytests/test_terrain.py
Files
SKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesSKILL.mdcore27,456 bytesdata/README.mddoc2,725 bytesdata/calling_codes.jsonasset20,961 bytesdata/country_names.jsonasset28,841 bytesdata/driving_side.jsonasset32,964 bytesdata/territories.jsonasset14,436 bytesreferences/aerial.mddoc6,257 bytesreferences/clues/README.mddoc2,406 bytesreferences/clues/global.mddoc8,603 bytesreferences/corridors.mddoc20,335 bytesreferences/data-sources.mddoc13,054 bytesreferences/geometry.mddoc38,163 bytesreferences/observe.mddoc8,479 bytesreferences/search.mddoc17,951 bytesreferences/sky.mddoc13,217 bytesreferences/skyline-fallback.mddoc5,991 bytesreferences/verify.mddoc14,465 bytesregions/README.mddoc7,557 bytesregions/_template/README.mddoc309 bytesregions/_template/clues.mddoc581 bytesregions/_template/region.jsonasset211 bytesregions/ca/clues.mddoc1,108 bytesregions/ca/region.jsonasset154 bytesregions/cn/clues.mddoc19,243 bytesregions/cn/data/admin.jsonasset332,965 bytesregions/cn/data/area_codes.jsonasset62,183 bytesregions/cn/data/plates.jsonasset46,640 bytesregions/cn/region.jsonasset1,362 bytesregions/cn/search.mddoc2,792 bytesregions/cn/tests.jsonasset1,190 bytesregions/il/clues.mddoc1,884 bytesregions/il/data/admin.jsonasset2,751 bytesregions/il/data/area_codes.jsonasset2,704 bytesregions/il/region.jsonasset616 bytesregions/il/tests.jsonasset1,061 bytesregions/jp/clues.mddoc2,395 bytesregions/jp/region.jsonasset149 bytesregions/lk/clues.mddoc3,198 bytesregions/lk/data/admin.jsonasset4,297 bytesregions/lk/data/area_codes.jsonasset8,150 bytesregions/lk/data/plates.jsonasset1,255 bytesregions/lk/region.jsonasset574 bytesregions/lk/tests.jsonasset3,242 bytesregions/mm/clues.mddoc509 bytesregions/mm/region.jsonasset164 bytesregions/mx/clues.mddoc1,316 bytesregions/mx/region.jsonasset167 bytesregions/nz/clues.mddoc4,797 bytesregions/nz/region.jsonasset518 bytesregions/tr/clues.mddoc6,170 bytesregions/tr/data/admin.jsonasset6,713 bytesregions/tr/data/area_codes.jsonasset4,919 bytesregions/tr/data/plates.jsonasset4,997 bytesregions/tr/region.jsonasset628 bytesregions/tr/tests.jsonasset1,046 bytesregions/us/clues.mddoc628 bytesregions/us/region.jsonasset204 bytesscripts/_browser.pyruns1,205 bytesscripts/_device.pyruns1,160 bytesscripts/_image.pyruns12,521 bytesscripts/_net.pyruns1,672 bytesscripts/baidu_pano.pyruns17,750 bytesscripts/board.pyruns66,285 bytesscripts/clues.pyruns12,885 bytesscripts/doctor.pyruns9,988 bytesscripts/evidence.pyruns8,098 bytesscripts/exif.pyruns3,971 bytesscripts/gazetteer.pyruns21,726 bytesscripts/geo.pyruns65,142 bytesscripts/gsv.pyruns22,403 bytesscripts/imgprep.pyruns17,107 bytesscripts/intake.pyruns22,870 bytesscripts/match.pyruns22,535 bytesscripts/ocr.pyruns8,380 bytesscripts/osm.pyruns50,485 bytesscripts/poi.pyruns11,138 bytesscripts/pose.pyruns26,506 bytesscripts/refresh.pyruns27,083 bytesscripts/regions.pyruns27,905 bytesscripts/revimg.pyruns21,786 bytesscripts/sat_scan.pyruns16,396 bytesscripts/sun.pyruns31,171 bytesscripts/terrain.pyruns99,947 bytesscripts/tiles.pyruns15,333 bytestests/test_board.pyruns13,484 bytestests/test_gazetteer.pyruns14,379 bytestests/test_match.pyruns4,729 bytestests/test_regions.pyruns20,347 bytestests/test_runtime.pyruns79,952 bytestests/test_sun.pyruns2,379 bytestests/test_terrain.pyruns13,185 bytes
Read SKILL.md
# geo-sleuth (v2)
Goal: find a location that **holds up under checking**. Every conclusion must point to the clue it used, the command it ran and the file it produced.
> `${CLAUDE_SKILL_DIR}` in commands means the directory containing this SKILL.md (the same for commands in references). Claude Code substitutes it automatically; in other agents, first `export CLAUDE_SKILL_DIR=<absolute path of this directory>` before running (if the shell doesn't keep variables between commands, prefix every command with it), or replace it with that path directly.
The work is split into three layers. Remember this first, then read the flow:
| Layer | Who | Tools |
|---|---|---|
| Decision: which candidates exist, how evidence is scored, whether a candidate can be excluded, what to scan next | **Script** (candidate board) | `board.py` |
| Perception: reading text, table lookups, finding targets in satellite imagery, street-view matching | **Scripts compute and rank first; you look only at the top few** | `intake.py` `ocr.py` `clues.py` `sat_scan.py` `match.py` `geo.py bearings` |
| Judgment: pulling clues out of the image, proposing hypotheses when the tables have nothing, deciding among the machine's top few | **You** | — |
View the complete source on GitHubSkills included
- geo-sleuth
Repository facts
- License
- MIT
- Created
- Sep 18, 2026
- Last pushed
- Nov 5, 2026
- Forks
- 768
- Open issues
- 8
- Project activity
- Active
Rank over the last 12 weeks
Now #236 · best #236 · up 317 in 30 days
- #265 on Nov 1
- #253 on Nov 2
- #252 on Nov 3
- #249 on Nov 4
- #239 on Nov 5
- #236 since Nov 6
42 earlier periods
- #902 on Sep 13
- #920 on Sep 18
- #887 on Sep 19
- #906 on Sep 20
- #924 on Sep 21
- #940 on Sep 22
- #932 on Sep 23
- #894 on Sep 24
- #837 on Sep 25
- #858 on Sep 26
- #875 on Sep 27
- #923 on Sep 28
- #947 on Sep 29
- #913 on Sep 30
- #845 on Oct 1
- #853 on Oct 2
- #817 on Oct 3
- #837 on Oct 4
- #806 on Oct 5
- #779 on Oct 6
- #580 on Oct 7
- #553 on Oct 8
- #533 on Oct 9
- #507 on Oct 10
- #456 on Oct 11
- #439 on Oct 12
- #414 on Oct 13
- #376 on Oct 14
- #354 on Oct 15
- #347 on Oct 16
- #331 on Oct 17
- #329 on Oct 18
- #319 on Oct 19
- #309 on Oct 20
- #302 on Oct 21
- #297 on Oct 22
- #289 on Oct 23
- #286 on Oct 24
- #289 on Oct 25
- #283 from Oct 28 to Oct 29
- #284 on Oct 30
- #275 on Oct 31
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 2, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 9 notes
skills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedskills/geo-sleuth/regions/cn/data/admin.json:10102Analysis incomplete: regex work limit reached
- No broad tool permissions
- No dangerous shell commands
- 250 network referencesin 37 files: geo-sleuth/tests/test_runtime.py:50 geo-sleuth/scripts/doctor.py:34 geo-sleuth/scripts/osm.py:63 and 34 more
- 19 obfuscation signalsin 2 files: geo-sleuth/tests/test_runtime.py:677 geo-sleuth/regions/lk/region.json:6
- No instruction overrides
- 34 executable scriptsin 34 files: geo-sleuth/scripts/_browser.py:1 geo-sleuth/scripts/_device.py:1 geo-sleuth/scripts/_image.py:1 and 31 more
- 42 references to secretsin 20 files: geo-sleuth/tests/test_runtime.py:52 geo-sleuth/scripts/_net.py:11 geo-sleuth/scripts/board.py:68 and 17 more
- No requests to vote in Hot
Show all 345 signals by file
skills/geo-sleuth/data/README.md
- Network accessline 5
| File | Content | Source | Fetched | Entries | License | |---|---|---|---|---|---| | `calling_codes.json` | Country calling codes for countries and regions | [en.wikipedia.org/wiki/List_of_telephone_country_codes](https://en.wikipedia.org/ - Network accessline 6
|---|---|---|---|---|---| | `calling_codes.json` | Country calling codes for countries and regions | [en.wikipedia.org/wiki/List_of_telephone_country_codes](https://en.wikipedia.org/wiki/List_of_telephone_country_codes) | 2026-09-14 | 281 | - Network accessline 7
| `calling_codes.json` | Country calling codes for countries and regions | [en.wikipedia.org/wiki/List_of_telephone_country_codes](https://en.wikipedia.org/wiki/List_of_telephone_country_codes) | 2026-09-14 | 281 | Derived from Wikipedia, C - Network accessline 8
| `driving_side.json` | Driving side by country | [en.wikipedia.org/wiki/Left-_and_right-hand_traffic](https://en.wikipedia.org/wiki/Left-_and_right-hand_traffic) | 2026-10-08 | 241 | Derived from Wikipedia, CC BY-SA 4.0 | - Network accessline 9
| `territories.json` | Overseas territories and dependencies | [en.wikipedia.org/wiki/List_of_dependent_territories](https://en.wikipedia.org/wiki/List_of_dependent_territories) | 2026-09-14 | 60 | Derived from Wikipedia, CC BY-SA 4.0 | - Network accessline 10
| `country_names.json` | Chinese–English names and clue aliases; ISO codes for boundary lookup | Hand-compiled names; [Unicode CLDR codes](https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-localenames-full/main/en/territorie
skills/geo-sleuth/data/calling_codes.json
skills/geo-sleuth/data/country_names.json
- Network accessline 4
"fetched": "2026-09-14", "count": 300, "iso3166_source": "https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-localenames-full/main/en/territories.json", - Network accessline 5
"count": 300, "iso3166_source": "https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-localenames-full/main/en/territories.json", "iso3166_fetched": "2026-11-01", - Network accessline 6
"iso3166_source": "https://github.com/unicode-org/cldr-json/blob/main/cldr-json/cldr-localenames-full/main/en/territories.json",
skills/geo-sleuth/data/driving_side.json
skills/geo-sleuth/data/territories.json
skills/geo-sleuth/references/data-sources.md
- Network accessline 41
In China the same point differs by several hundred meters between WGS84 and GCJ-02. Conversion: `scripts/geo.py convert --from X --to Y a b`. - Amap links use gcj: `https://uri.amap.com/marker?position=<lon>,<lat>`; Google links use wgs. - Network accessline 42
- Amap links use gcj: `https://uri.amap.com/marker?position=<lon>,<lat>`; Google links use wgs. - Network accessline 61
The endpoints are all at `https://mapsv0.bdimg.com/`, need no key, and must be accessed directly:
skills/geo-sleuth/references/search.md
- Network accessline 131
EOF UA='<tool name>/<version> (<contact>)' curl -s -G https://query.wikidata.org/sparql --data-urlencode query@pool.rq \ - Network accessline 132
UA='<tool name>/<version> (<contact>)' curl -s -G https://query.wikidata.org/sparql --data-urlencode query@pool.rq \ -H 'Accept: application/sparql-results+json' -A "$UA" -o pool.json - Network accessline 133
curl -s -G https://query.wikidata.org/sparql --data-urlencode query@pool.rq \ - Network accessline 138
jq -r '.results.bindings[] | select(.img) | [(.c.value | split("/")[-1]), .img.value] | @tsv' pool.json | while IFS=$'\t' read -r qid url; do [ -s "thumbs/$qid.jpg" ] || curl -sfL -A "$UA" "$url?width=480" -o "thumbs/$qid.jpg"; sleep - Network accessline 139
while IFS=$'\t' read -r qid url; do [ -s "thumbs/$qid.jpg" ] || curl -sfL -A "$UA" "$url?width=480" -o "thumbs/$qid.jpg"; sleep 1 done - Network accessline 140
[ -s "thumbs/$qid.jpg" ] || curl -sfL -A "$UA" "$url?width=480" -o "thumbs/$qid.jpg"; sleep 1
skills/geo-sleuth/references/skyline-fallback.md
- Network accessline 17
[Crestline](https://github.com/ExtReMLapin/crestline) by @ExtReMLapin is a U-Net (ConvNeXt-Base) that segments sky, skyline and inner ridges. On clear skies it matches the default detector to 1–2 px; on snow ranges with cloud it cut the err
skills/geo-sleuth/regions/README.md
skills/geo-sleuth/regions/cn/data/admin.json
- Network accessline 2
"_meta": { "source": [ "https://raw.githubusercontent.com/modood/Administrative-divisions-of-China/master/dist/pca-code.json" - Network accessline 3
"source": [ "https://raw.githubusercontent.com/modood/Administrative-divisions-of-China/master/dist/pca-code.json" ], - Network accessline 4
"https://raw.githubusercontent.com/modood/Administrative-divisions-of-China/master/dist/pca-code.json"
skills/geo-sleuth/regions/cn/data/area_codes.json
- Network accessline 9
"miss_note": "not a mainland China landline area code (mobile number, 400/800, foreign number)", "source": [ "https://zh.wikipedia.org/zh-cn/中国大陆固定电话号码" - Network accessline 10
"source": [ "https://zh.wikipedia.org/zh-cn/中国大陆固定电话号码" ], - Network accessline 11
"https://zh.wikipedia.org/zh-cn/中国大陆固定电话号码"
skills/geo-sleuth/regions/cn/data/plates.json
skills/geo-sleuth/regions/il/clues.md
- Network accessline 10
- Strength: weak (five codes for the whole country; each covers several districts) - Counterexamples: `05x` is mobile and `07x` is VoIP, both used nationwide; `1-700`/`1-800` business numbers; the same digits are used in the West Bank and G - Network accessline 12
- Sources: en.wikipedia "Telephone numbers in Israel", section "Geographic area codes", https://en.wikipedia.org/wiki/Telephone_numbers_in_Israel - Network accessline 19
- Strength: medium (two sources) - Counterexamples: there are exceptions (Highway 1 lies mostly north of Highway 3); roads in the West Bank and Golan Heights use the same scheme - Sources: en.wikipedia "Roads in Israel", section "Numbering - Network accessline 21
- Sources: en.wikipedia "Roads in Israel", section "Numbering of the roads", https://en.wikipedia.org/wiki/Roads_in_Israel; he.wikipedia "כבישי ישראל" (even = south–north, odd = west–east, numbers rise northward and eastward), https://he.wi
skills/geo-sleuth/regions/il/data/admin.json
- Network accessline 2
"_meta": { "source": [ "https://en.wikipedia.org/wiki/Districts_of_Israel", - Network accessline 3
"source": [ "https://en.wikipedia.org/wiki/Districts_of_Israel", "https://www.openstreetmap.org (boundary=administrative, admin_level=4; code = OSM relation id)" - Network accessline 4
"https://en.wikipedia.org/wiki/Districts_of_Israel", - Network accessline 5
"https://www.openstreetmap.org (boundary=administrative, admin_level=4; code = OSM relation id)"
skills/geo-sleuth/regions/il/data/area_codes.json
- Network accessline 11
"miss_note": "not an Israeli geographic code: 05x mobile, 07x VoIP/non-geographic, 1-700/1-800 numbers", "source": [ "https://en.wikipedia.org/wiki/Telephone_numbers_in_Israel", - Network accessline 12
"source": [ "https://en.wikipedia.org/wiki/Telephone_numbers_in_Israel", "https://www.openstreetmap.org (phone=* on nodes, ways and relations, placed in boundary=administrative admin_level=4 polygons)", - Network accessline 13
"https://en.wikipedia.org/wiki/Telephone_numbers_in_Israel", - Network accessline 14
"https://www.openstreetmap.org (phone=* on nodes, ways and relations, placed in boundary=administrative admin_level=4 polygons)", - Network accessline 15
"https://www.allschool.co.il/מוסדות/410266/האלה-ממד-נחושה (HaEla school, Nehusha, Mateh Yehuda, Jerusalem District: 08-6815269)"
skills/geo-sleuth/regions/lk/clues.md
- Network accessline 7
### Province code on number plates - Look for: two small Latin letters below the emblem on the left side of the plate, before the main registration (e.g. `WP CAB-1234`). Codes: WP Western, CP Central, SP Southern, NP Northern, EP Eastern, N - Network accessline 8
- Look for: two small Latin letters below the emblem on the left side of the plate, before the main registration (e.g. `WP CAB-1234`). Codes: WP Western, CP Central, SP Southern, NP Northern, EP Eastern, NW North Western, NC North Central, - Network accessline 10
- Strength: weak for the photo location (registration province only; Western Province cars are common across the island) - Counterexamples: vehicles travel and are sold across provinces, and existing plates often keep their code even after - Network accessline 12
- Sources: Wikipedia "Vehicle registration plates of Sri Lanka" (format, codes, position), https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Sri_Lanka; Ada Derana 2022-12-30 (Commissioner General of Motor Traffic: removal from 1 - Network accessline 17
- Strength: medium (29 codes for 25 districts; a shop's or school's own landline is usually local) - Counterexamples: `07x` numbers are mobile and used island-wide; hotels, bank branches and chain head offices often show a Colombo `011` num - Network accessline 19
- Sources: TRCSL numbering plan as filed with the ITU (communication of 12.III.2008, update 17.VIII.2009), https://www.itu.int/oth/T02020000C3; en.wikipedia "Telephone numbers in Sri Lanka", https://en.wikipedia.org/wiki/Telephone_numbers_i
skills/geo-sleuth/regions/lk/data/admin.json
- Network accessline 2
"_meta": { "source": [ "https://www.openstreetmap.org (boundary=administrative relations tagged ISO3166-2=LK-*: admin_level=4 provinces, admin_level=5 districts; name = OSM name tag)", - Network accessline 3
"source": [ "https://www.openstreetmap.org (boundary=administrative relations tagged ISO3166-2=LK-*: admin_level=4 provinces, admin_level=5 districts; name = OSM name tag)", "https://en.wikipedia.org/wiki/ISO_3166-2:LK" - Network accessline 4
"https://www.openstreetmap.org (boundary=administrative relations tagged ISO3166-2=LK-*: admin_level=4 provinces, admin_level=5 districts; name = OSM name tag)", - Network accessline 5
"https://en.wikipedia.org/wiki/ISO_3166-2:LK"
skills/geo-sleuth/regions/lk/data/area_codes.json
- Network accessline 11
"miss_note": "not a Sri Lankan geographic code: 07x mobile, or a code missing from the TRCSL list (e.g. 046, 060)", "source": [ "https://www.itu.int/oth/T02020000C3 (TRCSL numbering plan filed with the ITU, communication of 12.III.2008 - Network accessline 12
"source": [ "https://www.itu.int/oth/T02020000C3 (TRCSL numbering plan filed with the ITU, communication of 12.III.2008, update 17.VIII.2009)", "https://en.wikipedia.org/wiki/Telephone_numbers_in_Sri_Lanka", - Network accessline 13
"https://www.itu.int/oth/T02020000C3 (TRCSL numbering plan filed with the ITU, communication of 12.III.2008, update 17.VIII.2009)", - Network accessline 14
"https://en.wikipedia.org/wiki/Telephone_numbers_in_Sri_Lanka", - Network accessline 15
"https://www.openstreetmap.org (phone=*/contact:phone=* placed in boundary=administrative admin_level=5 polygons)", - Network accessline 16
"https://rti.gov.lk/do-list/ (Government of Sri Lanka RTI designated-officer directory; local authority numbers: Embilipitiya UC, Ruwanwella PS, Dehiattakandiya PS)", - Network accessline 17
"https://www.statistics.gov.lk/Resource/en/Education/School_Census/2015.pdf (Ministry of Education school census 2015; Hanguranketha education office under Nuwara Eliya District)", - Network accessline 18
"https://slpost.gov.lk/si/information/main-offices-directorate/ (Department of Posts post-office directory; Hanguranketha post offices on 081)"
skills/geo-sleuth/regions/lk/data/plates.json
- Network accessline 11
"miss_note": "no province code (older or new-format plate), a misread code, or a foreign plate", "source": [ "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Sri_Lanka" - Network accessline 12
"source": [ "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Sri_Lanka" ], - Network accessline 13
"https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Sri_Lanka"
skills/geo-sleuth/regions/lk/region.json
- Possible obfuscationline 6
"ශ්<U+200D>රී ලංකාව",
skills/geo-sleuth/regions/nz/clues.md
- Network accessline 10
- Strength: medium (single source); needs another local clue. Colour without readable service text is weak. - Counterexamples: other buses can be red, green, orange or blue; generic "Link" text is insufficient. Routes change: since 17 Novem - Network accessline 12
- Sources: [Auckland Transport: Link bus service](https://at.govt.nz/bus-train-ferry/bus-services/link-bus-service) describes the four Link colours, their routes and the 2024 OuterLink change. - Network accessline 17
- Strength: medium (single source); corroborate with a stop name or an independent local clue. - Counterexamples: the same brand covers several towns and transport modes. A vehicle away from its route, or a portable ticket or promotional it - Network accessline 19
- Sources: [Greater Wellington: Metlink bus, train and ferry](https://www.gw.govt.nz/transport/metlink-bus-train-and-ferry/) defines the network's coverage and its responsibility for stops, stations and signage. - Network accessline 24
- Strength: medium (single source: Otago Regional Council); needs route text or another independent clue to narrow further. - Counterexamples: Orbus is shared by two networks, including places beyond the central cities such as Mosgiel and A - Network accessline 26
- Sources: [Otago Regional Council: About Orbus](https://www.orc.govt.nz/orbus/travel-with-us/about-orbus) describes both networks and their outlying services; [Route 1 changes](https://www.orc.govt.nz/orbus/dunedin-bus-timetables/dunedin-b - Network accessline 31
- Strength: medium (single source); corroborate with fixed local signage or another independent clue. - Counterexamples: on-demand pickup points vary, so the vehicle does not imply a scheduled bus stop. A relocated vehicle or portable promo - Network accessline 33
- Sources: [Metro Timaru: MyWay by Metro](https://timaru.metroinfo.co.nz/myway-by-metro/) identifies the service area and explains its variable pickup and drop-off points.
skills/geo-sleuth/regions/tr/clues.md
- Network accessline 10
- Strength: weak for where the photo was taken; medium when most parked cars in a quiet residential street share one code - Counterexamples: rental and fleet cars are often registered in 34 İstanbul, 06 Ankara, 07 Antalya or 35 İzmir and dr - Network accessline 12
- Sources: tr.wikipedia "Türkiye taşıt plaka kodu" (codes, 1962 alphabetical order, 68–81 for later provinces), https://tr.wikipedia.org/wiki/Türkiye_taşıt_plaka_kodu; tr.wikipedia "Türkiye'nin illeri" (code per province), https://tr.wikipe - Network accessline 17
- Strength: weak (single source) - Counterexamples: in recent years every province hands out `AAA 999` to `ZZZ 999` in sequence, so new plates say nothing about the district; the letter scheme differs per province and is not published as on - Network accessline 19
- Sources: tr.wikipedia "Türkiye taşıt plaka kodu", section "Plaka türleri", https://tr.wikipedia.org/wiki/Türkiye_taşıt_plaka_kodu - Network accessline 24
- Strength: medium (a shop's own landline is usually local; a single source of the code list is enough here because two tables agree) - Counterexamples: `0850`, `0800` and `444 xx xx` are nationwide numbers; `05xx` numbers are mobile; a cha - Network accessline 26
- Sources: tr.wikipedia "Türkiye'nin illeri" (telephone code column), https://tr.wikipedia.org/wiki/Türkiye'nin_illeri; en.wikipedia "Telephone numbers in Turkey" (212/216 split, full table), https://en.wikipedia.org/wiki/Telephone_numbers_ - Network accessline 33
- Strength: medium (single source) - Counterexamples: a sign at a junction can name a road that starts in the next province; misreading a state road `D 300` as a provincial number - Sources: tr.wikipedia "Türkiye'deki il yolları listesi" (e - Network accessline 35
- Sources: tr.wikipedia "Türkiye'deki il yolları listesi" (every listed road starts with its province's plate code), https://tr.wikipedia.org/wiki/Türkiye'deki_il_yolları_listesi - Network accessline 40
- Strength: medium (single source) - Counterexamples: branch roads (`D 014`, `D 052`) are short spurs that may lie away from the main road's band; overlapping routes share a carriageway and only one number may be signed - Sources: tr.wikipe - Network accessline 42
- Sources: tr.wikipedia "Türkiye'deki devlet yolları listesi", section "Yolların numaralandırılması", https://tr.wikipedia.org/wiki/Türkiye'deki_devlet_yolları_listesi - Network accessline 49
- Strength: weak by default, as for any vegetation without a month; medium when the month is known and the bushes show the clipped, flat-topped rows of a harvested plantation (Turkey's tea is grown almost only here) - Counterexamples: clipp - Network accessline 51
- Sources: en.wikipedia "Tea in Turkey" (Rize as the main region since the mid-20th century), https://en.wikipedia.org/wiki/Tea_in_Turkey; en.wikipedia "Rize Province", https://en.wikipedia.org/wiki/Rize_Province - Network accessline 56
- Strength: weak (needs the month, and a second clue) - Counterexamples: hazel grows wild and in gardens elsewhere; from a distance the clumps look like any mixed scrub - Sources: tr.wikipedia "Türkiye'de fındık üretimi", https://tr.wikiped - Network accessline 58
- Sources: tr.wikipedia "Türkiye'de fındık üretimi", https://tr.wikipedia.org/wiki/Türkiye'de_fındık_üretimi
skills/geo-sleuth/regions/tr/data/admin.json
- Network accessline 2
"_meta": { "source": [ "https://tr.wikipedia.org/wiki/Türkiye'nin_illeri", - Network accessline 3
"source": [ "https://tr.wikipedia.org/wiki/Türkiye'nin_illeri", "https://www.openstreetmap.org (boundary=administrative, admin_level=4 names)" - Network accessline 4
"https://tr.wikipedia.org/wiki/Türkiye'nin_illeri", - Network accessline 5
"https://www.openstreetmap.org (boundary=administrative, admin_level=4 names)"
skills/geo-sleuth/regions/tr/data/area_codes.json
- Network accessline 9
"miss_note": "not a Turkish province landline code: 05xx mobile, 0850/0800/0444 nationwide numbers, or 0392 (Northern Cyprus, dialled through +90)", "source": [ "https://tr.wikipedia.org/wiki/Türkiye'nin_illeri", - Network accessline 10
"source": [ "https://tr.wikipedia.org/wiki/Türkiye'nin_illeri", "https://en.wikipedia.org/wiki/Telephone_numbers_in_Turkey" - Network accessline 11
"https://tr.wikipedia.org/wiki/Türkiye'nin_illeri", - Network accessline 12
"https://en.wikipedia.org/wiki/Telephone_numbers_in_Turkey"
skills/geo-sleuth/regions/tr/data/plates.json
- Network accessline 11
"miss_note": "not 01–81: misread digits, a foreign plate, or not a civil plate", "source": [ "https://tr.wikipedia.org/wiki/Türkiye_taşıt_plaka_kodu", - Network accessline 12
"source": [ "https://tr.wikipedia.org/wiki/Türkiye_taşıt_plaka_kodu", "https://tr.wikipedia.org/wiki/Türkiye'nin_illeri" - Network accessline 13
"https://tr.wikipedia.org/wiki/Türkiye_taşıt_plaka_kodu", - Network accessline 14
"https://tr.wikipedia.org/wiki/Türkiye'nin_illeri"
skills/geo-sleuth/scripts/_browser.py
- Executable scriptline 1
Executable file
skills/geo-sleuth/scripts/_device.py
skills/geo-sleuth/scripts/_image.py
- Executable scriptline 1
Executable file
skills/geo-sleuth/scripts/_net.py
- Executable scriptline 1
Executable file - Access to secretsline 11
[Credential-related source omitted] - Network accessline 26
result = subprocess.run(cmd + [url], capture_output=True, timeout=timeout + 5) if result.returncode: raise RuntimeError(f"Request failed (curl exit {result.returncode}); run doctor.py --network to check connectivity.") - Network accessline 27
if result.returncode: raise RuntimeError(f"Request failed (curl exit {result.returncode}); run doctor.py --network to check connectivity.") return result.stdout - Network accessline 28
raise RuntimeError(f"Request failed (curl exit {result.returncode}); run doctor.py --network to check connectivity.") - Access to secretsline 37
[Credential-related source omitted] - Access to secretsline 39
[Credential-related source omitted] - Access to secretsline 41
[Credential-related source omitted]
skills/geo-sleuth/scripts/baidu_pano.py
skills/geo-sleuth/scripts/board.py
skills/geo-sleuth/scripts/clues.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/scripts/doctor.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 34
SERVICES = { "Baidu image search": "https://graph.baidu.com/pcpage/index?tpl_from=pc", - Network accessline 35
"Baidu image search": "https://graph.baidu.com/pcpage/index?tpl_from=pc", - Network accessline 36
"Baidu panoramas": "https://mapsv0.bdimg.com/?qt=qsdata&x=0&y=0", - Network accessline 37
"Yandex Images": "https://yandex.com/images/", - Network accessline 38
"Google satellite tiles": "https://mt1.google.com/vt/lyrs=s&x=0&y=0&z=0", - Network accessline 39
"Overpass": "https://overpass-api.de/api/status", - Network accessline 40
"Elevation tiles": "https://s3.amazonaws.com/elevation-tiles-prod/terrarium/0/0/0.png", - Network accessline 41
"Hugging Face": "https://huggingface.co/", - Network accessline 46
STREET_VIEW = ("https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/SingleImageSearch", - Network accessline 57
try: result = subprocess.run( ["curl", "-q", "-sSL", "--max-time", "12", *curl_args(proxy), - Network accessline 58
result = subprocess.run( ["curl", "-q", "-sSL", "--max-time", "12", *curl_args(proxy), "-A", "geo-sleuth-doctor/1.0", "-o", os.devnull, "-w", "%{http_code}", url], - Network accessline 62
code = result.stdout.strip() if result.returncode: return check(name, "FAIL", f"Connection failed (curl exit {result.returncode}).", - Network accessline 63
if result.returncode: return check(name, "FAIL", f"Connection failed (curl exit {result.returncode}).", "Check DNS, TLS certificates and network access.") - Network accessline 64
return check(name, "FAIL", f"Connection failed (curl exit {result.returncode}).", - Network accessline 69
"Retry later or inspect the service in a browser. HTTP 403/429 may mean a challenge or rate limit.") except (OSError, subprocess.TimeoutExpired): return check(name, "FAIL", "Probe could not complete within its time limit.", "Che - Network accessline 71
return check(name, "FAIL", "Probe could not complete within its time limit.", "Check curl and network access, then retry.") - Network accessline 77
try: result = subprocess.run( ["curl", "-q", "-sS", "--max-time", "12", *curl_args(proxy), "-X", "POST", - Network accessline 78
result = subprocess.run( ["curl", "-q", "-sS", "--max-time", "12", *curl_args(proxy), "-X", "POST", "-H", "content-type: application/json+protobuf", "-H", "x-user-agent: grpc-web-javascript/0.1", - Network accessline 82
capture_output=True, text=True, encoding="utf-8", errors="replace", timeout=15) except (OSError, subprocess.TimeoutExpired): return check(name, "FAIL", "Probe could not complete within its time limit.", "Check curl and network a - Network accessline 83
except (OSError, subprocess.TimeoutExpired): return check(name, "FAIL", "Probe could not complete within its time limit.", "Check curl and network access, then retry.") if result.returncode: - Network accessline 84
return check(name, "FAIL", "Probe could not complete within its time limit.", "Check curl and network access, then retry.") - Network accessline 85
if result.returncode: return check(name, "FAIL", f"Connection failed (curl exit {result.returncode}).", "Check DNS, TLS certificates and network access.") try: - Network accessline 86
return check(name, "FAIL", f"Connection failed (curl exit {result.returncode}).", "Check DNS, TLS certificates and network access.") - Access to secretsline 117
[Credential-related source omitted]
skills/geo-sleuth/scripts/evidence.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 8
Input is a JSON spec file: { "map": "area.jpg", # required: output of tiles.py fetch (needs the same-name .json next to it) - Network accessline 9
{ "map": "area.jpg", # required: output of tiles.py fetch (needs the same-name .json next to it) "crop": [x0, y0, x1, y1], # optional, crop in original-image pixels - Network accessline 10
"map": "area.jpg", # required: output of tiles.py fetch (needs the same-name .json next to it)
skills/geo-sleuth/scripts/exif.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/scripts/gazetteer.py
skills/geo-sleuth/scripts/geo.py
skills/geo-sleuth/scripts/gsv.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 42
META = "https://maps.googleapis.com/$rpc/google.internal.maps.mapsjs.v1.MapsJsInternalService/SingleImageSearch" - Network accessline 43
THUMB = ("https://streetviewpixels-pa.googleapis.com/v1/thumbnail?panoid={id}&cb_client=maps_sv.tactile" - Network accessline 46
COVERAGE = "https://www.google.com/maps/photometa/ac/v1?pb=!1m1!1smaps_sv.tactile!6m3!1i{x}!2i{y}!3i17!8b1" - Access to secretsline 259
[Credential-related source omitted]
skills/geo-sleuth/scripts/imgprep.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/scripts/intake.py
skills/geo-sleuth/scripts/match.py
skills/geo-sleuth/scripts/ocr.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/scripts/osm.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 63
ENDPOINTS = [ "https://overpass-api.de/api/interpreter", - Network accessline 64
"https://overpass-api.de/api/interpreter", - Network accessline 65
"https://overpass.private.coffee/api/interpreter", - Network accessline 66
"https://maps.mail.ru/osm/tools/overpass/api/interpreter", - Network accessline 69
UA = "geo-sleuth (+https://github.com/Oldcircle/geo-sleuth)" - Network accessline 82
# TLS handshake failed: Windows 10's Schannel curl has no TLS 1.3, and overpass-api.de accepts nothing older; Python's OpenSSL does - Network accessline 83
value = resolve_proxy(proxy) opener = urllib.request.build_opener(urllib.request.ProxyHandler({"http": value, "https": value} if value else {})) req = urllib.request.Request(ep, data=urllib.parse.urlencode({"data": ql}).enco - Network accessline 84
opener = urllib.request.build_opener(urllib.request.ProxyHandler({"http": value, "https": value} if value else {})) req = urllib.request.Request(ep, data=urllib.parse.urlencode({"data": ql}).encode(), headers={"User-Agent": UA}) - Network accessline 85
req = urllib.request.Request(ep, data=urllib.parse.urlencode({"data": ql}).encode(), headers={"User-Agent": UA}) - Network accessline 88
body, code = resp.read().decode("utf-8", "replace"), str(resp.status) except urllib.error.HTTPError as e: # 4xx/5xx still carry the server's message, as with curl body, code = e.read().decode("utf-8", "replace - Network accessline 89
except urllib.error.HTTPError as e: # 4xx/5xx still carry the server's message, as with curl body, code = e.read().decode("utf-8", "replace"), str(e.code) except OSError as e: - Network accessline 90
body, code = e.read().decode("utf-8", "replace"), str(e.code) except OSError as e: return None, f"curl exit 35, urllib: {e}" - Network accessline 91
except OSError as e: return None, f"curl exit 35, urllib: {e}" elif r.returncode: - Network accessline 92
return None, f"curl exit 35, urllib: {e}" - Network accessline 93
elif r.returncode: return None, f"curl exit {r.returncode}" try: - Network accessline 94
return None, f"curl exit {r.returncode}" - Network accessline 158
time.sleep(15 * (rnd + 1)) sys.exit(f"Overpass query failed on every mirror ({last}). HTTP 504/\"too busy\": retry later, or use --bbox / a smaller area; " f"HTTP 400: check the query syntax; curl exit: network or proxy (do - Network accessline 160
f"HTTP 400: check the query syntax; curl exit: network or proxy (doctor.py --network)") - Access to secretsline 737
[Credential-related source omitted]
skills/geo-sleuth/scripts/poi.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 49
r = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8", errors="replace") if r.returncode != 0: print(f"Request failed (curl exit code {r.returncode}): {r.stderr.strip()[:200]}", file=sys.stderr) - Network accessline 50
if r.returncode != 0: print(f"Request failed (curl exit code {r.returncode}): {r.stderr.strip()[:200]}", file=sys.stderr) return r.stdout - Network accessline 51
print(f"Request failed (curl exit code {r.returncode}): {r.stderr.strip()[:200]}", file=sys.stderr) - Network accessline 57
if city: q["cityname"] = city raw = _curl("https://restapi.map.so.com/newapi?" + urllib.parse.urlencode(q), proxy=proxy) - Network accessline 58
q["cityname"] = city raw = _curl("https://restapi.map.so.com/newapi?" + urllib.parse.urlencode(q), proxy=proxy) try: - Network accessline 59
raw = _curl("https://restapi.map.so.com/newapi?" + urllib.parse.urlencode(q), proxy=proxy) - Network accessline 80
if country: q["countrycodes"] = country raw = _curl("https://nominatim.openstreetmap.org/search?" + urllib.parse.urlencode(q), proxy=proxy, - Network accessline 81
q["countrycodes"] = country raw = _curl("https://nominatim.openstreetmap.org/search?" + urllib.parse.urlencode(q), proxy=proxy, ua="geo-sleuth/1.0 (photo geolocation research)") - Network accessline 82
raw = _curl("https://nominatim.openstreetmap.org/search?" + urllib.parse.urlencode(q), proxy=proxy, - Network accessline 94
def search_sug(kw: str, proxy: str | None = None) -> list[dict]: raw = _curl("https://map.baidu.com/su?" + urllib.parse.urlencode({"wd": kw, "cid": 1, "type": 0, "newmap": 1, "ie": "utf-8"}), proxy=proxy) - Network accessline 95
raw = _curl("https://map.baidu.com/su?" + urllib.parse.urlencode({"wd": kw, "cid": 1, "type": 0, "newmap": 1, "ie": "utf-8"}), proxy=proxy) - Access to secretsline 122
[Credential-related source omitted]
skills/geo-sleuth/scripts/pose.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/scripts/refresh.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 34
SOURCES = { "calling_codes": ["https://en.wikipedia.org/wiki/List_of_telephone_country_codes"], - Network accessline 35
"calling_codes": ["https://en.wikipedia.org/wiki/List_of_telephone_country_codes"], - Network accessline 36
"driving_side": ["https://en.wikipedia.org/wiki/Left-_and_right-hand_traffic"], - Network accessline 37
"territories": ["https://en.wikipedia.org/wiki/List_of_dependent_territories"], - Network accessline 38
"cn/admin": ["https://raw.githubusercontent.com/modood/Administrative-divisions-of-China/master/dist/pca-code.json"], - Network accessline 39
"cn/plates": ["https://zh.wikipedia.org/zh-cn/中华人民共和国民用机动车号牌"], - Network accessline 40
"cn/area_codes": ["https://zh.wikipedia.org/zh-cn/中国大陆固定电话号码"], - Access to secretsline 465
[Credential-related source omitted]
skills/geo-sleuth/scripts/regions.py
skills/geo-sleuth/scripts/revimg.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 54
"sogouimg": ("sogou.com", "sogoucdn.com")} BAIDU_REFUSED = ("功能优化中", "建议您重新上传其他图片") TEXT_URL = {"bing": "https://cn.bing.com/search?q={q}", "baiduimg": "https://image.baidu.com/search/index?tn=baiduimage&word={q}", - Network accessline 55
BAIDU_REFUSED = ("功能优化中", "建议您重新上传其他图片") TEXT_URL = {"bing": "https://cn.bing.com/search?q={q}", "baiduimg": "https://image.baidu.com/search/index?tn=baiduimage&word={q}", "sogouimg": "https://pic.sogou.com/pics?query={q}"} - Network accessline 56
TEXT_URL = {"bing": "https://cn.bing.com/search?q={q}", "baiduimg": "https://image.baidu.com/search/index?tn=baiduimage&word={q}", - Network accessline 57
"sogouimg": "https://pic.sogou.com/pics?query={q}"} - Network accessline 105
def fetch(url: str): - Network accessline 106
try: data = fetch_bytes(url, proxy, 15, {"User-Agent": UA, "Referer": "https://graph.baidu.com/"}) return Image.open(io.BytesIO(data)).convert("RGB") - Network accessline 107
data = fetch_bytes(url, proxy, 15, {"User-Agent": UA, "Referer": "https://graph.baidu.com/"}) - Network accessline 149
pending: list = [] page.on("response", lambda r: pending.append(asyncio.ensure_future(grab(r))) if "graph.baidu.com/ajax/pcsimi" in r.url else None) await page.goto("https://graph.baidu.com/pcpage/index?tpl_from=pc", wait_until="dom - Network accessline 150
page.on("response", lambda r: pending.append(asyncio.ensure_future(grab(r))) if "graph.baidu.com/ajax/pcsimi" in r.url else None) await page.goto("https://graph.baidu.com/pcpage/index?tpl_from=pc", wait_until="domcontentloaded", timeout - Network accessline 151
await page.goto("https://graph.baidu.com/pcpage/index?tpl_from=pc", wait_until="domcontentloaded", timeout=60000) - Network accessline 196
async def _yandex(ctx, img: Path, shot: Path) -> dict: page = await ctx.new_page() await page.goto("https://yandex.com/images/search?rpt=imageview", wait_until="domcontentloaded", timeout=60000) - Network accessline 197
page = await ctx.new_page() await page.goto("https://yandex.com/images/search?rpt=imageview", wait_until="domcontentloaded", timeout=60000) await page.wait_for_timeout(2500) - Network accessline 198
await page.goto("https://yandex.com/images/search?rpt=imageview", wait_until="domcontentloaded", timeout=60000) - Access to secretsline 343
[Credential-related source omitted]
skills/geo-sleuth/scripts/sat_scan.py
skills/geo-sleuth/scripts/sun.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/scripts/terrain.py
skills/geo-sleuth/scripts/tiles.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 39
SOURCES = { "google": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", - Network accessline 40
"google": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}", - Network accessline 41
"esri": "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}", - Network accessline 54
def fetch(center: tuple[float, float], zoom: int, radius: int, out: Path, source: str, - Access to secretsline 240
[Credential-related source omitted] - Access to secretsline 261
[Credential-related source omitted] - Network accessline 264
pl = sub.add_parser("px2ll", help="pixels on a mosaic (or a cropped/scaled copy of it) → lat/lon") pl.add_argument("image", type=Path, help="mosaic from tiles.py fetch (needs the same-name .json next to it)") - Network accessline 265
pl.add_argument("image", type=Path, help="mosaic from tiles.py fetch (needs the same-name .json next to it)") - Network accessline 293
if args.cmd == "fetch": lat, lon = map(float, args.center.split(",")) meta = fetch((lat, lon), args.zoom, args.radius, args.out, args.source, args.proxy, args.cache) - Network accessline 294
lat, lon = map(float, args.center.split(",")) meta = fetch((lat, lon), args.zoom, args.radius, args.out, args.source, args.proxy, args.cache) print(json.dumps(meta)) - Network accessline 295
meta = fetch((lat, lon), args.zoom, args.radius, args.out, args.source, args.proxy, args.cache)
skills/geo-sleuth/tests/test_board.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/tests/test_gazetteer.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/tests/test_match.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/tests/test_regions.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 25
"admin_levels": {"1": "admin1", "2": "admin2"}, "lookups": {"area-code": {"file": "data/area_codes.json"}}}, "data/area_codes.json": {"_meta": {"kind": "area-code", "source": ["https://example.org/codes"], "fetched": - Network accessline 26
"lookups": {"area-code": {"file": "data/area_codes.json"}}}, "data/area_codes.json": {"_meta": {"kind": "area-code", "source": ["https://example.org/codes"], "fetched": "2026-10-08", "license": "CC - Network accessline 27
"data/area_codes.json": {"_meta": {"kind": "area-code", "source": ["https://example.org/codes"], "fetched": "2026-10-08", - Access to secretsline 48
[Credential-related source omitted]
skills/geo-sleuth/tests/test_runtime.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 50
class NetworkTests(unittest.TestCase): def test_route_precedence(self): with patch.dict(os.environ, {"GEO_PROXY": "http://localhost:8123"}, clear=True): - Network accessline 51
def test_route_precedence(self): with patch.dict(os.environ, {"GEO_PROXY": "http://localhost:8123"}, clear=True): self.assertEqual(_net.resolve_proxy(), "http://localhost:8123") - Network accessline 52
[Credential-related source omitted] - Access to secretsline 52
[Credential-related source omitted] - Network accessline 53
self.assertEqual(_net.resolve_proxy(), "http://localhost:8123") - Network accessline 54
self.assertEqual(_net.resolve_proxy("http://localhost:8234"), "http://localhost:8234") - Network accessline 55
self.assertIsNone(_net.resolve_proxy("direct")) self.assertIsNone(_net.resolve_proxy("")) with patch.dict(os.environ, {"HTTPS_PROXY": "http://localhost:9999"}, clear=True): - Network accessline 56
self.assertIsNone(_net.resolve_proxy("")) with patch.dict(os.environ, {"HTTPS_PROXY": "http://localhost:9999"}, clear=True): self.assertIsNone(_net.resolve_proxy()) - Network accessline 57
[Credential-related source omitted] - Access to secretsline 57
[Credential-related source omitted] - Network accessline 60
@unittest.skipUnless(shutil.which("curl"), "curl required") - Network accessline 72
thread = threading.Thread(target=server.serve_forever, daemon=True) thread.start() base = f"http://127.0.0.1:{server.server_port}" - Network accessline 73
thread.start() base = f"http://127.0.0.1:{server.server_port}" try: - Network accessline 74
base = f"http://127.0.0.1:{server.server_port}" - Network accessline 75
try: with patch.dict(os.environ, {"HTTP_PROXY": "http://127.0.0.1:1", "http_proxy": "http://127.0.0.1:1", "ALL_PROXY": "http://127.0.0.1:1", "NO_PROXY": "*", "GEO_PROXY": "http://127.0.0. - Network accessline 76
[Credential-related source omitted] - Access to secretsline 76
[Credential-related source omitted] - Network accessline 77
"ALL_PROXY": "http://127.0.0.1:1", "NO_PROXY": "*", "GEO_PROXY": "http://127.0.0.1:1"}): - Network accessline 78
self.assertEqual(_net.fetch_bytes(base + "/direct", "direct"), b"ok") self.assertEqual(_net.fetch_bytes("http://example.invalid/proxied", base), b"ok") self.assertEqual(paths, ["/direct", "http://example.invalid/ - Network accessline 79
self.assertEqual(_net.fetch_bytes("http://example.invalid/proxied", base), b"ok") - Network accessline 80
self.assertEqual(paths, ["/direct", "http://example.invalid/proxied"]) - Network accessline 86
def test_model_route_overrides_ambient_variables(self): with patch.dict(os.environ, {"GEO_PROXY": "http://chosen:8080", "https_proxy": "http://old:8080", "NO_PROXY": "*"}, clear=True): - Network accessline 87
[Credential-related source omitted] - Access to secretsline 87
[Credential-related source omitted] - Network accessline 88
_net.model_proxy_env() self.assertEqual(os.environ["HTTPS_PROXY"], "http://chosen:8080") if os.name != "nt": # Windows environment variable names are case-insensitive - Network accessline 89
[Credential-related source omitted] - Access to secretsline 89
[Credential-related source omitted] - Access to secretsline 91
[Credential-related source omitted] - Access to secretsline 92
[Credential-related source omitted] - Access to secretsline 94
[Credential-related source omitted] - Access to secretsline 95
[Credential-related source omitted] - Network accessline 97
def test_baidu_near_forwards_proxy(self): with patch.object(baidu_pano, "fetch_bytes", return_value=b'{"content":null}') as fetch: self.assertIsNone(baidu_pano.near(35, 110, proxy="http://chosen:8080")) - Network accessline 98
with patch.object(baidu_pano, "fetch_bytes", return_value=b'{"content":null}') as fetch: self.assertIsNone(baidu_pano.near(35, 110, proxy="http://chosen:8080")) self.assertEqual(fetch.call_args.args[1], "http://chose - Network accessline 99
self.assertIsNone(baidu_pano.near(35, 110, proxy="http://chosen:8080")) - Network accessline 100
self.assertEqual(fetch.call_args.args[1], "http://chosen:8080") - Network accessline 104
poi.search_so("school", None, 2, "direct") self.assertEqual(fetch.call_args.kwargs["proxy"], "direct") poi.search_sug("school", "http://chosen:8080") - Network accessline 105
self.assertEqual(fetch.call_args.kwargs["proxy"], "direct") poi.search_sug("school", "http://chosen:8080") self.assertEqual(fetch.call_args.kwargs["proxy"], "http://chosen:8080") - Network accessline 106
poi.search_sug("school", "http://chosen:8080") self.assertEqual(fetch.call_args.kwargs["proxy"], "http://chosen:8080") with patch.object(poi, "_curl", return_value='[]') as fetch: - Network accessline 107
self.assertEqual(fetch.call_args.kwargs["proxy"], "http://chosen:8080") - Network accessline 108
with patch.object(poi, "_curl", return_value='[]') as fetch: poi.search_osm("school", None, 2, "http://chosen:8080", "us") self.assertEqual(fetch.call_args.kwargs["proxy"], "http://chosen:8080") - Network accessline 109
poi.search_osm("school", None, 2, "http://chosen:8080", "us") - Network accessline 110
self.assertEqual(fetch.call_args.kwargs["proxy"], "http://chosen:8080") - Network accessline 151
launch = AsyncMock(return_value=object()) p = SimpleNamespace(chromium=SimpleNamespace(launch=launch)) with patch.dict(os.environ, {"GEO_PROXY": "http://old:8080"}): - Network accessline 152
p = SimpleNamespace(chromium=SimpleNamespace(launch=launch)) with patch.dict(os.environ, {"GEO_PROXY": "http://old:8080"}): await _browser.launch_browser(p, "direct") - Network accessline 153
[Credential-related source omitted] - Access to secretsline 153
[Credential-related source omitted] - Network accessline 179
for returncode, stdout, status in [(0, "200", "PASS"), (0, "429", "WARN"), (7, "000", "FAIL")]: with self.subTest(status=status), patch.object(doctor.subprocess, "run", return_value=SimpleNamespace(returncode=returncode, stdout= - Network accessline 180
with self.subTest(status=status), patch.object(doctor.subprocess, "run", return_value=SimpleNamespace(returncode=returncode, stdout=stdout)): row = doctor.probe(("service", "https://example.invalid"), "direct") - Network accessline 181
row = doctor.probe(("service", "https://example.invalid"), "direct") - Network accessline 184
def test_local_checks_do_not_probe_network_or_print_proxy_credentials(self): with tempfile.TemporaryDirectory() as folder, patch.object(doctor, "browser_check", AsyncMock(return_value=doctor.check("browser", "PASS", "ready"))), patc - Network accessline 185
[Credential-related source omitted] - Access to secretsline 185
[Credential-related source omitted] - Network accessline 303
"""Windows 10's Schannel curl has no TLS 1.3, which overpass-api.de requires, so curl exits 35 before any HTTP.""" - Network accessline 316
thread = threading.Thread(target=server.serve_forever, daemon=True) thread.start() base = f"http://127.0.0.1:{server.server_port}" - Network accessline 317
thread.start() base = f"http://127.0.0.1:{server.server_port}" try: - Network accessline 318
base = f"http://127.0.0.1:{server.server_port}" - Access to secretsline 521
[Credential-related source omitted] - Access to secretsline 541
[Credential-related source omitted] - Network accessline 553
self.assertIsInstance(meta["description"], str) self.assertTrue(meta["description"].strip()) self.assertLessEqual(len(meta["description"]), 1024) # https://agentskills.io/specification - Network accessline 555
self.assertLessEqual(len(meta["description"]), 1024) # https://agentskills.io/specification - Access to secretsline 631
[Credential-related source omitted] - Possible obfuscationline 677
HEIC_HEAD = b"\x00\x00\x00\x1cftypheic" + b"\x00" * 64 - Possible obfuscationline 700
"JPEG": b"\xff\xd8\xff\xe0", "PNG": b"\x89PNG\r\n\x1a\n", "WEBP": b"RIFF\x00\x00\x00\x00WEBPVP8 ", - Possible obfuscationline 701
"GIF": b"GIF89a", "HEIF": HEIC_HEAD[:16], "AVIF": b"\x00\x00\x00\x1cftypavif", "TIFF": b"II*\x00\x08\x00\x00\x00", - Possible obfuscationline 706
self.assertEqual(_image.sniff(b"II*\x00\x10\x00\x00\x00CR\x02\x00", ".jpg"), "RAW") # Canon CR2 - Possible obfuscationline 707
self.assertEqual(_image.sniff(b"\x00\x00\x00\x18ftypcrx ", ".cr3"), "RAW") # Canon CR3 - Possible obfuscationline 708
self.assertEqual(_image.sniff(b"MM\x00*\x00\x00\x00\x08", ".NEF"), "RAW") # TIFF-based RAW by suffix - Possible obfuscationline 710
self.assertIsNone(_image.sniff(b"\x00\x01\x02\x03", ".jpg")) - Possible obfuscationline 730
(self.d / "noise.jpg").write_bytes(b"\x00\x01\x02\x03" * 20) - Possible obfuscationline 731
(self.d / "IMG_1.CR2").write_bytes(b"II*\x00\x10\x00\x00\x00CR\x02\x00" + b"\x00" * 64) - Possible obfuscationline 732
(self.d / "IMG_2.dng").write_bytes(b"II*\x00\x08\x00\x00\x00" + b"\x00" * 64) - Possible obfuscationline 747
for name, tags in (("dng_named.jpg", {254: 1, 50706: b"\x01\x06\x00\x00"}), ("preview_only", {254: 1, 330: 100})): - Possible obfuscationline 776
(self.d / "IMG_3.CR2").write_bytes(b"II*\x00\x10\x00\x00\x00CR\x02\x00") - Possible obfuscationline 785
(self.d / "IMG_4.NEF").write_bytes(b"MM\x00*\x00\x00\x00\x08" + b"\x00" * 64) - Possible obfuscationline 796
raw.write_bytes(b"II*\x00\x08\x00\x00\x00" + b"\x00" * 64) - Possible obfuscationline 851
(self.d / "y.CR2").write_bytes(b"II*\x00\x10\x00\x00\x00CR\x02\x00") - Possible obfuscationline 1237
(self.d / "IMG.CR2").write_bytes(b"II*\x00\x10\x00\x00\x00CR\x02\x00" + b"\x00" * 64) - Possible obfuscationline 1276
raw.write_bytes(b"II*\x00\x10\x00\x00\x00CR\x02\x00" + b"\x00" * 64) - Possible obfuscationline 1455
(self.d / "IMG_2.CR2").write_bytes(b"II*\x00\x10\x00\x00\x00CR\x02\x00" + b"\x00" * 64)
skills/geo-sleuth/tests/test_sun.py
- Executable scriptline 1
#!/usr/bin/env python3
skills/geo-sleuth/tests/test_terrain.py
- Executable scriptline 1
#!/usr/bin/env python3
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.
Declared and executed: 29 facts
- Contacts mapsv0.bdimg.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/baidu_pano.py:41High confidence
- Contacts graph.baidu.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:35High confidence
- Contacts mapsv0.bdimg.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:36High confidence
- Contacts yandex.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:37High confidence
- Contacts mt1.google.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:38High confidence
- Contacts overpass-api.de, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:39High confidence
- Contacts s3.amazonaws.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:40High confidence
- Contacts huggingface.co, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:41High confidence
- Contacts maps.googleapis.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/doctor.py:46High confidence
- Contacts maps.googleapis.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/gsv.py:42High confidence
- Contacts streetviewpixels-pa.googleapis.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/gsv.py:43High confidence
- Contacts www.google.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/gsv.py:46High confidence
- Contacts overpass-api.de, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/osm.py:64High confidence
- Contacts overpass.private.coffee, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/osm.py:65High confidence
- Contacts maps.mail.ru, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/osm.py:66High confidence
- Contacts restapi.map.so.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/poi.py:59High confidence
- Contacts nominatim.openstreetmap.org, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/poi.py:82High confidence
- Contacts map.baidu.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/poi.py:95High confidence
- Contacts en.wikipedia.org, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/refresh.py:35High confidence
- Contacts raw.githubusercontent.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/refresh.py:38High confidence
- Contacts zh.wikipedia.org, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/refresh.py:39High confidence
- Contacts cn.bing.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/revimg.py:56High confidence
- Contacts image.baidu.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/revimg.py:56High confidence
- Contacts pic.sogou.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/revimg.py:57High confidence
- Contacts graph.baidu.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/revimg.py:107High confidence
- Contacts yandex.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/revimg.py:198High confidence
- Contacts s3.amazonaws.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/terrain.py:61High confidence
- Contacts mt1.google.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/tiles.py:40High confidence
- Contacts server.arcgisonline.com, which SKILL.md, the README and the plugin manifest do not mentiongeo-sleuth/scripts/tiles.py:41High confidence
Signal confidence: 287 facts
- Network access in prose of documentationgeo-sleuth/data/README.md:5Low confidence
- Network access in prose of documentationgeo-sleuth/data/README.md:6Low confidence
- Network access in prose of documentationgeo-sleuth/data/README.md:7Low confidence
- Network access in prose of documentationgeo-sleuth/data/README.md:8Low confidence
- Network access in prose of documentationgeo-sleuth/data/README.md:9Low confidence
- Network access in prose of documentationgeo-sleuth/data/README.md:10Low confidence
- Network access in prose of documentationgeo-sleuth/references/data-sources.md:41Low confidence
- Network access in prose of documentationgeo-sleuth/references/data-sources.md:42Low confidence
- Network access in prose of documentationgeo-sleuth/references/data-sources.md:61Low confidence
- Network access in code of documentationgeo-sleuth/references/search.md:131Low confidence
- Network access in code of documentationgeo-sleuth/references/search.md:132Low confidence
- Network access in code of documentationgeo-sleuth/references/search.md:133Low confidence
- Network access in code of documentationgeo-sleuth/references/search.md:138Low confidence
- Network access in code of documentationgeo-sleuth/references/search.md:139Low confidence
- Network access in code of documentationgeo-sleuth/references/search.md:140Low confidence
- Network access in prose of documentationgeo-sleuth/references/skyline-fallback.md:17Low confidence
- Network access in code of documentationgeo-sleuth/regions/README.md:63Low confidence
- Network access in code of documentationgeo-sleuth/regions/README.md:64Low confidence
- Network access in code of documentationgeo-sleuth/regions/README.md:65Low confidence
- Network access in prose of documentationgeo-sleuth/regions/il/clues.md:10Low confidence
- Network access in prose of documentationgeo-sleuth/regions/il/clues.md:12Low confidence
- Network access in prose of documentationgeo-sleuth/regions/il/clues.md:19Low confidence
- Network access in prose of documentationgeo-sleuth/regions/il/clues.md:21Low confidence
- Network access in prose of documentationgeo-sleuth/regions/lk/clues.md:7Low confidence
- Network access in prose of documentationgeo-sleuth/regions/lk/clues.md:8Low confidence
- Network access in prose of documentationgeo-sleuth/regions/lk/clues.md:10Low confidence
- Network access in prose of documentationgeo-sleuth/regions/lk/clues.md:12Low confidence
- Network access in prose of documentationgeo-sleuth/regions/lk/clues.md:17Low confidence
- Network access in prose of documentationgeo-sleuth/regions/lk/clues.md:19Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:10Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:12Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:17Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:19Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:24Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:26Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:31Low confidence
- Network access in prose of documentationgeo-sleuth/regions/nz/clues.md:33Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:10Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:12Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:17Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:19Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:24Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:26Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:33Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:35Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:40Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:42Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:49Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:51Low confidence
- Network access in prose of documentationgeo-sleuth/regions/tr/clues.md:56Low confidence
and 237 more
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Compatible | Standard SKILL.md skills/geo-sleuth/SKILL.md | .claude/skills/<skill-name>/ |
| Codex | Compatible | Standard SKILL.md skills/geo-sleuth/SKILL.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md skills/geo-sleuth/SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md skills/geo-sleuth/SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md skills/geo-sleuth/SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md skills/geo-sleuth/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.
Explore alternatives and comparisons
Add this badge to your README
It updates every night and links to this page.
[](https://hotskills.dev/skill/oldcircle-geo-sleuth/)