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:
rootandClaude Fable 5.1 committed 2026-09-28 02:09:39 +08:00
1 parent b839ed4056
commit 16ab2a6c84
97 files changed
+592 -648

No files matched your search

@@ -21,7 +21,7 @@ const SlotMeta = z.object({
name: z
.string()
.trim()
.min(1, "请填写目标名称")
.min(1, "填写名称")
.max(64, "最多 64 个字符")
.regex(/^[\w\-.+ ]+$/u, "只用字母、数字、空格和 - _ . +"),
distinctGroup: z.string().trim().max(64, "最多 64 个字符"),
@@ -30,7 +30,7 @@ const SlotMeta = z.object({
/** 409:别人(或状态机)已改过这个 Slot */
export function conflictToast(err: unknown, onRefresh: () => void) {
if (err instanceof ApiRequestError && (err.code === "conflict" || err.code === "precondition_failed")) {
toast.error("规则已被修改(版本不一致),已刷新,请在最新版本上重新编辑", { duration: 4000 });
toast.error("规则已被修改,已刷新。在最新版本上重新编辑。", { duration: 4000 });
onRefresh();
return;
}
@@ -51,10 +51,10 @@ export function SlotsPanel({
return (
<div className="space-y-3">
<div className="flex flex-wrap items-center justify-between gap-2">
<p className="text-meta text-muted-foreground">每个目标独立判定与升级;状态只由状态机推进,这里只改规则。</p>
<p className="text-meta text-muted-foreground">每个版本目标单独判定和升级。这里只改规则。</p>
<Button variant="outline" size="sm" onClick={() => setEditing("new")}>
<Plus />
新建目标
新建版本目标
</Button>
</div>
{q.isPending ? (
@@ -65,8 +65,8 @@ export function SlotsPanel({
<EmptyState
plain
icon={Target}
title="还没有收录目标"
description="没有目标时按已发布收录策略的缺省模板建;也可以在这里手动建。"
title="还没有版本目标"
description="没有时按已发布收录策略的默认模板创建,也可以手动新建。"
className="py-8"
/>
) : (
@@ -140,7 +140,7 @@ function SlotEditorSheet({
const errs: Record<string, string> = {};
if (!meta.success) for (const i of meta.error.issues) errs[String(i.path[0])] ??= i.message;
if (!rules.ok) Object.assign(errs, rules.errors);
if (requireDistinct && !distinctGroup.trim()) errs.distinctGroup = "需要不同物理资产时请填写分组名";
if (requireDistinct && !distinctGroup.trim()) errs.distinctGroup = "要求不同物理资产时须填写分组";
setErrors(errs);
if (Object.keys(errs).length || !meta.success || !rules.ok) return;
const common = {
@@ -153,7 +153,7 @@ function SlotEditorSheet({
{ id: slot.id, expectedRevision: slot.revision, ...common },
{
onSuccess: (s) => {
toast.success(`已保存目标 ${s.name}(r${s.revision})`);
toast.success(`已保存 ${s.name}(r${s.revision})`);
onClose();
},
onError: (e) => conflictToast(e, onConflict),
@@ -164,7 +164,7 @@ function SlotEditorSheet({
{ mediaEntityId, subscriptionId, name: meta.data.name, ...common },
{
onSuccess: (s) => {
toast.success(`已新建目标 ${s.name}`);
toast.success(`已新建 ${s.name}`);
onClose();
},
onError: (e) => toast.error(errorMessage(e)),
@@ -178,11 +178,9 @@ function SlotEditorSheet({
open
onOpenChange={(o) => !o && !pending && onClose()}
width="lg"
title={slot ? `编辑目标 ${slot.name}` : "新建收录目标"}
title={slot ? `编辑版本目标 ${slot.name}` : "新建版本目标"}
description={
slot
? `当前版本 r${slot.revision};保存时校验版本,期间被修改会提示刷新。`
: "硬条件决定能不能收,软偏好决定先收哪个。"
slot ? `当前 r${slot.revision}。保存时若已被修改,会提示刷新。` : "不满足硬条件的资源不收;软偏好决定先收哪个。"
}
footer={
<>
@@ -228,7 +226,7 @@ function SlotEditorSheet({
<div className="flex items-center justify-between gap-3 rounded-lg border border-border px-3 py-2">
<div className="min-w-0">
<p className="text-caption font-medium text-foreground">要求不同物理资产</p>
<p className="text-meta text-muted-foreground">真正的双版本:一个文件不能同时算两个目标</p>
<p className="text-meta text-muted-foreground">同一个文件不能同时满足两个目标</p>
</div>
<Switch checked={requireDistinct} onCheckedChange={setRequireDistinct} aria-label="要求不同物理资产" />
</div>