Omahub
← All plugins
K

Globe Guesser

by kairos

Guess where in the world a photo was taken. Five rounds, an OpenStreetMap map and a spinnable globe to click, and photographs of real places from Wikipedia. Falls back to a bundled offline map when there is no network.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
e4e2be9
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

None
AI risk level
None
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
e4e2be9
Reviewed
1 month ago

I reviewed the manifest, README, and sample source and found a straightforward QML bar-widget game. Network use is limited to documented, opt-in queries to Wikipedia/Wikimedia and optional CARTO tiles, with all downloads bounded, cached in private directories, and sanitised before display. No obfuscation, destructive install actions, persistence tricks, or credential theft are present.

How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/kairos-tech-oh/omarchy-globe-guesser --enable
Widgets #bar

Globe Guesser

Globe Guesser mid-round: a coastal city photograph beside the world map, with Skip, Give up and Confirm

A photograph, somewhere on Earth. Click the map — or spin the globe — to say where you think it was taken.

Five rounds, 5,000 points each, scored on how close you got. Your best run is kept.

What it does

  • A real photo of a real place. Each round draws a city from a bundled list of the 1,000 largest in the world, then asks Wikipedia which articles sit near it and takes their lead images. An article with a coordinate is almost by definition a place — a station, a bridge, a district, a cathedral — and its lead image is a photograph an editor chose to show what that place looks like. The answer is the article's own recorded position, not the city centre.
  • Two ways to guess. A flat world map you can pan and zoom, or a globe you can spin. Both are drawn from bundled Natural Earth outlines, so the whole game works with no network, no account and no key. Add your own free CARTO key and the map upgrades to real OpenStreetMap tiles you can zoom to street level — see Map detail.
  • Playable without a mouse. Arrow keys (or hjkl) place and nudge the pin, Enter confirms, M and G switch between map and globe, Esc closes.
  • Attribution shown. Commons photographs are almost all CC-licensed. The photographer and the licence appear with the answer, because the licence is only honoured if they travel with the picture.

Use

Control What it does
Click the map or globe Place your guess
Drag Pan the map, or spin the globe
Scroll Zoom, centred on the pointer — all the way to street level with a CARTO key set, to country shapes without one
Arrow keys / hjkl Place the pin, then nudge it — finer the further you are zoomed in
M / G Switch to the map / the globe
Enter Confirm the guess, then move to the next round
Esc Close the panel — a game in progress is still there when you reopen it
Skip Draw a different photo without scoring the round

Install

omarchy plugin add https://github.com/kairos-tech-oh/omarchy-globe-guesser.git --enable

Then add Globe Guesser to your bar from the Omarchy settings UI, under Fun.

That is the whole install — the game plays with no key, no account and no network. Optionally, add a free CARTO key for street-level map detail: see Adding a key.

The shell normally picks the plugin up immediately. If the widget does not appear, restart it once:

omarchy restart shell

Update

omarchy plugin update kairos.globe-guesser --yes

Remove

omarchy plugin remove kairos.globe-guesser --yes

If the plugin directory was placed at ~/.config/omarchy/plugins/kairos.globe-guesser by hand rather than by omarchy plugin add, remove that directory and restart the shell instead:

rm -rf ~/.config/omarchy/plugins/kairos.globe-guesser
omarchy restart shell

State left behind. Two things, and omarchy plugin remove deletes neither, so remove them by hand if you want nothing left:

rm -f  ~/.local/state/omarchy/globe-guesser-state.json   # best score, games played
rm -rf "${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/omarchy-globe-guesser"
rm -rf ~/.cache/omarchy-globe-guesser                     # only if XDG_RUNTIME_DIR was unavailable

The first is a 34-byte JSON file holding your best score and how many games you have finished. The second is the download cache: at most three photographs, plus a tiles/ directory of at most 256 map tiles if you set a CARTO key. Both live in a directory that is cleared at logout anyway, because it is on tmpfs.

Your settings live in the shell's own shell.json alongside every other widget's, and are removed with the widget when you delete it from your bar. That includes your CARTO key, so removing the widget removes the key with it. To clear the key without removing the widget:

omarchy bar set kairos.globe-guesser cartoApiKey ""

Settings

Under Fun in the Omarchy settings UI. Any of them can also be set from a terminal, which takes effect immediately:

omarchy bar set kairos.globe-guesser <setting> <value>

The <setting> is the key name in the table below: difficulty, roundsPerGame, defaultView, searchRadiusKm, cartoApiKey.

Setting Options Default What it changes
Difficulty easy / normal / hard normal Which cities a round can come from: the 150 largest, the 500 largest, or all 1,000
Rounds per game 3–10 5 How many photos make up one game
Starting view map / globe map Which surface a round opens on. You can switch mid-round either way
Photo radius (km) 1–10 10 How far from a city centre a place may be. 10 km is both the default and MediaWiki's hard ceiling for a geosearch, so this only ever narrows the search
CARTO basemap key (cartoApiKey) text (empty) Optional. Empty means the map is drawn from bundled outlines and no tile is ever requested. Set it for street-level detail — see Adding a key

Network use

Three small requests per round, all anonymous, none needing an API key or an account. Out of the box the plugin makes no map-tile request at all — the map is drawn from bundled offline outlines. Street-level tiles are opt-in and need a key of your own; see Map detail below.

Service What for Published limit What this plugin does
en.wikipedia.org/w/api.php One geosearch query listing articles near a city with their coordinates and lead images No hard anonymous limit; the user-agent policy requires a descriptive User-Agent One identifying User-Agent, one query per round, never more than one request per second. Measured 17–30 KB per reply
upload.wikimedia.org Downloads the one chosen photograph — One download per round, capped at 6 MB, no redirects followed
commons.wikimedia.org/w/api.php The photographer and licence for that one file, so the credit can be shown as above One request per round, at reveal, off the path that decides how fast the photo appears. Measured 361 bytes
basemaps.cartocdn.com OpenStreetMap map tiles, while the map is on screen Requires an API key since August 2026; free to 5M tiles/month Only if you set a key. With none, nothing is requested. At most 64 tiles at a time, ~18 for a typical pane, six transfers in flight. Each capped at 256 KiB and refused unless it is a PNG of at most 512×512. Cached on disk and by URL, so panning back over ground already seen costs nothing

Map detail and the CARTO key

The game is fully playable with no key and no account. The map and the globe are drawn from bundled Natural Earth outlines — coastlines, borders, and the shapes you need to place a city — and that is the default.

What a key buys you is detail: real OpenStreetMap tiles you can zoom down to street level, which makes a hard round much more guessable.

In August 2026 CARTO began requiring an API key for their raster basemaps and stamping an API KEY REQUIRED watermark across every unauthenticated tile. The request still succeeds and the tile is still a valid image, so this is not a failure the plugin can detect and route around — it just comes back defaced. Rather than ship a watermarked map, or embed a key of ours that would be a shared secret in a public repository and our quota to exhaust, the key is yours:

Adding a key

1. Get one. Free at carto.com/basemaps/apikey, no card. Fair use is 5 million tiles a month — this plugin fetches about 18 for a new map view, and never re-fetches a tile it already has.

2. Set it.

omarchy bar set kairos.globe-guesser cartoApiKey "your_carto_key"

It takes effect immediately. No restart, no reopening the panel — open the map and the tiles are there.

The setting is named CARTO basemap key wherever Omarchy shows widget settings.

Changing or removing a key

Same command with the new value:

omarchy bar set kairos.globe-guesser cartoApiKey "your_new_key"

To remove it and go back to the bundled outlines, set it to an empty string:

omarchy bar set kairos.globe-guesser cartoApiKey ""

Clearing it takes effect immediately too: the tiles already on screen are dropped and the outlines come back, because a tile fetched under a key you have withdrawn is not one this plugin should keep showing.

Both commands edit the plugin's entry in ~/.config/omarchy/shell.json, so you can also edit that file directly if you prefer — the key lives on the widget's entry as "cartoApiKey".

Checking it worked

Zoom in. Streets and place names mean the key is good.

If the map comes back with API KEY REQUIRED written across it, the key is wrong. CARTO answers a bad key with exactly the same watermarked tile it sends for no key at all — byte for byte — so the plugin cannot tell those two cases apart and does not pretend to. Re-run the set command with the correct key.

If the map shows plain country outlines and no watermark, no key is set and nothing is being requested. That is the default and it is not an error.

Why CARTO and not tile.openstreetmap.org. The OSM Foundation's tile usage policy forbids distributing an application that draws on their servers — they are donated infrastructure for the map's own website, not a free CDN. The same rules out maps.wikimedia.org, whose policy limits it to sites hosted by the Wikimedia Foundation or its affiliates. CARTO renders the same OpenStreetMap data, and the map shows the attribution their terms require.

Every response is capped at the producer before the shell can hold it: 256 KiB for the article query, 32 KiB for the credit, 6 MB for the photograph. Nothing else is contacted, ever. The map, the globe, the scoring and the "12 km from Kyoto" line are all computed from bundled data.

Nothing is loaded into an Image straight off the network — not the photographs, and, since the decode ceiling was tightened, not the map tiles either. Both are downloaded first, under a byte ceiling at the producer, and both have their image header read and checked before anything decodes them.

The reason the header check exists and a size cap is not enough: a PNG stores its pixel count in the header and its pixels compressed, so the two numbers are unrelated. A 61 KiB file can declare 8000×8000. Qt's sourceSize does not save you there — it scales during load for JPEG only, and for any other format it loads the source at full size and scales afterwards, so the peak is already paid. Measured on Qt 6.11.1, loading such a file into an Image with sourceSize set to 320×240 peaked at 439.6 MiB against a 75.2 MiB baseline, inside the long-lived shell process. So a photograph is refused above 8 megapixels and a tile above 512×512, on the dimensions their headers declare, before a decoder ever sees the bytes.

One extra request happens when you open the panel while no game is running: the first round is fetched while you are still looking at the start screen, so pressing Start shows a photograph rather than a spinner. Opening the game is taken as intending to play; merely having the widget on your bar is not, and nothing is fetched at login.

Turn the network off mid-game and the photograph fails with a readable message and a Try another button. If you had tiles, the map notices they are not arriving and falls back to the bundled outlines, so you can still place a guess — with country shapes instead of streets. Without a key it was already drawing those outlines, so the map does not change at all.

Where the map comes from

The detailed map is OpenStreetMap data, rendered by CARTO, fetched as tiles while you play. The fallback map and the globe come from bundled data:

data/WorldOutline.js and data/Places.js are generated from Natural Earth (public domain), pinned to an exact upstream commit. data/PROVENANCE.md records the commit, the SHA-256 of every input and output, and how to reproduce them:

tools/build-world.py --check

Development

tools/run-checks.sh

Runs three things: that both data files rebuild byte-for-byte from the pinned upstream commit, that the maths and the sanitisers behave under Node, and that they behave under Qt's V4 engine — which is the engine omarchy-shell actually uses, and is not Node.

Files

File What it is
BarWidget.qml The bar slot and the click target that opens the panel
Panel.qml The game: state machine, the two network calls, scoring, persistence
GlobeMap.qml The guessing surface — tiles, outline canvas, markers, pan/zoom/spin
TileLayer.qml The OpenStreetMap tile grid — fetching tiles under a byte and dimension ceiling, caching them, and noticing when they cannot be reached
PhotoPane.qml The photograph, its loading and error states, and its attribution
GeoMath.js Projections and their inverses, great-circle distance, the score curve
Sanitise.js Everything that crosses into or out of the plugin as text
data/ Generated country outlines and city list, with provenance
tools/ The generator and the check suite

Dependencies

curl, head, od, mktemp, timeout, find — all present on any Omarchy install. python3 and node are needed only to regenerate the data or run the checks, never to play.

Attribution

Photographs are the lead images of Wikipedia articles, served by Wikimedia Commons, and remain under their own licences, shown with each answer.

Map tiles are © OpenStreetMap contributors, © CARTO, shown on the map itself. OpenStreetMap data is licensed under the ODbL.

The bundled fallback map and the city list are from Natural Earth, public domain.

Licence

MIT. See LICENSE.