style(copy): fix remaining punctuation violations and make check:copy strict
Auto-fix of 602 string literals across 74 files (half-width punctuation next to Chinese, parenthesised Chinese, quotes); biome reflow; e2/e6 assertions follow the new full-width summaries. check:copy now runs with --strict in ci. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
0fccfe257d
commit
fb84a71f80
76 files changed
+582
-570
No files matched your search
@@ -97,8 +97,8 @@ function PasskeyRow({ item }: { item: PasskeyInfo }) {
|
||||
<Trash2 />
|
||||
</Button>
|
||||
}
|
||||
title={`删除 Passkey「${item.name}」?`}
|
||||
description="删除后这把钥匙不能再登录控制台;设备上的钥匙要在系统设置里另外删。"
|
||||
title={`删除 Passkey「${item.name}」?`}
|
||||
description="删除后这把钥匙不能再登录控制台;设备上的钥匙要在系统设置里另外删。"
|
||||
confirmLabel="删除"
|
||||
destructive
|
||||
onConfirm={async () => {
|
||||
@@ -139,7 +139,7 @@ export function PasskeyBlock({ disabled }: { disabled: boolean }) {
|
||||
};
|
||||
|
||||
let body: React.ReactNode;
|
||||
if (disabled) body = <p className="text-caption text-muted-foreground">当前用 API Key 访问,登录会话才能修改。</p>;
|
||||
if (disabled) body = <p className="text-caption text-muted-foreground">当前用 API Key 访问,登录会话才能修改。</p>;
|
||||
else
|
||||
body = (
|
||||
<div className="grid gap-3">
|
||||
@@ -155,7 +155,7 @@ export function PasskeyBlock({ disabled }: { disabled: boolean }) {
|
||||
<p className="text-caption text-muted-foreground">还没有登记 Passkey。</p>
|
||||
)}
|
||||
{!supported ? (
|
||||
<p className="text-meta text-muted-foreground">这个浏览器用不了 Passkey:需要 HTTPS 或 localhost 访问。</p>
|
||||
<p className="text-meta text-muted-foreground">这个浏览器用不了 Passkey:需要 HTTPS 或 localhost 访问。</p>
|
||||
) : adding ? (
|
||||
<form onSubmit={add} className="flex max-w-md flex-wrap items-center gap-2">
|
||||
<Input
|
||||
@@ -197,7 +197,7 @@ export function PasskeyBlock({ disabled }: { disabled: boolean }) {
|
||||
section="account"
|
||||
anchor="passkeys"
|
||||
title="Passkey"
|
||||
description="用指纹、面容或安全钥匙直接登录,不用输密码和验证码。可以登记多把。"
|
||||
description="用指纹、面容或安全钥匙直接登录,不用输密码和验证码。可以登记多把。"
|
||||
>
|
||||
{body}
|
||||
</SettingsBlock>
|
||||
|
||||
@@ -45,13 +45,13 @@ function QrCode({ value }: { value: string }) {
|
||||
|
||||
/** 恢复码展示:只此一次;可复制、下载 */
|
||||
function RecoveryCodes({ codes, onDone }: { codes: string[]; onDone: () => void }) {
|
||||
const text = `UHD Media Tool 恢复码(每个只能用一次)\n\n${codes.join("\n")}\n`;
|
||||
const text = `UHD Media Tool 恢复码(每个只能用一次)\n\n${codes.join("\n")}\n`;
|
||||
const copy = async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(codes.join("\n"));
|
||||
toast.success("恢复码已复制");
|
||||
} catch {
|
||||
toast.error("复制失败,手动选中复制");
|
||||
toast.error("复制失败,手动选中复制");
|
||||
}
|
||||
};
|
||||
const download = () => {
|
||||
@@ -65,8 +65,8 @@ function RecoveryCodes({ codes, onDone }: { codes: string[]; onDone: () => void
|
||||
return (
|
||||
<div className="grid max-w-md gap-3">
|
||||
<p className="text-caption">
|
||||
验证器丢了就用恢复码登录,每个只能用一次。
|
||||
<span className="text-muted-foreground">它们只显示这一次,存到密码管理器里。</span>
|
||||
验证器丢了就用恢复码登录,每个只能用一次。
|
||||
<span className="text-muted-foreground">它们只显示这一次,存到密码管理器里。</span>
|
||||
</p>
|
||||
<ol className="grid grid-cols-2 gap-x-6 gap-y-1 rounded-lg bg-muted px-4 py-3 font-mono text-sm select-all">
|
||||
{codes.map((c) => (
|
||||
@@ -173,7 +173,7 @@ export function TotpBlock({ disabled }: { disabled: boolean }) {
|
||||
const grouped = setup.data?.secret.replace(/(.{4})/g, "$1 ").trim();
|
||||
|
||||
let body: React.ReactNode;
|
||||
if (disabled) body = <p className="text-caption text-muted-foreground">当前用 API Key 访问,登录会话才能修改。</p>;
|
||||
if (disabled) body = <p className="text-caption text-muted-foreground">当前用 API Key 访问,登录会话才能修改。</p>;
|
||||
else if (mode === "codes") body = <RecoveryCodes codes={codes} onDone={() => reset()} />;
|
||||
else if (mode === "setup")
|
||||
body = setup.isPending ? (
|
||||
@@ -190,9 +190,11 @@ export function TotpBlock({ disabled }: { disabled: boolean }) {
|
||||
<form onSubmit={enable} noValidate className="grid gap-4 sm:grid-cols-[auto_minmax(0,1fr)] sm:items-start">
|
||||
<QrCode value={setup.data.otpauthUri} />
|
||||
<div className="grid max-w-md gap-2">
|
||||
<p className="text-caption">用验证器(1Password、Google Authenticator 等)扫码,再输入它显示的 6 位验证码。</p>
|
||||
<p className="text-caption">
|
||||
用验证器(1Password、Google Authenticator 等)扫码,再输入它显示的 6 位验证码。
|
||||
</p>
|
||||
<details className="text-meta text-muted-foreground">
|
||||
<summary className="cursor-pointer select-none">扫不了码?手动输入密钥</summary>
|
||||
<summary className="cursor-pointer select-none">扫不了码?手动输入密钥</summary>
|
||||
<code className="mt-1.5 block rounded-lg bg-muted px-2 py-1.5 font-mono text-sm break-all text-foreground select-all">
|
||||
{grouped}
|
||||
</code>
|
||||
@@ -261,7 +263,7 @@ export function TotpBlock({ disabled }: { disabled: boolean }) {
|
||||
body = (
|
||||
<div className="grid justify-items-start gap-3">
|
||||
<p className={left <= 2 ? "text-caption text-warning" : "text-caption text-muted-foreground"}>
|
||||
还剩 {left} 个恢复码(共 {RECOVERY_CODE_COUNT} 个)。{left <= 2 ? "快用完了,重新生成一组。" : ""}
|
||||
还剩 {left} 个恢复码(共 {RECOVERY_CODE_COUNT} 个)。{left <= 2 ? "快用完了,重新生成一组。" : ""}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<Button size="sm" variant="outline" onClick={() => reset("regenerate")}>
|
||||
@@ -290,7 +292,7 @@ export function TotpBlock({ disabled }: { disabled: boolean }) {
|
||||
description={
|
||||
enabled
|
||||
? "登录时除了密码还要输入验证器里的 6 位验证码。关闭需要当前密码。"
|
||||
: "开启后登录还要输入验证器里的 6 位验证码,同时生成 8 个一次性恢复码。"
|
||||
: "开启后登录还要输入验证器里的 6 位验证码,同时生成 8 个一次性恢复码。"
|
||||
}
|
||||
actions={
|
||||
disabled || status.isPending ? null : (
|
||||
|
||||
@@ -39,7 +39,7 @@ function PasswordBlock({ disabled }: { disabled: boolean }) {
|
||||
setErrors({});
|
||||
try {
|
||||
const r = await change.mutateAsync({ currentPassword: form.currentPassword, newPassword: form.newPassword });
|
||||
toast.success(r.revokedSessions ? `密码已修改,注销了其它 ${r.revokedSessions} 个会话` : "密码已修改");
|
||||
toast.success(r.revokedSessions ? `密码已修改,注销了其它 ${r.revokedSessions} 个会话` : "密码已修改");
|
||||
setForm(EMPTY_PWD);
|
||||
} catch (err) {
|
||||
const msg = errorMessage(err);
|
||||
@@ -56,7 +56,7 @@ function PasswordBlock({ disabled }: { disabled: boolean }) {
|
||||
section="account"
|
||||
anchor="password"
|
||||
title="修改密码"
|
||||
description="修改后其它设备上的会话全部注销,当前会话保留。"
|
||||
description="修改后其它设备上的会话全部注销,当前会话保留。"
|
||||
dirty={dirty}
|
||||
>
|
||||
<form onSubmit={submit} noValidate className="grid gap-x-4 gap-y-1 sm:grid-cols-3">
|
||||
@@ -135,7 +135,7 @@ function SessionBlock() {
|
||||
<div className="mt-4 border-t border-border/60 pt-4">
|
||||
<p className="text-caption font-medium">本机 Token</p>
|
||||
<p className="mb-2 text-meta text-muted-foreground">
|
||||
只存在这个浏览器,有值时请求会带上它。{hasToken ? "已设置。" : "未设置。"}
|
||||
只存在这个浏览器,有值时请求会带上它。{hasToken ? "已设置。" : "未设置。"}
|
||||
</p>
|
||||
<div className="flex max-w-md flex-wrap items-center gap-2">
|
||||
<Input
|
||||
|
||||
@@ -17,7 +17,7 @@ const RUNTIME_CARD: CardSpec = {
|
||||
name: "pi.contextBudget",
|
||||
label: "上下文预算(token)",
|
||||
kind: "number",
|
||||
hint: "4096–2000000,超过模型窗口时按窗口算",
|
||||
hint: "4096–2000000,超过模型窗口时按窗口算",
|
||||
},
|
||||
{ name: "pi.subagentsEnabled", label: "允许子会话", kind: "switch" },
|
||||
{ name: "pi.compaction.enabled", label: "上下文压缩", kind: "switch" },
|
||||
@@ -25,7 +25,7 @@ const RUNTIME_CARD: CardSpec = {
|
||||
name: "pi.compaction.thresholdRatio",
|
||||
label: "压缩触发比例",
|
||||
kind: "number",
|
||||
hint: "0.3–0.95,用到预算的这个比例时压缩",
|
||||
hint: "0.3–0.95,用到预算的这个比例时压缩",
|
||||
visible: (v) => v["pi.compaction.enabled"] === true,
|
||||
},
|
||||
],
|
||||
@@ -50,12 +50,12 @@ const RUNTIME_CARD: CardSpec = {
|
||||
const BUDGET_CARD: CardSpec = {
|
||||
anchor: "budget",
|
||||
title: "预算",
|
||||
description: "超出每日预算的运行停在「超出预算」,等你放行。",
|
||||
description: "超出每日预算的运行停在「超出预算」,等你放行。",
|
||||
fields: [
|
||||
{ name: "budget.agentMaxRunsPerDay", label: "每日运行次数", kind: "number" },
|
||||
{ name: "budget.agentMaxCostUsdPerDay", label: "每日费用(USD)", kind: "number" },
|
||||
{ name: "agent.maxToolCalls", label: "单次工具调用上限", kind: "number", hint: "1–500" },
|
||||
{ name: "agent.maxDurationSec", label: "单次时长上限(秒)", kind: "number" },
|
||||
{ name: "agent.maxDurationSec", label: "单次时长上限(秒)", kind: "number" },
|
||||
{ name: "agent.maxTokensPerRun", label: "单次 token 上限", kind: "number", hint: "留空不限" },
|
||||
{ name: "agent.maxCostUsdPerRun", label: "单次费用上限(USD)", kind: "number", hint: "留空不限" },
|
||||
],
|
||||
@@ -84,7 +84,7 @@ const BUDGET_CARD: CardSpec = {
|
||||
const INVESTIGATE_CARD: CardSpec = {
|
||||
anchor: "investigate",
|
||||
title: "自动调查",
|
||||
description: "待处理事项(识别有歧义、下载失败等)创建时,自动发起一次有界调查。",
|
||||
description: "待处理事项(识别有歧义、下载失败等)创建时,自动发起一次有界调查。",
|
||||
fields: [
|
||||
{ name: "agent.autoInvestigate", label: "自动调查", kind: "switch", wide: true },
|
||||
{
|
||||
@@ -92,10 +92,10 @@ const INVESTIGATE_CARD: CardSpec = {
|
||||
label: "模式",
|
||||
kind: "select",
|
||||
options: [
|
||||
{ value: "investigate", label: "只读调查,结论交还给你" },
|
||||
{ value: "recover", label: "授权内恢复(重试任务、重新校验、确认识别)" },
|
||||
{ value: "investigate", label: "只读调查,结论交还给你" },
|
||||
{ value: "recover", label: "授权内恢复(重试任务、重新校验、确认识别)" },
|
||||
],
|
||||
hint: "恢复只在已发布策略或持续授权覆盖时执行,换源、删除、清理始终排除;没有授权时按只读调查",
|
||||
hint: "恢复只在已发布策略或持续授权覆盖时执行,换源、删除、清理始终排除;没有授权时按只读调查",
|
||||
wide: true,
|
||||
visible: (v) => v["agent.autoInvestigate"] === true,
|
||||
},
|
||||
@@ -110,12 +110,12 @@ const INVESTIGATE_CARD: CardSpec = {
|
||||
name: "agent.investigateMaxAttempts",
|
||||
label: "同一根因最多恢复次数",
|
||||
kind: "number",
|
||||
hint: "1–10,用完后只交还给你",
|
||||
hint: "1–10,用完后只交还给你",
|
||||
visible: (v) => v["agent.autoInvestigate"] === true && v["agent.autoInvestigateMode"] === "recover",
|
||||
},
|
||||
{
|
||||
name: "agent.recoverVerifySec",
|
||||
label: "恢复后核实时长(秒)",
|
||||
label: "恢复后核实时长(秒)",
|
||||
kind: "number",
|
||||
hint: "等下载或任务状态变化的最长时间",
|
||||
visible: (v) => v["agent.autoInvestigate"] === true && v["agent.autoInvestigateMode"] === "recover",
|
||||
@@ -143,16 +143,16 @@ const ADVANCED_CARD: CardSpec = {
|
||||
anchor: "advanced",
|
||||
title: "高级",
|
||||
fields: [
|
||||
{ name: "agent.goalPollSec", label: "目标轮询间隔(秒)", kind: "number", hint: "等下载、入库结束时的检查间隔" },
|
||||
{ name: "agent.goalPollSec", label: "目标轮询间隔(秒)", kind: "number", hint: "等下载、入库结束时的检查间隔" },
|
||||
{
|
||||
name: "agent.goalWaitHours",
|
||||
label: "目标最长等待(小时)",
|
||||
label: "目标最长等待(小时)",
|
||||
kind: "number",
|
||||
hint: "超时后按「仍在等待」汇报结束",
|
||||
},
|
||||
{
|
||||
name: "agent.optionsTimeoutSec",
|
||||
label: "方案选择等待(秒)",
|
||||
label: "方案选择等待(秒)",
|
||||
kind: "number",
|
||||
hint: "Agent 给出方案后等你选择的最长时间",
|
||||
},
|
||||
@@ -167,7 +167,7 @@ const ADVANCED_CARD: CardSpec = {
|
||||
},
|
||||
{
|
||||
name: "agent.approvalTimeoutSec",
|
||||
label: "会话内审批有效期(秒)",
|
||||
label: "会话内审批有效期(秒)",
|
||||
kind: "number",
|
||||
hint: "步骤处的审批卡过期未批准,按拒绝处理",
|
||||
},
|
||||
@@ -177,13 +177,13 @@ const ADVANCED_CARD: CardSpec = {
|
||||
kind: "text",
|
||||
wide: true,
|
||||
placeholder: "留空用 DATA_DIR/agent-sessions",
|
||||
hint: "绝对路径,api 与 worker 都要可读写;有运行中的会话时不要改",
|
||||
hint: "绝对路径,api 与 worker 都要可读写;有运行中的会话时不要改",
|
||||
},
|
||||
{
|
||||
name: "agent.fakeScript",
|
||||
label: "fake 脚本(JSON)",
|
||||
kind: "textarea",
|
||||
hint: "只对 fake 上游生效,留空用内置演示脚本;格式见 docs/runbook/agent.md",
|
||||
hint: "只对 fake 上游生效,留空用内置演示脚本;格式见 docs/runbook/agent.md",
|
||||
},
|
||||
],
|
||||
fromSettings: (s) => ({
|
||||
|
||||
@@ -39,7 +39,7 @@ function CopyButton({ text, label }: { text: string; label: string }) {
|
||||
setDone(true);
|
||||
toast.success("已复制");
|
||||
} catch {
|
||||
toast.error("复制失败,手动选中复制");
|
||||
toast.error("复制失败,手动选中复制");
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -149,7 +149,7 @@ export function PiOAuthLogin({
|
||||
waitMs: 25_000,
|
||||
});
|
||||
setProgress(r.progress);
|
||||
if (r.state === "pending") setMessage("还在处理,稍后再提交一次。");
|
||||
if (r.state === "pending") setMessage("还在处理,稍后再提交一次。");
|
||||
else finish(r.state, r.message);
|
||||
} catch (err) {
|
||||
toast.error(errorMessage(err, "提交失败"));
|
||||
@@ -213,7 +213,7 @@ export function PiOAuthLogin({
|
||||
) : session.mode === "device" ? (
|
||||
<div className="grid gap-2 rounded-lg border border-border/60 p-3">
|
||||
<p className="text-caption text-muted-foreground">
|
||||
在任意设备打开验证地址,输入下面的验证码。授权后这里自动完成。
|
||||
在任意设备打开验证地址,输入下面的验证码。授权后这里自动完成。
|
||||
</p>
|
||||
<div className="flex items-center gap-2">
|
||||
<code className="rounded-md bg-muted px-3 py-1.5 font-mono text-lead tracking-widest select-all">
|
||||
@@ -256,7 +256,7 @@ export function PiOAuthLogin({
|
||||
) : (
|
||||
<form onSubmit={submitPasted} noValidate className="grid gap-2 rounded-lg border border-border/60 p-3">
|
||||
<p className="text-caption text-muted-foreground">
|
||||
在浏览器打开授权链接。授权后会跳到 localhost 地址,页面打不开属正常,把地址栏里的完整 URL 粘贴到下面。
|
||||
在浏览器打开授权链接。授权后会跳到 localhost 地址,页面打不开属正常,把地址栏里的完整 URL 粘贴到下面。
|
||||
</p>
|
||||
{session.authorizeUrl ? (
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
|
||||
@@ -22,21 +22,21 @@ const DEFAULTS_CARD: CardSpec = {
|
||||
{ name: "sites.defaultRateLimit.concurrency", label: "并发", kind: "number", hint: "同一站点同时进行的请求" },
|
||||
{
|
||||
name: "sites.defaultSnapshotIntervalSec",
|
||||
label: "快照周期(分钟)",
|
||||
label: "快照周期(分钟)",
|
||||
kind: "number",
|
||||
hint: "站点开了定时快照但没设周期时使用;5–10080",
|
||||
hint: "站点开了定时快照但没设周期时使用;5–10080",
|
||||
},
|
||||
{
|
||||
name: "sites.userDataMaxSeedingPages",
|
||||
label: "做种列表页数上限",
|
||||
kind: "number",
|
||||
hint: "拉取用户数据时最多翻几页做种列表;1–50",
|
||||
hint: "拉取用户数据时最多翻几页做种列表;1–50",
|
||||
},
|
||||
{
|
||||
name: "sites.userAgent",
|
||||
label: "User-Agent",
|
||||
kind: "text",
|
||||
hint: "账号没填 UA 时,登录和拉取用户数据用这个",
|
||||
hint: "账号没填 UA 时,登录和拉取用户数据用这个",
|
||||
wide: true,
|
||||
},
|
||||
{
|
||||
@@ -44,7 +44,7 @@ const DEFAULTS_CARD: CardSpec = {
|
||||
label: "代理地址",
|
||||
kind: "url",
|
||||
placeholder: "http://127.0.0.1:7890",
|
||||
hint: "只对开了“使用代理”的站点生效;留空不用代理",
|
||||
hint: "只对开了「使用代理」的站点生效;留空不用代理",
|
||||
wide: true,
|
||||
},
|
||||
],
|
||||
@@ -81,7 +81,7 @@ export function SitesSection() {
|
||||
<div className="space-y-6">
|
||||
<div className="pg-slab flex flex-wrap items-center justify-between gap-3 rounded-xl px-4 py-3">
|
||||
<p className="text-caption text-muted-foreground">
|
||||
站点和凭证在「站点」页管理;单个站点的限流、周期、代理在站点的"编辑"里改。
|
||||
站点和凭证在「站点」页管理;单个站点的限流、周期、代理在站点的"编辑"里改。
|
||||
</p>
|
||||
<Button asChild size="sm" variant="outline">
|
||||
<Link to={consolePath("sites")}>
|
||||
|
||||
Reference in new issue
Block a user