PLAN.md: Move… is a folder picker; moves across filesystems copy then remove

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-10-11 16:29:27 -07:00
co-authored by Claude Fable 5.1
parent fb3b8e4b4c
commit b6d72cce9f
+24
View File
@@ -683,6 +683,30 @@ something long in one, switch away and back, refresh — it's all still there.
- *Not done, on purpose:* no cap on the cache and no clear button (not asked; it only - *Not done, on purpose:* no cap on the cache and no clear button (not asked; it only
holds what was looked at); no tonemapping for HDR sources (a 10-bit HEVC frame comes out holds what was looked at); no tonemapping for HDR sources (a 10-bit HEVC frame comes out
flat); no preview in the viewer for a video (it still says "binary, download it"). flat); no preview in the viewer for a video (it still says "binary, download it").
- **Move… is a folder picker** — **shipped 2026-10-11** (v0.1.0-204, `MovePicker` in
`Files.tsx`, `internal/files/move.go`, `POST /api/files/move`). Asked for as: instead of
a path prompt, "an interactive file explorer, where I can go back/forward, etc and then
click some button, and it will move the file/folder to where I was". The picker opens in
the item's own folder and walks the machine the way the tab does — back and forward
through where it has been, up, breadcrumbs, a path box, folders only, `.hidden`
following the tab's toggle, **+ folder** to make the destination on the spot — and
**Move here** puts the item in the folder being looked at. It says why it can't when it
can't, with the button greyed: already here, a folder into itself, a name clash in that
folder (read from the listing before anything is tried). The row being moved shows in
its own folder, greyed. Rename stays a name prompt: it is a different question.
- **Across filesystems it copies, then removes.** `os.Rename` is EXDEV between
filesystems, and on `grid` every dataset is one — `/tank/media` to `/tank/files` was a
"invalid cross-device link" error before this, and the picker would have made that
move easy to attempt. `/api/files/move` renames when it can (204) and otherwise runs
`hamlab fs move` as a task (202 with the task; the tab shows its output and reloads
when it ends). The copy is built under a hidden name beside its destination
(`.<name>.hamlab-moving`), renamed into place once complete, and only then is the
original removed — a failure part-way removes the partial copy and leaves the original
as it was, and a cancel (SIGTERM to the helper) does the same. Modes, mtimes and
symlinks are kept; owners too when the backend is root. Devices, pipes and sockets are
refused outright rather than half-copied. Progress every 500 files or 512 MiB.
Verified on `grid` ext4 → ZFS with a tree holding a 0600 file, a symlink and an old
mtime, all intact on the other side.
- **Docker read-only view** — `docker ps`/logs; dockhand stays the source of truth. - **Docker read-only view** — `docker ps`/logs; dockhand stays the source of truth.
- **Notifications** — push on service failure / SMART warning / UPS event. - **Notifications** — push on service failure / SMART warning / UPS event.
- **Terminal extras** — search, copy-mode, font/theme, split panes, upload via - **Terminal extras** — search, copy-mode, font/theme, split panes, upload via