docs(plan): v0.2 adds Pi subagents and scheduled-jobs board
Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
1 parent
b839ed4056
commit
16ab2a6c84
97 files changed
+592
-648
No files matched your search
@@ -155,13 +155,13 @@ const BLOCK_ERR: Record<
|
||||
NonNullable<FileDeleteCheck["blocked"]>,
|
||||
[ConstructorParameters<typeof FilesError>[0], string]
|
||||
> = {
|
||||
download_active: ["download_active", "属于纳管下载任务(未完成或做种义务未满足)"],
|
||||
is_root: ["bad_request", "不能删除根本身或只读登记根下的内容"],
|
||||
download_active: ["download_active", "属于未完成或做种义务未满足的下载任务"],
|
||||
is_root: ["bad_request", "不能删除根目录或只读根下的内容"],
|
||||
needs_retire: ["needs_retire", "含已登记资产,需勾选“同时退役资产”"],
|
||||
needs_unbind: ["needs_unbind", "是作品/季的绑定目录,需勾选“解除绑定”"],
|
||||
root_unavailable: ["root_unavailable", "根不可用,不当作已删除"],
|
||||
root_unavailable: ["root_unavailable", "根不可用"],
|
||||
not_found: ["not_found", "不存在"],
|
||||
escape: ["path_escape", "路径逃出根"],
|
||||
escape: ["path_escape", "路径指向根外"],
|
||||
};
|
||||
|
||||
export async function deleteFiles(
|
||||
@@ -171,7 +171,7 @@ export async function deleteFiles(
|
||||
): Promise<FilesDeleteResult> {
|
||||
if (body.mode === "permanent") {
|
||||
if (!d.options.allowPermanentDelete)
|
||||
throw new FilesError("permanent_disabled", "永久删除未开启(FILES_ALLOW_PERMANENT_DELETE),请使用回收站");
|
||||
throw new FilesError("permanent_disabled", "未开启永久删除(FILES_ALLOW_PERMANENT_DELETE)。改用回收站");
|
||||
if (!isAdminSession(principal)) throw new FilesError("forbidden", "永久删除只允许控制台管理员会话");
|
||||
}
|
||||
const downloads = await managedDownloads(d);
|
||||
@@ -276,8 +276,8 @@ export async function deleteFiles(
|
||||
for (const s of slots)
|
||||
await upsertDecision(d.ao, trx, {
|
||||
kind: "other",
|
||||
title: `Slot 满足资产已被删除:${s.name}`,
|
||||
summary: "文件管理删除了满足该 Slot 的资产(进回收站或永久删除),Slot 退回 attention,请确认是否重新获取",
|
||||
title: `版本目标的文件已删除:${s.name}`,
|
||||
summary: "满足该版本目标的资产已在文件管理中删除,版本目标改为需关注。确认是否重新获取",
|
||||
subjectType: "acquisition_slot",
|
||||
subjectId: s.id,
|
||||
dedupeKey: `files_delete_slot:${s.id}`,
|
||||
@@ -396,7 +396,7 @@ async function moveToTrash(
|
||||
if (check.size > d.options.trashCrossMaxBytes)
|
||||
throw new FilesError(
|
||||
"bad_request",
|
||||
`无法同卷移入回收站,且大小 ${check.size} 超过跨卷上限 ${d.options.trashCrossMaxBytes};请使用永久删除`,
|
||||
`无法同卷移入回收站,且大小 ${check.size} 超过跨卷上限 ${d.options.trashCrossMaxBytes}。改用永久删除`,
|
||||
);
|
||||
await rm(join(ctx.rootReal!, TRASH_DIR, stamp, id), { recursive: true, force: true }).catch(() => undefined);
|
||||
trashPath = join(resolve(d.options.dataDir), "trash", stamp, id, check.path);
|
||||
@@ -487,10 +487,10 @@ export async function mkdirWithin(rootReal: string, rel: string): Promise<void>
|
||||
throw e;
|
||||
});
|
||||
if (st?.isSymbolicLink())
|
||||
throw new FilesError("path_escape", `还原路径中的 ${relOfRoot(rootReal, cur)} 是符号链接,拒绝`);
|
||||
throw new FilesError("path_escape", `还原路径中的 ${relOfRoot(rootReal, cur)} 是符号链接,不能还原`);
|
||||
if (st && !st.isDirectory()) throw new FilesError("exists", `还原路径中的 ${relOfRoot(rootReal, cur)} 不是目录`);
|
||||
if (!st) await mkdir(cur);
|
||||
if (!within(await realpath(cur), rootReal)) throw new FilesError("path_escape", `还原路径逃出根: ${rel}`);
|
||||
if (!within(await realpath(cur), rootReal)) throw new FilesError("path_escape", `还原路径指向根外: ${rel}`);
|
||||
}
|
||||
}
|
||||
const relOfRoot = (root: string, p: string) => (p === root ? "" : p.slice(root.length + 1));
|
||||
@@ -509,7 +509,7 @@ export async function restoreTrash(
|
||||
throw new FilesError("bad_request", "还原目标必须是已存在的目录");
|
||||
// "还原到…"只能进可写的 managed 库根(与 move/copy 的目标规则一致;register_only / 下载根拒绝,验收 07 S-5)
|
||||
if (target && !(await isWritableTarget(target.def, target.rootReal)))
|
||||
throw new FilesError("not_writable", `还原目标根 ${target.def.name} 不可写(仅 managed 库根可作为目标)`);
|
||||
throw new FilesError("not_writable", `还原目标根 ${target.def.name} 不可写,只能选 managed 库根`);
|
||||
for (const id of body.ids) {
|
||||
try {
|
||||
const row = await d.ctx.db.selectFrom("trash_item").selectAll().where("id", "=", id).executeTakeFirst();
|
||||
@@ -547,7 +547,7 @@ export async function restoreTrash(
|
||||
if (bytes > d.options.trashCrossMaxBytes)
|
||||
throw new FilesError(
|
||||
"too_large",
|
||||
`跨卷还原大小 ${bytes} 超过上限 ${d.options.trashCrossMaxBytes};请在同卷还原,或手工处理 ${row.trash_path}`,
|
||||
`跨卷还原大小 ${bytes} 超过上限 ${d.options.trashCrossMaxBytes}。在同卷还原,或手工处理 ${row.trash_path}`,
|
||||
);
|
||||
await copyTree(d, row.trash_path, dst, files);
|
||||
await rm(row.trash_path, { recursive: true });
|
||||
|
||||
Reference in new issue
Block a user