fix(storage): 本地写入口拒绝 Alist 虚拟路径,补字幕在 Alist 库根上明确失败

虚拟前缀 /@alist/… 读到本地是 ENOENT,但 mkdir -p、复制 / 移动目标、写文件、回收站落点会在本机真建出
/@alist 并写入文件。统一守卫:任何本地写类操作参数是虚拟路径即抛 REMOTE_PATH_ON_LOCAL_FS
(remote_path_on_local_fs),不落盘。

- adapters:fs/remote-guard.ts,接在 runFsOp、FsProxy.run(父进程拒绝不起子进程)、copyWithVerify、
  crossDeviceMove、moveSafe、commitNoClobber、sweepStalePartials、writeRootSentinel
- server:storage/local-fs.ts 带守卫的写函数,整理 / 替换 / 刮削 / 回收站 / 上传 / 字幕 / vfs 本地分支改用它
- 补字幕目标在 Alist 媒体库上返回失败原因,撤销同样拒绝

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-07 00:35:41 +08:00
1 parent a54905e571
commit 521c86d730
23 files changed
+371 -13

No files matched your search

+4
View File
@@ -23,8 +23,10 @@ import {
runFsOp,
type WireCopyOptions,
type WireCrossMoveOptions,
writePathsOf,
} from "./fsops.ts";
import type { CrossMoveResult, MoveResult } from "./move.ts";
import { assertLocalPaths } from "./remote-guard.ts";
import type { RootHealth, StatResult } from "./stat.ts";
export type { FsProgress } from "./fsops.ts";
@@ -243,6 +245,8 @@ export class FsProxy {
async run(req: FsOpRequest, call: FsCallOptions = {}): Promise<unknown> {
call.signal?.throwIfAborted();
// 远端虚拟路径在父进程就拒绝,不起执行子进程
assertLocalPaths(req.op, ...writePathsOf(req));
if (this.#mode === "subprocess") {
try {
return await this.#runSubprocess(req, call);