Home (All Topics) → Technology → Software → AI-Created Software
By Marios Alexandrou on September 9, 2026.
The following AI-generated aka vibe-coded software. The software is specific to my needs and my system and may not work for you or your system. Support is limited, but if you report a bug I'll certainly look into it. All code is provided in a zip file for you to review should you choose.
A Chrome extension that files downloads into subfolders automatically, based on where they came from and what kind of file they are. Set a rule like huggingface.co → Models or .pdf → Documents, and matching downloads land in that folder instead of the general pile.
Version 3.0. Manifest V3. Works in Chrome, Vivaldi, Edge, Brave, and other Chromium browsers.
Not published to the Web Store, so load it unpacked:
manifest.json, the HTML, JS and CSS files at the top level, with the icons in an icons subfolder beside them.chrome://extensions (or vivaldi://extensions).After editing any file, hit the reload arrow on the extension’s card.
Changes to background.js or rules.js need that reload; changes to the interface take effect the next time you open it.
Click the toolbar icon for the popup, or open the full page — right-click the toolbar icon and choose Options, or press Open full page at the bottom of the popup.
Both surfaces are the same interface, built from the same code, so anything you can do in one you can do in the other. The full page just has room to breathe: it shows all 50 activity entries instead of the most recent six, and it isn’t at risk of being dismissed when a file dialog opens.
Adding a rule. Fill in a source domain (huggingface.co), a list of file types (pdf, zip, tar.gz), or both, then a destination folder, and click Add Rule. The folder is relative to your browser’s download directory and is created on first use.
Editing. Click Edit on any rule.
The form fills in and the button turns green and reads Update Rule. Cancel Edit backs out.
Turning a rule off. The checkbox at the left of each row switches a rule on and off without deleting it. A disabled rule is dimmed, keeps its place in the list, and is skipped entirely when a download arrives — useful for testing which rule is responsible for something.
Deleting. The red X removes a rule immediately, with no confirmation.
Replacing same-name files. Each rule has a checkbox: Replace files with the same name. Off (the default) means a second download of report.pdf is saved as report (1).pdf. On means it overwrites the existing file — silently, with no prompt, and the old file does not go to the trash.
Useful for a daily export that always arrives under the same name; risky for everything else. Each rule shows its current mode underneath in the list.
The Recent activity list records the last 50 downloads and what the extension did with each: the file, the site it came from, where it was saved, and which rule matched — or No rule matched, which is usually the more useful entry when something didn’t get filed where you expected.
Entries store the source hostname only, never the full URL, along with the filename and destination path. Everything stays in chrome.storage.local. Record switches logging off (existing entries are kept until you clear them), and Clear empties the list. The log is never included in an export.
A rule can match on a source domain, on file types, or on both. Every enabled rule is tested in list order and the first one that matches wins.
github.com + zip routes only the zips from GitHub, and leaves everything else from GitHub alone.Domain matching is a plain substring test against the source URL and the referrer URL, not a domain parse, and everything is compared in lower case. That has consequences worth knowing:
hub.co also matches github.com, because the text appears inside it. Prefer longer, more specific fragments.File types are matched against the end of the filename, so multi-part extensions like tar.gz work. Leading dots and case don’t matter: PDF, .pdf and pdf are the same thing. A filename literally called pdf, with no extension, is not a match.
Downloads that match nothing are left entirely alone, and disabled rules are skipped as though they weren’t there.
Subfolders work: AI/Models nests two levels deep. Before use, the folder string is cleaned up — backslashes become forward slashes, the characters : * ? " < > | are stripped, .. is removed so a rule can’t escape the downloads directory, and stray leading or trailing slashes are trimmed. If nothing survives that (a rule of .., say), the download is saved normally rather than to a broken path.
Export writes every rule to a JSON file named for the moment it was created, in local time:
download-router-settings-2026-09-06-143052.json
The file wraps the whole of the extension’s local storage:
{
"format": "download-router-settings",
"formatVersion": 2,
"exportedAt": "2026-09-06T18:30:52.114Z",
"settings": {
"rules": [
{
"id": "r-8fk21mq0",
"domain": "huggingface.co",
"extensions": [],
"folder": "Models",
"overwrite": true,
"enabled": true
}
]
}
}
Import opens a file picker, then shows what the file holds — how many rules, how many overlap with yours — before writing anything. Then choose:
The importer also accepts an export from any earlier version, a bare {"rules": ...} object, or a hand-written {"domain": "Folder"} map, so you can write a rule set by hand. Anything older is upgraded to the current shape on the way in.
Entries with no folder, or with neither a domain nor a file type, are skipped and reported in the summary rather than silently dropped.
Rules live in chrome.storage.local, which is per-profile and never synced. Export is how you move a setup to another machine, another browser, or a fresh profile.
Rules used to be stored as an object keyed by domain, which no longer works now that a rule can have no domain at all. Anything already in storage is converted to the new ordered-array shape the first time it’s read, and rewritten on install and on your next edit. Existing rules keep their folder and overwrite setting, come across enabled, and start with no file-type restriction, so routing behaves exactly as before. Old export files still import.
| File | Purpose |
|---|---|
manifest.json |
Extension metadata, permissions, icon declarations |
background.js |
Service worker; renames each download as it starts and records it |
rules.js |
Shared model: rule shape, migration, matching, storage and log helpers |
ui.js |
The interface — rule editor, backup, activity log |
ui.css |
Styles for both surfaces |
popup.html |
Toolbar popup shell |
options.html |
Full-page shell |
icons/icon16.png, icons/icon32.png, icons/icon48.png, icons/icon128.png |
Toolbar, extensions page, and store sizes |
icons/icon.svg |
Icon source, for regenerating the PNGs |
downloads — required to watch downloads and change where they land. This is the whole point of the extension.storage — saves your rules and the activity log locally.<all_urls> — carried over from earlier versions so the extension can read the source and referrer of each download. If you want to tighten things up, this is the one to try removing first; test a download from a site with a rule before deciding it’s safe to leave out.The extension makes no network requests of its own and sends nothing anywhere. Everything stays in local storage.
The file picker can close the popup. Chrome sometimes dismisses an extension popup when the OS file dialog takes focus, which cancels an import mid-flight. If that happens on your system, run the import from the full page instead, where nothing can dismiss the window.
Overwrite is permanent.conflictAction: 'overwrite' replaces the file in place.
There’s no undo and nothing lands in the trash.
The extension’s own export is never routed.
Downloads originating from the extension’s own URL skip rule matching, so a loose rule can’t file your backup somewhere unexpected.
“Ask where to save each file” still applies. If that browser setting is on, you’ll get a save dialog as usual; the routed path shows up pre-filled in it.
| Version | Change |
|---|---|
| 3.0 | File-type matching, per-rule enable/disable, activity log, full-page options view. Rules are now stored as an ordered array; older storage is migrated on read |
| 2.7 | Icons moved into an icons subfolder |
| 2.6 | Custom icon, declared at all four sizes and shown in the popup header |
| 2.5 | Export and Import moved to a sticky top bar; paste-JSON option removed |
| 2.4 | Export filename time as six digits (143052) |
| 2.3 | Time added to the export filename |
| 2.2 | Export and import of all settings |
| 2.1 | Per-rule option to replace same-name files |
| 2.0 | Rule editing UI |


Leave a Reply