Studio Jan Henrik Hansen
How it works
A short guide to this site — for humans and for the AI assistants we use to make things for it.
What this is
A lightweight host for shareable HTML. The whole site lives in a GitHub repo (SpaceMusicZH/Prototypes) with one folder per item under sites/. Adding a new folder — by any of the three methods below — triggers a rebuild and the item appears on the landing page automatically. Hosted at prototypes.origin-infinite.com.
Prototypes and documents
The site holds two kinds of thing, and each gets its own tab:
- Prototypes — things you click around in. They run code, have controls, do something when you poke them. This is the landing tab, at
/. - Documents — things you read. Write-ups, plans, architecture notes. Prose and diagrams, no moving parts. These live at
/documents/.
Which tab an item lands in comes from "type" in its meta.json. When you upload, the site reads the file and pre-selects the right one for you — the Type buttons at the top of the form show its guess, and you can override it before submitting. If a folder has no type at all, the same guess is made at build time, so nothing ends up homeless.
To move something between tabs later, open its ⋯ → Edit and switch the Type.
Adding something
Three ways, pick whichever fits:
- From this site. Click + Add in the header, pick a
.htmlfile or a.zip, check the Type, fill in title and tags, submit. The server commits a new folder to GitHub and the site redeploys within ~30–60 seconds. - From Dropbox. The Dropbox folder
4_FORSCHUNG/F032_Prototypes/prototypes.origin-infinite.com/is kept in two-way sync with thesites/folder in the repo. Duplicate_template/, rename the copyYYYY-MM-DD-your-slug, editindex.htmlandmeta.json. Within ~30 seconds the sync engine commits to GitHub and the site rebuilds. Edits made in Dropbox propagate to GitHub; archives made on this site propagate back to Dropbox. The sync dashboard is atsync.spacemusic.tv. - Via git. Create a folder under
sites/, drop inindex.htmlplusmeta.json, commit, push tomain. dev push redeploys.
meta.json schema
{
"title": "Human-readable title", // required
"type": "prototype", // optional — "prototype" or "document";
// guessed from the HTML if absent
"author": "armin", // optional
"date": "2026-05-13", // optional — falls back to folder prefix
"blurb": "One or two sentences.", // optional — appears on the card
"tags": ["ui", "experiment"] // optional — clickable filters on the index
}
Folder naming
Folders use the pattern YYYY-MM-DD-slug. The date prefix drives default sort order (newest first). Use the Date field in the Add modal to backdate an item if you're uploading something you made earlier.
ZIP rules
index.htmlmust exist at the ZIP root, or inside a single top-level folder (which gets stripped).- Path traversal (
..) is rejected. macOS metadata (__MACOSX/,.DS_Store) is stripped. - Caps: 100 files, 20 MiB uncompressed total.
Search & filter
The search bar matches against title, author, blurb, and tags. The tag chips at the top toggle filters — selecting multiple tags shows items matching any of them (OR). Search and tag filter combine: matches must satisfy both. Click Clear filters to reset.
Searching only looks inside the tab you're on. If your query also has hits in the other tab, a line appears under the results — "3 more matches in Documents →" — and clicking it takes your search with you. A filtered view is a shareable link: the address bar keeps up as you filter.
Editing & archiving
Each card has a ⋯ menu in the top-right with two actions:
- Edit opens the same form as the upload modal — type, title, author, date, blurb, tags. Changing the Type here moves the item to the other tab. The file isn't editable here; edit it via Dropbox or git if needed.
- Archive moves the folder from
sites/<slug>/tosites/_archive/<slug>/. It disappears from the index but the files remain in the repo, still visible in Dropbox, and can be restored by moving the folder back. Archive is not delete.
Where files live
sites/<folder>/— one folder per item (this is what you add to). Mirrored to/from Dropbox under4_FORSCHUNG/F032_Prototypes/prototypes.origin-infinite.com/.sites/_archive/— archived items. Visible in Dropbox, excluded from the index because the folder name starts with_.sites/_template/— starter folder a non-dev can duplicate in Dropbox to add something without writing JSON by hand. Excluded from the index._shared/— optional shared assets; served at/_shared/.... Not synced to Dropbox (lives outsidesites/)._template/— repo-level index page CSS + HTML and this docs page (different fromsites/_template/).build.mjs— scanssites/and writesdist/(one page tree per type).types.mjs— the prototype/document definition and the guesser both the build and the server use.serve.mjs— static server plusPOST /uploadandGET /me.
Folders starting with _ or . are excluded from the index but still served.
For AI agents
If you're an AI assistant being asked to add something, read CLAUDE.md in the repo — it has the local recipe (folder name, meta.json, build + commit). The same conventions apply whether you upload via the button or push directly.