Commit Graph
59 Commits
Author SHA1 Message Date
phantomptrandClaude Opus 5.5 1934dc8e9d fix(api): appInfoDetails checks ok through assertOk
The require-assert-ok lint rule failed CI on main: the function tested
res.ok by hand. A refusal now throws inside the existing try and still
yields null (no details), so behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 22:13:06 -07:00
phantomptr 5a28819d25 Release v5.39.0 2026-09-28 21:45:11 -07:00
phantomptrandClaude Opus 5.5 2cad667901 feat(cheats): game-first Cheats screen with covers, details and version matching; mark PS5 messages read
Cheats: the screen lists the console's games (cover, name, installed
version) grouped as playing / ready / to download / none, using the full
repo index (fetched once) to show availability per game. The detail pane
shows appinfo details (version, size, install and last-opened dates,
content id), the downloaded cheats as switches (disabled with an
explanation while the game isn't running, since the payload refuses a
toggle then), and every repo file ranked with the installed version first
and a prominent Download button. appInfoDetails() wraps /api/ps5/appinfo;
the browser shim now accepts Tauri's camelCase titleId.

Notifications: the payload ring carries no read state, so every entry was
unread forever. Read state now lives client-side per console (watermark +
exceptions) with Mark read / Mark unread / Mark all as read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 21:45:07 -07:00
phantomptr 05fa3178db Release v5.38.0 2026-09-28 18:13:57 -07:00
phantomptrandClaude Opus 5.5 15dd1a0c44 feat(install): each queue row carries its install's full status
The running install's phase, bytes, speed, time left and status notes now
live on its queue row instead of a page-level banner. Installers report
structured progress through InstallHooks (phase/current/total/rate) and
status notes through onStatus, which the queue stores on the item.

The queue is grouped into Now / Up next (run order) / Finished, with
summary chips, compact waiting rows, and reordering that swaps only with
the neighbour of the same install tier. The Install page drops the
duplicate stream-result card, reorders its sections, folds the FPKG
checklist, and gives link download-first its own notice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 18:13:03 -07:00
PhantomPtrandClaude Opus 5.5 105e4aae96 chore(android): run-android reuses and foregrounds the emulator; software rendering by default (#339)
* chore(android): run-android foregrounds and reuses the emulator; faster emulator

- ensure reuses a running or still-booting emulator instead of booting a
  second; run-android brings its window to the front and reopens a headless
  one with a window; run-android-background leaves it headless.
- A stopped emulator is waited on until it has really exited (forced after
  60s), so a restart no longer mistakes it for one that is booting.
- Windowed emulators render on the host GPU instead of software, with 4 GB
  RAM and up to 6 cores.
- Android dev serves Vite on 1430/1431 (PS5UPLOAD_VITE_PORT), so it can run
  alongside desktop dev on 1420.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(android): software rendering by default; host GPU is opt-in

-gpu host froze the Android 16 image within minutes on an M1 Max (the
emulator warns its guest GL layer is unstable above API 35), with or
without Guest ANGLE. PS5UPLOAD_EMU_GPU=host opts back in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 17:31:42 -07:00
phantomptr 3190458798 Release v5.37.2 2026-09-28 16:47:58 -07:00
PhantomPtrandClaude Opus 5.5 e6e8601363 Files crash: reload on a missing screen chunk; make keeps node_modules; dev FAQ/changelog (#340)
* fix(app): a screen whose code is gone reloads the page instead of crashing

Screens load on demand; when a screen's file can't be fetched the
import rejects ('Importing a module script failed') and the route showed
the crash screen. That happens to a web UI tab left open across an
update (it asks for file names the new build doesn't have) and to a dev
server whose dependency cache was rebuilt under it. Reproduced by
swapping the served build under an open tab: main showed the crash
screen for Files; now the page reloads once and opens Files from the
new build. A second failure within 30 s shows the error, so an outage
can't reload forever.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(make): don't reinstall client dependencies that already match the lockfile

setup-client ran npm ci on every make (run-client, run-android, emu-test,
dist-*). npm ci deletes node_modules first — Vite's dependency cache
with it — so a dev server already running lost its cache and its
screens failed ('Importing a module script failed' on Files). It now
reinstalls only when package-lock.json or Node changed since the last
install (a stamp in node_modules). Checked: a make during a running dev
server leaves it working; a stale stamp still reinstalls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(dev): the FAQ and What's New screens load on the dev server

They imported the repo-root FAQ.md and CHANGELOG.md with ?raw, and the
dev server served those (outside the client folder) as raw markdown
instead of modules. A small Vite plugin exposes them as virtual modules,
which go through the normal pipeline in dev and in builds (each is its
own on-demand chunk, locally and in the Docker web UI build). New e2e
test: both screens show their document.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(changelog): 5.37.2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 16:47:36 -07:00
phantomptr d8e62af42d Release v5.37.1 2026-09-28 14:55:47 -07:00
PhantomPtrandClaude Opus 5.5 6f5abad2b5 elfldr that recovers by itself; 75-minute publish builds; 5.37.1 notes (#338)
* feat(elfldr): vendor elfldr with a read deadline, embedded in the engine

elfldr serves one connection at a time and its reads had no deadline,
so a client that went silent without closing (a dropped link, a machine
or console asleep mid-send) left it running but deaf on :9021 — users
had to load elfldr again. Measured on the Phat (FW 5.10): the stock
build answered nothing while a silent connection stayed open; with a
15 s SO_RCVTIMEO it dropped that connection and answered the next
request at once, and a payload sent with 10 s pauses still loaded.

third_party/elfldr is upstream 02cfe91 plus ps5upload.patch (GPLv3,
credited), with the tested ELF checked in so every engine build embeds
it; `make elfldr` rebuilds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(elfldr): the engine swaps a console's stock elfldr for the patched one

GET /api/ps5/elfldr/health tells healthy / stuck / absent from a request
elfldr answers without running anything. POST /api/ps5/elfldr/ensure
replaces the standard elfldr.elf with the embedded patched build when it
answers and isn't the one this engine installed (a reboot or autoloader
brings the stock one back), leaves any other loader on :9021 alone, and
returns once the new one answers. On the Phat: upgraded (pid 685,
answering at once), then 'current'; the helper was untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(publish): give each client build 75 minutes

The Intel macOS build ran past the 45-minute limit for v5.37.0 (about
33 minutes for v5.35.0 and v5.36.0), which cancelled it and skipped
create-release, so v5.37.0 was never published.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(engine): history tests get their own temp dirs

TmpDir named directories by pid and nanoseconds, but macOS time ticks in
microseconds: two tests starting together shared a directory and one
deleted it under the other (a_legacy_host_port_file_is_still_read read
nothing). A counter makes each name unique. The elfldr embed test reads
the embedded bytes directly instead of clearing an env var mid-run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(elfldr): the app keeps the patched elfldr in place and never sends into a stuck one

Before sending the helper, the app checks the console's loader: a stuck
one (took the connection, never answered) is waited out for 20 s — the
patched build clears in 15 — and one that stays stuck is reported
plainly ('load elfldr again') instead of a socket error. Once the helper
is up, the engine swaps the stock elfldr for the patched build: at once
after a fresh helper send (a reboot or wake brings the stock one back),
else at most every 10 minutes per console. Desktop, browser and Android
share the engine routes; strings in all 20 languages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(changelog): 5.37.1 — elfldr recovers by itself; 5.37.0 folded in

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(elfldr): swap it in when the helper is already up at launch

Only ensurePayloadCurrent asked for the patched elfldr, and a helper
that is already up when the app opens never goes through it — on the
Phat the stock elfldr stayed. The status poll's 'arrives at up' edge
(first sighting included) now asks too, after the same settle as the
log capture and never during a transfer.

Hardware (Phat FW 5.10, web build and Android app): stock elfldr
replaced ~10 s after opening; a silent :9021 connection held while the
helper was shut down — the helper came back through the patched
elfldr; with the stock elfldr wedged, the Android app sent nothing for
150 s (health: stuck), then redeployed and swapped elfldr once released.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(convert): the compress stage pays for reading and writing on one thread

kraken_image::compress runs the encoder on a pool, but one thread reads
the source and writes each compressed block, so the stage takes the
longer of encoding and read+write — not the slower of reading and
encoding, as the estimate assumed. With the Windows Battlefield 6 run's
speeds the model now gives 75 min for a 71-min build.

The estimate also reports the speeds it measured (rates), because the
small read/write samples can be fooled by caches: on a source read an
hour earlier the read sample hit the file cache at 8.6 GB/s and the
estimate came out at 25 min for a 54-min build. Calibrating from past
builds is the follow-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(changelog): build-time estimate, stated as measured

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* ci(docker): 25 minutes for the PR image checks

Both PR gates build the whole image (engine, and the client for the web
UI one) in about 7-10 minutes; the engine gate took 9m55s and the web UI
gate was cancelled at its 10-minute limit on PR #338.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:55:05 -07:00
phantomptr ce76e9dec5 Release v5.37.0 2026-09-28 12:16:16 -07:00
phantomptrandClaude Opus 5.5 e338b29973 test(e2e): the sidebar lists every screen from the start
The browser smoke test still expected the Favorites sidebar (Home only,
"Star screens in More"); links now appear in both the sidebar and
More, so More's are looked up inside the page body.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:46:34 -07:00
phantomptrandClaude Opus 5.5 c155c08c88 fix(convert): the time estimate covers the whole build, at the speed the drives allow
A 234 GiB game estimated at 17 min took 71: the estimate timed only
compression, of blocks already in memory, one thread multiplied by the
thread count. It now times the source's sequential reads and the
output drive's writes, runs the sample on every thread at once, and
adds the package's write and verify to compression bounded by the
slower of reading and encoding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:41:06 -07:00
phantomptrandClaude Opus 5.5 ca84bb2b61 feat(nav): the sidebar shows every screen; hide what you don't use
The desktop sidebar held Home, your starred screens and About, so a new
user saw nothing else — Convert and File System lived behind the More
icon. It now lists every screen in its sections (each folds away,
remembered); hover a row to hide it, and More's eye switch brings it
back. Hidden screens and folded sections are mirrored to settings.json.
Favorites are retired; nothing is hidden at first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:32:56 -07:00
phantomptrandClaude Opus 5.5 fedaba42e8 fix(css): raw buttons honour their text and font classes
An unlayered `button { font: inherit }` outranked every Tailwind
utility (they live in @layer), so each raw <button> ignored its
text-/font- classes: sidebar headers, tabs, Refresh and the Install
Package header actions rendered at body size. Tailwind's own base layer
already sets it. Checked before/after on 16 screens at desktop and
phone widths; nothing overflows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:32:56 -07:00
phantomptrandClaude Opus 5.5 8b2758290f fix(icons): a suffixed save folder shows its game's icon and name
Saves listed a console folder named PPSA17221.bak and asked the engine
for the icon of "PPSA17221.bak" (400, then a retry). GameIcon now
looks up the leading title id and skips names that aren't one; the
Saves header names the game too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:31:50 -07:00
phantomptrandClaude Opus 5.5 d75a5adf4b fix(picker): with folders ticked, Add is the one action
"Use this folder" resolved only the open folder and dropped the ticks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:06:48 -07:00
phantomptrandClaude Opus 5.5 f9fbfd5734 chore: untrack a client/node_modules symlink committed by mistake
59440903 committed a worktree's node_modules symlink, pointing at an
absolute path on the author's machine. `node_modules/` only ignores
directories; `node_modules` covers a symlink too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:59:04 -07:00
phantomptrandClaude Opus 5.5 ba68a1910a fix(picker): let the multi-pick hint wrap on a phone
Seen on the Android emulator: "add them toget…" was cut off beside
the Add button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:58:38 -07:00
phantomptrandClaude Opus 5.5 93e02d8969 feat(convert): Game language — declare one PlayGo language in the package
Battlefield 6's eboot imports scePlayGoGetLanguageMask: it asks the
install which language it has, and every converted package answered
"all 31, en-US first". Convert's Options card now takes one language;
the package's playgo-scenario.json then lists it as the default and
only language (the shape Sony's own scenarios take). Carried through a
single run and the Convert queue; reset per game.

Checked on the Phat (FW 5.10): a fr-FR Minecraft build installs and
plays like the all-language control.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:49:40 -07:00
phantomptrandClaude Opus 5.5 8d128ad520 feat(picker): tick several files or folders in the in-app browser
The browser build and Android browse in-app, which picked one path at a
time. pickLocalPaths() opens it with checkboxes kept across folders and
an Add N button; Upload's Choose file/folder feed every pick to the
batch list, pickPaths() uses it off-desktop, and Convert's queue gains
Pick several….

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 09:11:50 -07:00
phantomptrandClaude Opus 5.5 79d49c08a8 fix(layout): buttons never shrink below their label; the Games grid fills by room, not window width
Buttons in tight rows ellipsized to "Ref…" / "Connect a NAS…"; they keep their
label now (rows wrap). The game cover grid chose columns by window width, so
beside the sidebar at 768 px it squeezed four 99 px cards; it now fits as
many ≥8 rem columns as the space holds (two on a phone, more on wide windows).
Scanned at 390/768/1280: no overflow, no cut labels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 08:14:48 -07:00
phantomptrandClaude Opus 5.5 07c7f1de00 fix(mobile): header actions and the Upload picker row wrap instead of squeezing labels; titles wrap on phones
On a phone, header action rows shrank their buttons to "Ref…" / "New f…" /
"From this d…" (File System, Install Package) and Upload's picker row
crushed three buttons into fragments. Rows wrap now; a long page title wraps
to two lines on a phone instead of truncating.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 08:02:39 -07:00
phantomptrandClaude Opus 5.5 c40d70ce7c fix(button): an icon passed as a child stays on the label's line
The label span is a block (for truncation) and a block-level svg sat above
the text: Refresh / Add a server / Add point / Reset play time… rendered as an
icon over a word on every screen that passes the icon as a child.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 08:00:27 -07:00
phantomptrandClaude Opus 5.5 0f296fdfcb style(icons): one icon per screen, the same in the menu and the page header
Audit log, Connection, Game activity and Processes showed a different icon in
their header than in the menu; Cheats shared the Games gamepad, Edit game image
shared the Volumes drive, Processes shared the Console CPU. Now: audit log
shield-check, connection cable, game activity clock, processes layers, cheats
wand, edit game image file-pen, games gamepad.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:58:19 -07:00
phantomptrandClaude Opus 5.5 ea5b7700d7 style: every screen in the same page frame; Convert uses two columns on wide windows
Screens sat in a mix of centered 3xl/4xl/5xl columns with 16 or 24 px padding,
leaving half a wide window empty on some and not others. All screen roots (and
the tabbed shell) now use the shared app-page frame: one max width, 24 px
padding, 16 px on phones. Convert puts the game and its options beside
building and the queue at xl widths. The queue's Start button only shows when
something is waiting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:56:34 -07:00
phantomptrandClaude Opus 5.5 fb1d384154 fix(web): FAQ and Changelog load in the browser build; Keep awake and Capture don't offer what a web page can't do
The browser build showed developer errors ("'faq_load' requires the Tauri desktop
client… Guard the call site…") on FAQ and in Settings → Keep awake, and its
Capture button could only fail. FAQ/CHANGELOG are bundled into the web app as
lazy chunks; Keep awake reports unsupported there; Capture is desktop-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:48:11 -07:00
phantomptrandClaude Opus 5.5 7872b0fc4f feat(convert): a queue - several games converted one after another, installs handed to the console queue
Add this game / Add games from a folder… queue builds on this computer, one at
a time, each shown by the Convert screen's own stage view. After converting:
keep the package, or Stream & install / Upload & install - the package is
handed to the console queue and the next build starts while it installs
(a console dump still swaps inside its build). Optional delete after a
verified install. Reorder, remove, stop after the current build; a build
interrupted by a restart is built again, and the engine now clears an
interrupted build's stale .pkg.partial instead of refusing the rebuild.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:28:22 -07:00
phantomptrandClaude Opus 5.5 9eab028449 feat(upload): several sources at once - review list, multi-select, drops, Add games from a folder
Two or more sources (multi-select pickers, a multi drop, or Add games from a
folder…, which lists a folder's children with games checked) switch Upload to
a review list: each row is inspected in the background (four at a time) and
shows its kind, size and where it lands; an encrypted .rar asks for its
password inline. Before adding: rows landing in the same place block, rows
already queued are skipped, and space per drive blocks only when it clearly
won't fit (warns when it can't tell). Shared destination, resume/overwrite and
only the options the list needs; Add N to queue / Upload N now. One source
still behaves exactly as before; a package dropped on Upload is uploaded and
installed (it no longer jumps to Install Package).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:13:20 -07:00
phantomptrandClaude Opus 5.5 4f28b1d52e feat(upload): shared queue-item builder; a server archive is copied when its turn comes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 07:01:57 -07:00
phantomptrandClaude Opus 5.5 cd57a668a7 feat(viewer): open it from anywhere - drops, Convert, the queue, File System, server browser
One app-wide viewer. A package, image or folder dropped on a screen without
its own drop zone opens it with Install… / Convert… (a drop no longer jumps
straight to Install Package); Convert views its game and its package; queue
rows view their package or source; File System and Connections → Browse get
View on packages, images and game folders (read on the console / server).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 06:54:38 -07:00
phantomptrandClaude Opus 5.5 21aee22efa feat(viewer): Files, Images and Related tabs; packages and games on a server or the PS5
The viewer reads remote:// and ps5:// sources through the engine's opener, and
.pkg parsing now works over any reader, so a staged package opens straight
from the console: every Install Package row gets View details, reading the
local original when there is one. New GET /api/game/inspect/files lists a
package's entries or a tree's files (a windowed list for 200k-file dumps);
Images shows and saves every artwork; Related groups the title's other
library and queued packages base → update → DLC, each viewable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 06:45:36 -07:00
phantomptrandClaude Opus 5.5 bd14603614 feat(convert): Convert & replace swaps a console dump for its package
A dump on the PS5 and its package share a title id, and ShadowMountPlus
re-registers a dump over an install, so a console source is never installed
beside its dump. The swap journals each step to /data/ps5upload/swap first,
parks the dump on its own volume (outside every scan root), waits for SMP to
let go, removes the leftover registration, installs through the queue, and
moves the dump back if anything fails. A running game stops it untouched.
The result offers Delete the old dump / Keep it parked (dropping its
manual.lst line); an interrupted swap is listed on Convert to put back or
finish.

Verified on the Phat (5.10) with a disposable fixture title: a failed install
rolled back (dump restored, SMP re-registered); a good one parked the dump and
left a real app.pkg install; Delete the old dump removed it and the journal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 01:36:17 -07:00
phantomptrandClaude Opus 5.5 3c558ba0ed feat(convert): read a game in place on a saved server or the PS5
A server folder or image is built straight off the server through the
engine's server file system (8 MiB read-ahead, retries) - no copy stage;
only a server archive is still copied, then unpacked. 'On the PS5' browses
the console and reads a dump through ftpsrv (:2121) as ps5://host/path;
installed games under /user/app are refused as encrypted. source::open
resolves remote:// and ps5:// through an opener the engine registers, so
build, estimate, inspect and the viewer all read them. Compression still
copies a server image first (it reads local disk).

Verified on the Phat (5.10): inspect + build of an image on the console
over ps5://, same package size as the local build; /user/app refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 01:08:22 -07:00
phantomptrandClaude Opus 5.5 ebcc541173 feat(convert): build from a .zip, .7z or .rar archive
An archive is unpacked into .ps5upload-extract-<job> in the output folder as
its own Convert stage (progress, Cancel), the game found inside - a folder
however wrapped, or a single .exfat/.ffpkg/.ffpfsc image - is built, and the
unpack is removed when the run ends. Space for the files plus the package is
checked first; unpack folders left by an earlier run are swept. RAR takes a
password (never stored); a wrong one on a content-encrypted RAR now says so
instead of 'File CRC error', for uploads too. zip/7z are built without their
encryption features, so a protected one is refused with that reason. A server
archive is copied, then unpacked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:53:45 -07:00
phantomptrandClaude Opus 5.5 67335e2c50 fix(settings): hide the Beta features switch while nothing is in beta; README drops Convert's beta note
Convert graduated; the switch revealed nothing and the README still told users
to enable Convert there. Stream install is Stream & install everywhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:30:48 -07:00
phantomptrandClaude Opus 5.5 808780f2e3 fix(viewer): cache sees folder PARAM and split-part edits; safer reads and labels
- Cache key covers a folder's PARAM files and a package's split parts, and a
  hit keeps its token alive.
- Content-id slicing can't panic; text read from an image or folder is capped;
  a failing OS random source is an error, never a guessable token.
- SFO counts and levels show in decimal (flags and versions stay hex).
- "Entries" for a package, "Parental level" for PS4; Copy uses the shared
  clipboard helper; a reply for an earlier path or console is ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:29:19 -07:00
phantomptrandClaude Opus 5.5 4784996be2 fix(queue): a failed Install Package upload or browser stream leaves no dead queue row
The library row already shows an upload failure; its queue row's Retry would
stage a copy nothing waits for. A browser-staged stream copy is deleted after
a failure, so its row (and the Retry via upload hint) could never work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:20:24 -07:00
phantomptrandClaude Opus 5.5 4598183dcc fix(pkg-library): install() returns its own result; stream callbacks can't leak or be overwritten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:18:19 -07:00
phantomptrandClaude Opus 5.5 5944090346 fix(queue): duplicate installs join the queued one; library rows show queue state
A second identical install now awaits the queued one instead of failing, and
Install Package rows show Queued/Installing and block Delete while their
install waits in the console queue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 00:16:13 -07:00
phantomptrandClaude Opus 5.5 628e8c4a13 feat(upload): a package's footer button reads Upload & install and yields to Stream & install
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:57:57 -07:00
phantomptrandClaude Opus 5.5 6a11e21259 feat(install): Stream & install first — renamed buttons, stream-first copy, drops stream
Stream install → Stream & install (primary, first); Add package → Upload &
install (secondary). Install Package's description and empty state lead
with streaming; dropping a package streams it; Upload's .pkg card offers
Stream & install as the recommended route; Convert uses the same label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:55:49 -07:00
phantomptrandClaude Opus 5.5 1ebbd62ffa fix(viewer): no PS4-vs-PS5 firmware verdict; honest installed check; space on the roomiest drive
- A PS4 package's minimum firmware is PS4 firmware: never compared with the
  PS5's (was a false red "can't run").
- Installed check comes from the preflight: unknown is no verdict (never
  "not installed"), installed-without-version reads as installed, DLC and
  updates are checked as themselves and say when the base game is missing,
  an unknown package version is not compared.
- Space is checked against the roomiest single drive, not the sum.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:49:01 -07:00
phantomptrandClaude Opus 5.5 dfbdca9a5b fix(viewer): keep CDATA update notes, hide empty ones, pad the panel; View details always on the package card; changelog
Hardware (web UI, Playwright): Star Wars patch (PS4), Star Wars base, Spider-Man 2 (PS5 fake package) and a PPSA30528 .exfat inspected — titles, ids, versions, firmware, SDK, covers and update notes correct; checks match the console (installed 01.02, FW 5.10 meets 3.55).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:40:18 -07:00
phantomptrandClaude Opus 5.5 d101fc287e feat(viewer): open the package panel from Install Package and Upload
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:28:01 -07:00
phantomptrandClaude Opus 5.5 c280409756 feat(viewer): PackagePanel — cover, badges, console checks, Overview and Details
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:23:59 -07:00
phantomptrandClaude Opus 5.5 29052d27cd feat(viewer): firmware, installed-version and space checks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:20:37 -07:00
phantomptrandClaude Opus 5.5 2ed82f8554 feat(inspect): /api/game/inspect with a token cache, its image route, Tauri commands and browser mapping
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 23:19:56 -07:00
phantomptrandClaude Opus 5.5 7228fa9d33 fix(queue): review fixes — an install is never run twice, the saved queue loads first, installs never auto-rerun
- Stop and Clear leave a running install running (Sony's install can't be
  stopped); a new drain waits for it instead of re-queueing and running it
  a second time, and its outcome is recorded even after Stop.
- The saved queue loads at app start; nothing is saved before it loads,
  and anything queued before the load is kept.
- Reconnect-resume never re-runs a failed install; Retry failed resets
  install rows cleanly.
- A failed install never stops the installs queued after it.
- Retry via upload installs after uploading and wins over a staged
  variant (the old dialog's options), and drops the row only once the
  upload is accepted.
- Rest mode after uploads ignores installs and an Install Package upload
  whose install is queued next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 22:10:45 -07:00
phantomptrandClaude Opus 5.5 c40b0951b4 fix(queue): show the queue at the top of Install Package; installs appear once in the activity bar
The Queue panel sat below the link box and two info cards, out of view.
The activity bar and task list also mirrored install items as "Upload"
rows next to the install's own task, so every queued install showed twice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 21:56:47 -07:00