In the browser the banner only knew the upload queue and the one-shot
upload, so a Files download or upload, a Convert or image build, a RAR
extract or a link download running in this same tab showed up as an
orphan. Every follower polls through jobStatus, so a poll now claims the
job for the tab; Files downloads and the Convert pipeline are also claimed
from their stores.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The engine keeps downloading whether or not this tab can read the job, so
one dropped poll used to leave a running job with no banner and no Cancel.
Failed reads are now counted like the upload poller does: after
MAX_POLL_FAILURES the banner says contact is lost and polling continues at
the slower pace; only an engine that no longer knows the job ends it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The browser build has no app.db route, so every 5 s poll joined against
nothing and cleared every Playing badge and Close game button. Titles now
come from app.db when it answers, else from the process list, and nothing
is published when neither does. A reply for a console the user has since
switched away from is dropped instead of showing its rows with buttons that
act on the new console.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Upload: drop zone is a soft dashed glass well with an icon orb; queue rows
are glass rows with tinted edges for active/failed; a failed upload row says
what happened in plain words and has its own Retry.
- Files: drive and sort chips use the shared chip style (no solid accent
block); roomier glass file rows in the sans face; pill breadcrumb bar.
- Selectable cards (Convert compression, image format, link install method,
Move to / Send to destinations, Upload choices) share one glass card style
with an accent ring when chosen; compression levels use icons, not emoji.
- Disk usage treemap uses tints of the theme's palette instead of fixed blue.
- Volumes cards are glass with the shared progress bar; Connection steps no
longer wear a green frame when done.
- Raw inputs/selects use the shared .input/.select fields; hard tone frames
become tinted edges; buttons are pills.
- Error cards on Files, Volumes, Search, Disk usage, Servers, Local image and
Upload preflight get a plain-language message and Retry where it applies.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Pin v0.44 (sha256 4d06eab7...). Its crt/ and prospero-nid are identical
to v0.43, so the vendored sdk-crt (+ ps5upload.patch) and the portable
prospero-nid stay as they are; the helper, installer and elfldr build to
the same code (only the build-id differs). v0.44 adds LLVM 23 to the
candidate list, so the Makefile comment and Homebrew fallbacks move too.
scripts/update-ps5-sdk.sh (make update-sdk): finds the latest release
(or --tag), checks the zip, rewrites the pin, re-vendors prospero-nid
and crt only when upstream changed them (stops if our crt patch no
longer applies), moves the "SDK vX.Y" doc mentions and installs with
install-ps5-sdk.sh, keeping the old SDK as a backup. --check only
reports. The installer names its backups after the release they hold.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Game files' detail/move/mount dialogs stand on the float surface (they
were translucent surface-2 over the scrim), and the notes, inputs and
small buttons in Game files, ShadowMount+, the game page copy rows and
the Collection modals move to the rounded glass/pill language.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Bug report's chips, Hardware's fan presets, Settings' retention picker
use the shared chip; Send payload's path field is a standard input.
- Bordered rows built in template strings get the field radius.
- Phone: Tasks history rows are glass with only running/failed edges
coloured; missed reminders and screenshot rows wrap their actions under
the text; Bug report's action bar sits just above the tab bar.
- Hardware metric values no longer wrap mid-number.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- components/GameIconFrame: the reference's white cover frame (glass rim at
night), caption (title over a muted meta line) and tags that sit on art.
- Collection: framed cover grid, chip filters, glass stats; Ready to play:
framed cards, chips for the play-time sort/filter, pill search, a glass
kstuff line (soft token instead of an opacity modifier) and Now playing.
- Games: chip tabs through the shared Tabs, same ?tab= contract.
- Game page: glass hero with the framed cover, big title and fact chips;
coral-circle section headings; pill controls in the copy rows.
- Game files: glass rows with framed thumbnails, pill search; the running
apps panel humanises its error.
- Game Activity: shared Tabs, framed icons; Processes: glass rows.
- Home: a Recent games row from the Collection (newest first, chips per
console that was read, Not installed), hidden when the Collection is empty.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Hardware: every panel is a glass card with an icon disc header, metric
rows with the hint under the value, and more room between cards.
- Notifications: unread rows are raised glass with a coral dot instead of a
solid accent tint; the unread bar matches.
- Settings: text size and theme pickers are chips/glass pills; Backup
presets and Profile's Crop/Fit are chips; the roster's Save/Add are pills.
- Captures: the count sits beside the description.
- Changelog/FAQ: a wrapped bullet stays one list item (was split into a
stray paragraph).
- Sweep of my screens, components and layout: old rounded-md/lg bordered
boxes become glass panels or radius tokens, small buttons become pills,
single-line fields are glass pills; undefined colour tokens
(--color-error/-danger/-surface-1) and Tailwind palette colours replaced
with theme tokens.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Engine: /api/pkg/remote/download/start takes `existing: resume|replace` for a
different file already under the download's name (resume moves it to the
.partial, whose tail is checked against the link; replace deletes it), and
its 409 carries the file's path and sizes. A live download of the same name
is answered before anything is taken over.
- Client starts link downloads over the engine API (lib/linkDownload) so the
409s keep their fields: a duplicate attaches to the running download, and
Install Package asks Resume (when the file is shorter than the link) or
Replace instead of the old 'Move or delete it first'.
- Convert & install shows 'Will install on {console}' while it runs; 'Show in
folder' is hidden where no file manager can open it and says so when
opening fails.
- Install Package says a refresh is held for the running install.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Callout: tinted glass with normal-colour text and a tone-coloured icon
disc; ErrorCard/SuccessCard/WarningCard are now Callout wrappers, and
ErrorCard humanizes engine strings and takes onRetry.
- TabbedShell (Logs, Payloads) and the package viewer use chip tabs; Tasks'
Tasks/History/Stats switch is the shared Tabs instead of a solid accent bar.
- Focus: .input/.select keep their own focus style without the extra ring;
the command palette's search row lights up instead of a heavy outline.
- Overlays share a frosted .scrim; Cheats' repo browser and the capture
previews use the shared Modal; Bug report's action bar and the audit log
header are frosted glass.
- Tasks lists missed scheduled reminders with Run now / Dismiss.
- Retry on list errors across Hardware, Health, Cheats, Saves, Profile,
FW spoof, Backup, Remote Play; Logs' Open logs folder reports failures.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- One-shot upload: a failed status poll no longer fails a transfer the engine
is still sending. After several in a row it shows lost contact (phase stays
running, so nothing starts a competing upload) and keeps polling the same
job; Check again re-attaches now. A failed upload gets a Retry.
- Upload screen subscribes to the phase kind only; the live numbers re-render
just the status card. QueuePanel and RunningEngineJobs are memoized, and the
latter no longer re-renders on every progress tick.
- RunningEngineJobs Cancel waits for the engine and keeps the banner with the
error when the cancel failed.
- Queue Clear says what it did: a running upload was stopped; a running
install keeps going.
- Delete-source-after-upload failures raise a warning instead of vanishing.
- Convert & install installs on the console chosen at start (or stops with the
package kept when that console left the roster); giving up on polling stops
the engine job, or says it may still be running.
- Pkg library Refresh during an install is held and run when it ends.
- Sizes in Upload/Files/Install/Convert/Volumes/First run go through
formatBytes (IEC); the bandwidth cap is labelled MiB/s like the engine.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- lib/usePoll: one poll primitive that never overlaps itself and pauses
while the window is hidden or a transfer to that console runs; Hardware
(power/storage, PS5 clock, SMP meta), Notifications and the kernel log use it.
- Engine log bridge appends a whole tick in one store update; the log store
keeps an error counter so Sidebar/More stop re-filtering 500 lines.
- Schedules fire whatever came due since the last tick (15 min catch-up),
and record later ones as missed instead of silently skipping the day.
- Screenshots / Video clips: Delete for the selection (confirm, engine
delete like Files, thumbnail too), Retry on list errors, previews in the
shared Modal.
- formatDate: dates follow the app language.
- Kernel log renders only the rows on screen (fixed-height windowing).
- Logs: Open logs folder shows its error. Settings and Connection load lazily;
the vendor-react chunk matches exact package names.
- Modal reads onClose through a ref so an inline arrow doesn't re-grab focus
on every render.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Ready to play: the running-games poll skips while the window is hidden
(and catches up when shown), keeps the old map when nothing changed, looks
backport rows up in a map, and memoises the cards.
- Running-apps store: every writer is keyed by the bare host (the panel wrote
host:port, the rest bare host); readers go through runningOn/useRunningTitleIds.
- Game files: a row's param.json read is cached per console + path for two
minutes, so showing the screen again does not re-read every folder.
- Game page: the view is tagged with its title id; a late reply for a game the
page already left is dropped.
- Game page Updates/Add-ons: staged packages get an Install/Reinstall button
that queues through the package library, asking first when the base game is
not on the console.
- Collection: narrow store selectors (the scan counters live in their own
line), memoised cards, and covers versioned per game instead of per scan.
- Scan/read error cards on both Games tabs get Try again and a readable reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The dark photo tiles' status line measured 2.1-3.5:1 over the brightest
photos; the fade under the label now keeps it above 5.9:1. The dyslexia
font was set on body while #root set the app font itself, so it never
showed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Banners (engine down, pairing, helper version, Android) and the update bar
float as tinted glass instead of full-width strips. The command palette
gets pill rows with a soft accent highlight. Text on the warn/good game
badges and the selected bug-report capture uses the theme's contrast colour
instead of fixed black or white. On a phone the Recent activity heading
keeps its width and the chips wrap under it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Tailwind nests the colour-mix() of every colour-with-opacity utility
(bg-[var(--color-good)]/5 and the like) in an @supports block inside the
rule, and postcss-cascade-layers drops at-rules nested that way. Only the
full-strength fallback was left. While the colour tokens sat in @theme
Tailwind had resolved those at build time (to the dark theme's colours);
on plain custom properties they painted solid. A small PostCSS step now
hoists such at-rules out beside their rule first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The link-copy space check said 'GB' for 10^9 bytes while the collection export and
the health checks said 'GB' for 2^30. ps5upload_core::units::iec_bytes is now the
one formatter (KiB, MiB, GiB), used by all three.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- Artwork cache reads/writes run on the blocking pool; the cache size is tracked
instead of walking the folder on every write; concurrent writes of one entry use
unique temp names.
- Server-folder copies write on the blocking pool and fail on a failed sync.
- Debug/trace lines keep their own 500-line ring, so per-request and per-range
lines no longer push warnings out of the log tail; the pkg-host per-range line is
debug.
- Repeated-failure collapsing is keyed by route and console.
- Delete, move, unregister, process kill, power, user delete, backup restore/delete
and cheat delete answer 400 without an addr instead of acting on the default
console.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The main actions (Upload, Install, Games, Files, Saves, Convert) are framed
photo tiles: a thick white frame, a soft generated photo in the reference
palette (CSS only, distinct per tile), the label bottom-left and a white
round arrow. Beside them, a greeting panel with the orb and a time-of-day
hello carries the console status, metrics and live sensors that were in
the hero and the Console status card. Recent activity gets filter chips;
power, health, notifications and servers follow as glass cards. Nothing
that Home showed before is gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Desktop: the app is a large rounded glass canvas floating on the
atmosphere, the sidebar inside it: the orb and wordmark on top, the console
picker as a glass pill, small uppercase section captions, and pill nav
items (the active one a white pill with a coral icon). The content's top
bar holds Back/Forward and the console tabs as pills, and on the right a
search pill that opens the command palette plus white round buttons for
notifications and the theme. The status line sits quietly under the canvas.
Phones: the tab bar is a floating glass pill and More is restyled to match.
Every function, test id, aria label and shortcut is kept; notifications
moved from the sidebar footer to the top bar (the inbox gained an opening
direction and a round-button variant).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
New light and dark token sets: every surface is translucent glass over a
fixed atmospheric wash (peach, rose and lavender by day; aubergine and
indigo with ember and violet glows by night), with bright white edges,
large radii, warm shadows and one coral accent. Body text keeps >= 4.5:1
on the glass in both modes (numbers in index.css).
The colour tokens moved out of Tailwind's @theme onto :root: Tailwind
inlined @theme values into arbitrary color-mix() classes at build time,
which is what painted dark bands into the light theme.
High contrast makes the glass opaque and drops the blur; Reduced motion and
prefers-reduced-transparency drop the blur too.
Poppins 400-700 is bundled (@fontsource/poppins), with the system stack
behind it so scripts it lacks fall back per glyph.
Primitives follow: pill buttons (coral primary with a glow, white glass
secondary), glass cards and fields, chip-row tabs and segmented controls,
coral toggle, tinted-edge callouts, coral-to-pink progress, glass modals,
drawers, menus and toasts, rows-on-glass tables, a big bold page title, and
the Orb brand mark (also in empty states).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
OLED and Rose are gone. A stored or mirrored "oled" reads as dark and
"rose" as light (normalizeTheme), and the stored key is rewritten once so
it only ever holds one of the two. The theme toggle flips between them and
the Settings picker shows two options.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Each title cost about nine console calls (two listings per drive plus an
unfiltered appinfo query). The drives' user/patch and user/addcont folders are now
listed once per read and shared; a title's DLC folder is listed only when it has
one; appinfo asks for APP_VER and CONTENT_VERSION only. A listing or version query
that fails (not one that is absent) marks the detail unread, and the snapshot keeps
what the last read found instead of recording 'no update, no DLC'.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
A killed download left a short file under the real name, so every retry got 409
'Move or delete it first', and two downloads of one link wrote one file. Bytes now
land in <name>.partial and are renamed when complete; a retry resumes from the
partial after re-checking its tail against the origin (a mismatch starts over); a
file already complete is reported done; a second live download of the same file is
refused with the first one's id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
A panic in an install task left its console 'busy' until the engine restarted, and
a poisoned lock broke installs on every console. The task now holds a guard that
fails the job and frees the slot; every JobStore lock recovers from poisoning;
finish forgets the stop request and keeps the newest 200 finished statuses. The
per-console key uses the shared host normalisation, so IPv6 addresses no longer
collapse to a prefix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
Each job's blocking work now holds the drop guard transfers use (a panic marks the
job failed) plus guards that stop its ticker and free the build's partial file or
the unpack's folder and active-set entry. The tickers skip building events nobody
listens to.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The 500 ms poll, the 5 s job list and every 200 ms progress event carried the
whole planned file list (megabytes on a big folder), cloned under the jobs lock
each time. The snapshot now has files_count; the client reads the list once per
job. Events are not built when nobody subscribes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
clear-slot, users/list, remoteplay/devices, tmdb/fetch, bps inspect/apply, pkg install cancel,
appinfo/set, time/state get/set, pkg/parse and the fan-curve routes lost their last caller with
today's client clean-up; their handlers, types and the core code only they used go too, as does
the search-index module only tests used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
- DLC content class: a DLC's param.json names neither applicationCategoryType
nor applicationDrmType (all seven DLC packages read, four publishers), and
its container is 0x21 / 0x0a020000. content_class gave it the game pair.
- The flat layout refuses a u2c delta past a byte instead of clamping it at
255, which sent the console's read to the wrong record (the block layout
already refused). Two scale tests built such trees with the flat writer;
they now use larger files, or the block layout.
- A build's .partial is removed on every way out but success: an I/O error in
the in-memory writer, a failed rename, a panic. A separate Kraken spool is
removed the same way, and its name carries the process and a count, so two
builds of one content id into different folders no longer share (and
truncate) one spool.
- The in-memory writer has the flat layout only; a block-layout request (the
default) goes to the streaming writer instead of being written flat.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9
The engine's unified install now owns DPI bring-up and the unreachable-
stream diagnosis (REASON_GUIDANCE plus the engine's hint), so
lib/dpiUnavailable.ts, streamUnreachableMessage/originOf and the
engine-blind hint were no longer reachable. redactDiagnosticText is
replaced by lib/redaction.ts, effectiveMount is inlined where the
Library reads mounts, and the per-console queue reorders within its
group. Also drops test-only exports (loaderAddr, portOf, rarFolderName,
resolveCheatName, fetchJobSummaries, firmwareMajor, recentProblems,
fwToSdkHex/PS5_FIRMWARES, normalizeTitleId, onTaskStatusChange) and
store members only tests read. useStaleHostGuard now reuses
captureHostProbe instead of duplicating it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ub1mez9eaVtTF8pMEFXvA9