style(copy): punctuation rules and site-wide fix with a CI check (QA U11)

- glossary: 10 punctuation rules (full-width in Chinese, CJK/Latin spacing,
  full-width parens around Chinese, single ellipsis, 「」 quotes, period rules)
- scripts/check-copy-punctuation.mjs: checks string literals, templates and JSX
  text (not comments, types, keys, match/compare strings); --fix, --strict,
  --by-file; wired into deno task ci as check:copy in warn mode
- --fix applied to web, server and contracts; files other lanes were editing
  (subscriptions, sites, browser, agent, auth/account, inventory) left for them
- tests updated for the changed messages

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 20:09:29 +08:00
1 parent 9b017906cf
commit 52402864d6
143 files changed
+985 -606

No files matched your search

@@ -23,8 +23,8 @@ import { formatBytes } from "~/lib/utils.ts";
// 与站点工作台同一套下载说明;请求走 POST /search/releases/{siteId}/{siteReleaseId}/plan(同 /acquisition-plans 流程)
const STEPS = [
"生成下载计划,预留版本目标和预算;每个版本目标同时只有一个在途计划",
"已有相同资源或相同 hash 的任务时直接接管,不重复提交",
"生成下载计划,预留版本目标和预算;每个版本目标同时只有一个在途计划",
"已有相同资源或相同 hash 的任务时直接接管,不重复提交",
"缓存卷超过硬阈值或读不到磁盘状态时无法提交",
"提交前复核免费、做种等易变字段",
];
@@ -32,13 +32,13 @@ const STEPS = [
/** 委托 Agent:和工作台一样带上资源、作品、站点 */
export function delegateToAgent(r: SearchRelease) {
openAgentDrawer({
label: `资源:${r.title}`,
label: `资源:${r.title}`,
releaseId: r.sourceReleaseId ?? undefined,
entityId: r.entity?.id,
siteId: r.siteId,
goal: r.sourceReleaseId
? "判断这个资源是否值得下载;合适就按正常流程提交"
: `判断站点 ${r.siteName} 的资源「${r.title}」是否值得下载;合适就按正常流程提交`,
? "判断这个资源是否值得下载;合适就按正常流程提交"
: `判断站点 ${r.siteName} 的资源「${r.title}」是否值得下载;合适就按正常流程提交`,
});
}
@@ -72,7 +72,7 @@ export function SearchDownloadDialog({
if (r.submitted && r.plan) {
setRejected(null);
setDone(r.plan.id);
toast.success(`已提交${slotName(r.slotId) ? `(${slotName(r.slotId)})` : ""},进度见“下载队列”`);
toast.success(`已提交${slotName(r.slotId) ? `(${slotName(r.slotId)})` : ""},进度见「下载队列」`);
} else {
setRejected(r.rejected);
toast.warning("没有生成下载计划");
@@ -107,7 +107,7 @@ export function SearchDownloadDialog({
))}
</ol>
{!entityId ? (
<p className="text-meta text-muted-foreground">资源未关联本地作品。先在“身份与元数据”指定。</p>
<p className="text-meta text-muted-foreground">资源未关联本地作品。先在「身份与元数据」指定。</p>
) : slots.isPending ? (
<p className="text-meta text-muted-foreground">正在读取版本目标…</p>
) : slotList.length ? (
@@ -127,11 +127,11 @@ export function SearchDownloadDialog({
<p className="text-meta text-muted-foreground">这个作品没有版本目标。先在订阅里新建。</p>
)}
{release.entityMatch === "alias" ? (
<p className="text-meta text-warning">作品关联来自标题别名,尚未确认。</p>
<p className="text-meta text-warning">作品关联来自标题别名,尚未确认。</p>
) : null}
{rejected ? (
<div className="rounded-xl border border-warning/40 bg-warning/10 px-3 py-2.5 text-caption text-warning">
<p className="mb-1">没有生成下载计划:</p>
<p className="mb-1">没有生成下载计划:</p>
<ul className="list-disc space-y-0.5 pl-5">
{rejected.map((r, i) => (
<li key={`${r.slotId}-${r.code}-${i}`} className="break-words">