Two gaps that were the same gap: the store list could only ever grow, and it could only grow from what the registry happened to offer. **Removing** uninstalls what the store installed, then deletes the store itself, in that order. The order is the whole of it: `state.json` is the only record of which payloads, icons and menu entries belong to a store, so deleting the home first would strip the one thing that knows — leaving files nothing could ever identify, least of all a later install of the same store into the same folder. The confirmation says how many titles will go, because that is the part nobody would otherwise expect. The token goes too; a credential for a store that is not here is a secret kept for nothing. The window names a *store*, never a path: the home is resolved against what a disk scan actually found before anything is deleted, and `removeHome` refuses anything else. That is the only guard between a bad argument and `rm -rf`, so it has a test. **Adding** moved to a + beside Refresh — both are actions on the whole store rather than on one of them, and the full-width button under the list read as a third store — and the picker now takes a catalog address as well as a listed one. A bare host is enough and the name comes from the address; nothing else about installing changes, which is why the typed path hands the same record to the same method instead of growing a second one. The picker also has a Cancel now: opening it with a store installed used to replace the grid with no way back. `make storetest` is new, and it earned itself immediately. Removal is the only code here that deletes a directory tree, which the smoke test cannot cover — it runs against the real machine and would have to delete a real store to prove anything. Two bugs on the first run: - `http://` was accepted and became a store called *http*. The trailing slashes were stripped before the scheme was checked, turning `http://` into `http:` and then into `https://http:`, whose hostname parses as "http". The URL is rebuilt from the parsed form now, which also settles the trailing slash in one place. - `STORE_ROOT` only *prepended* to the search path, so a "sandboxed" run still listed the real stores — despite the README saying "instead of the real one". Harmless while a sandbox could only add; not harmless now that it can delete. It replaces the search path. The self-test needed two changes, both of which are it working: the store row is a wrapper now, so clicking `.store-row` did nothing at all, and the footer icon check counted exactly two named controls when there are three. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1.9 KiB
WarpEngine Client 2.5.0
A store can be taken off the machine again. Hovering a store in the side menu shows
a bin. It asks first, and says how many titles will go with it — because removing a
store uninstalls what it installed. That is not a convenience: a store's state.json
is the only record of which payloads, icons and menu entries belong to it, so leaving
the games behind would leave orphans nothing could ever identify, least of all a later
install of the same store into the same folder. The catalog cache, the settings and any
sign-in token go too.
Adding one moved to a + beside Refresh, and it now takes a catalog address of your
own as well as the ones the registry lists. A bare host is enough — https is assumed —
and the name is taken from the address. Both are actions on the whole store rather than
on one of them, which is why they sit together; the full-width "Add a store…" button
under the list read as a third store.
The picker has a way out. Opening it with a store already installed used to be a trap: the grid was replaced and nothing short of installing something brought it back.
Two things found by the new test. make storetest adds and removes a store in a
sandbox, because removal is the only code here that deletes a directory tree and the
path it deletes is named by the window. It immediately caught that http:// was
accepted and became a store called http — the trailing slashes were being stripped
before the scheme was checked — and that STORE_ROOT only prepended to the search
path, so a "sandboxed" run still listed the real stores. With a delete button in the
window, a sandbox that can reach a working installation is not a sandbox; it replaces
the search path now.
btn-secondary had no styling at all. It was introduced in 2.4.0 on the card's
sign-in button and on the sign-in panel, and rendered as a plain button in both places.