Repository navigation
feat(files): file browser redesign on PC and phone, and RemEx 3.1.0 (versionCode 39) - #56
Conversation
…oth platforms Explorer-style three-pane PC screen and an adaptive two-sided Android screen, one new range-read message for live preview, and file_hash_request relayed to phones read-only. Records every decision from the planning Q&A and the six-phase delivery plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
PowerShell 7.6 appends its own platform newline to a string piped into a native command: CRLF on Windows (why the explicit trailing LF exists), but a bare LF on Linux, where the explicit one became an empty stdin record. git check-ignore rejects that as an empty pathspec and exits 128, so every Linux run threw "git check-ignore failed" before building anything. The explicit LF is now Windows-only; Windows behaviour is byte-for-byte unchanged. Reproduced in isolation (exit 128 with the trailing LF, exit 0 without) and confirmed by a full -Scope all run reaching the end on Linux. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
…n phase 1) Protocol and hosts for docs/specs/2026-10-08-file-browser-redesign.md. - New file_read_range_request/response: up to 1 MiB of one file from an offset or from the end (live tail), base64 on the control channel. Additive, capability-flagged (fileCapabilities.readRange / hash). - PC host: FileTransferService.ReadRangeAsync / ReadVolumeRangeAsync, resolved like a download source (same root, consent and restricted-path checks); opened ReadWrite|Delete so a live log can be tailed. - Phone host: answers range reads and file_hash_request through facade.resolve (the browse gate, per request), off the collector, under small permit pools; a provider-reported size of 0 is treated as unknown. - PhoneFileRelay forwards both read-only requests (product decision, recorded in REGRESSION-GUARDS), after ReadRefusal checks root, path and range; hashes get a 30-minute wait like copy/move. - FileTransferClient.ReadRangeRemoteAsync (the PC UI's receiver) and an optional hash timeout for phone-sized hashes. - HashFormat (C# + Kotlin twins, shared vectors): hex for display, hex or Base64 accepted when pasted, constant-time compare. Review: csharp-reviewer and kotlin-reviewer both PASS; all their MEDIUM and LOW findings are fixed here. New guards defect-injected and seen red: relay ReadRefusal, hash timeout, service bounds, HashFormat length, phone folder check, range bounds, capability flags, unknown-size handling, read cap. Gate (verify.ps1 -Scope all, Linux): Android unit tests and lintRelease pass; core, desktop and render suites pass. The receipt says FAIL because of 10 remex.agent.tests failures that fail identically on a clean checkout of the base commit in this container (headless capture x7, root-only revoker injection, two HostIdentityUnification tests with a Remex.Agent/remex.agent path-case bug), plus ConnectionBecomesRegistryVisibleTests failing once under load (passes 3/3 alone, passed in the previous full run). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
…gn phase 2) - A transfer that really compared SHA-256 hashes now finishes "Verified" and keeps the hash (hex for display); one whose host sent no hash stays "Done". Rows say "Verifying…" while the ends compare. Every path reports it: v3/v2 uploads, downloads (only when a hash was compared), and both PC-started phone transfers through PhoneFileRelay. Delivered through a small ITransferVerificationSink on the IProgress the queue already passes, so no work delegate changed. New string in all 9 locales. - remex.desktop/Services/FilePreview: preview classifier, text decoder (BOMs, binary sniff, no half characters at a read's edge), per-line syntax colouring (logs incl. .NET fail:/warn:, JSON, XML, code), a full-size image loader in 1 MiB reads refusing >40 MiB after one read, and a live TextTail that reads only what was added, restarts on rotation and bounds an endless line. Bound into the screen in phase 3. Defect-injected and seen red: download only-when-compared, IsVerified needs a hash, tail carry bound, image size limit, UTF-8 cut handling. Gate (verify.ps1 -Scope dotnet, Linux): core, desktop (3903) and render suites pass; the receipt says FAIL only for the same 10 remex.agent.tests failures that fail identically on the pre-change base in this container (headless capture x7, root-only revoker injection, HostIdentityUnification path case). Android untouched since phase 1's passing Android run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
…review and SHA-256 tools (redesign phase 3) Replaces the old source-picker screen with three panes: - Folders: This PC and each connected phone as a lazily loaded tree (shared folders, plus a phone's volumes), kept in step with browsing. - Contents: breadcrumbs, thumbnails in list and grid (ThumbnailCache), right-click menus, keyboard shortcuts, drag between devices. - Preview: follows the selection; full-quality zoomable images, coloured text/code/logs with a live tail, details, and an Integrity section to compute, copy, compare and verify-against a SHA-256 on another device. A bottom transfer strip counts active/verified/failed transfers. Phone-to-phone and folder drops are refused with their own reason (a test now pins the message; the old one passed on any status). Gate (verify.ps1 -Scope dotnet, Linux container): core 1642/1642, desktop 3924 passed/4 skipped, render 60/60. Agent: the same 10 environment-only failures as the base commit (headless capture, root permissions, path case), none in touched code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
…rified" on phone transfers (redesign phase 4) - Kotlin twins of the PC preview pipeline (classifier, decoder, tokenizer, image/text/tail loaders) under ui/files/preview, held to the C# rules by one shared vector file kept byte-identical in remex.desktop.tests/Fixtures and the Android test resources. - PcFileRequests: range-read and SHA-256 requests to the PC, matched by request id, routed from the file view model's message feed. - LocalDocuments: DocumentsContract listing (one query per folder), path walking through SharedPathPolicy, range reads and on-phone SHA-256. - PhoneBookmarksRepository: phone-only bookmarks in their own DataStore key; "Share with PC" writes the existing Access-from-PC list; grants are released only when no list (or whole-device browse) holds them. - QueuedTransfer.verified: set only when a hash was compared; queue rows say Verified with a copy-hash button, and the finish notification says "Transfer verified". 3 strings x 9 locales + 1. Every new guard was defect-injected (15 Kotlin + 1 C#); two blind tests were fixed before landing. Gate (verify.ps1 -Scope all, Linux): Android unit 1974/1974 and lintRelease pass; .NET as phase 3, with the same 10 environment-only agent failures as the base commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
…e preview and SHA-256 tools (redesign phase 5) - One folder tree for This phone and PC: permanent pane on expanded width, a drawer elsewhere; contents and preview through the list-detail scaffold, full-screen preview with back on phones. - This phone: shared folders plus phone-only bookmarks (Add folder); "Share with PC" puts one on the existing Access-from-PC list. - Tapping a file previews it: zoomable images (HEIC included), coloured text and logs with Live tail, and a SHA-256 card (compute, copy, compare, check against the other device). - Send to PC / Save to phone through a folder picker of the other device, on the existing transfer engine; multi-select on both sides. - Toolbar reduced to search, sort/view and one primary action + More. - Mixed versions (spec 2.4): an older PC gets an "update" note instead of requests it can't answer; fingerprint buttons follow `hash`. - Review fixes: switching PC folder clears the old listing first (a delete could otherwise hit a same-named file in the new folder); listings keep the tree current; preview work stops when it closes; phone rows are keyed by document id; grants stay held while a transfer uses them; release-lint string reads moved to composition. - Quick-access strip removed (the tree replaces it), with its 3 strings. - New guard: nothing under service/ may read phone-only bookmarks (REGRESSION-GUARDS.md); two stale engine anchors re-pointed. 58 strings x 9 locales. Every new guard defect-injected (red, then green). Gate (verify.ps1 -Scope all, Linux): Android unit 2004/2004, lintRelease passed; .NET with the same 10 environment-only agent failures as the base commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
…edesign delivered (redesign phase 6) - FILE_SHARING.md: a "Files screen" section in plain English: the tree, live preview, phone-only folders and the Share with PC switch (still one consent list), Verified vs Done, and the fingerprint tools. - Spec section 7: what landed per phase, and where it differs from the plan (medium-width Android is one pane at a time, files not folders across devices, no phone-side rename/delete, the older-PC fallback, same-named phone files), plus what still needs Connor's machines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
Version set with build-remex.ps1 -Version 3.1.0 -VersionCode 39, which writes version.properties and Directory.Build.props together (VersionSourceOfTruthTests). CHANGELOG: Unreleased becomes 3.1.0 — the redesigned file screens on PC and phone. Gate (verify.ps1 -Scope all, Linux): all suites green apart from the same 10 environment-only agent failures as the base commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
- What's New on both apps lists the seven 3.1 highlights in all nine languages (WhatsNewCount 9 -> 7; AboutScreen.kt follows). - PC version strings: app.manifest assemblyIdentity 1.13.0.0 -> 3.1.0.0, RemEx.iss fallback 2.2.0 -> 3.1.0. build-remex.ps1 now rewrites both on every version change (Sync-PinnedVersionStrings), and VersionSourceOfTruthTests fails if they drift. - build-remex.ps1 named RemEx.sln; the file is Remex.sln, so every PC build on Linux died at dotnet restore. Fixed, with BuildScriptPathCaseTests checking every repo path the script names, case included (defect-injected red). - Release docs: RELEASE-NOTES-3.1.0.md, PLAY-WHATS-NEW-3.1.0.md (9 locales, each under 500 characters), README "What's new in 3.1" and 3.1.0 downloads, install docs and version examples, CHANGELOG Fixed. Verified: Windows publish stamps Remex.Agent.exe 3.1.0.0 (file and manifest); Linux package builds as remex-agent-v3.1.0-linux-x64.tar.gz (70.1 MB); APK is 3.1.0 (39). Gate (verify.ps1 -Scope all, Linux): all green apart from the same 10 environment-only agent failures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
|
CI: both red checks are already red on
I'm not re-running either job: both fail deterministically on Generated by Claude Code |
Checklist
scripts/verify.ps1was run (-Scope all, Linux). Everything passes except 10remex.agent.testsfailures. The untouched base commit fails the same 10 in this container: headless capture, running as root, and aRemex.Agentvsremex.agentpath-case bug. So-Checkreports the receipt as FAIL for those 10 only.testReleaseUnitTest,lintRelease,assembleRelease)docs/REGRESSION-GUARDS.mdfirst. This PR touches none of those. It adds one guard (phone-only bookmarks never reach the PC), widens the phone-relay guard, and fixes two stale anchors..axamlchanged: looked at the result via theui-verifyskill. The skill needs a live Windows desktop, which this session doesn't have. The new File Transfer view was rendered headlessly instead, with PNG snapshots. The 13-cellui-palette-sweep.ps1still needs a run on Windows.What changed and why
The redesigned file screens on both platforms, as specified in
docs/specs/2026-10-08-file-browser-redesign.md(§7 says what was delivered and where it differs from the plan).Protocol. Two additions, neither of which changes
protocolVersion, and both gated behind capability flags so older peers are never asked:file_read_range_request/file_read_range_responsepair, answered by both the PC and the phone.file_hash_request.The PC's phone relay forwards both, with paths and ranges checked before they leave the PC. Hashes display as lowercase hex, and the C# and Kotlin versions share one set of test vectors.
PC plumbing. Transfers say Verified only when a hash was really compared. This phase also adds the preview pipeline: classifier, text decoder, tokenizer, and image, text-head and live-tail loaders.
PC screen. An Explorer-style layout: a tree (This PC plus phones), contents with thumbnails, right-click menus, keyboard shortcuts and drag between devices, a live preview, and a SHA-256 panel. A transfer strip runs along the bottom.
Phone plumbing. Kotlin twins of the preview code, held to the C# rules by one shared vector file. Range reads, hashing and browsing against the PC;
DocumentsContractlisting on the phone; phone-only bookmarks; and Verified on phone transfers.Phone screen.
Docs.
FILE_SHARING.md,CHANGELOG.md,REGRESSION-GUARDS.md,API_CONTRACTS.md§3.Release. 3.1.0, Android versionCode 39, set through
build-remex.ps1 -Version 3.1.0 -VersionCode 39.Testing
lintReleasepasses.🤖 Generated with Claude Code
https://claude.ai/code/session_01E9cDSGibUBVRtkDqkLMk7V
Generated by Claude Code