feat(subtitles): 字幕库验证码由智能体视觉接管;字幕站原站视图下载当前字幕

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-03 11:43:08 +08:00
1 parent 023063edf4
commit c30a758a74
24 files changed
+466 -41

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/adapters",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts", "./fsworker": "./src/fs/fsworker.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/agent",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/contracts",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+10 -6
View File
@@ -188,10 +188,14 @@ export const SubtitleSearchResponse = z.object({
});
export type SubtitleSearchResponse = z.infer<typeof SubtitleSearchResponse>;
export const SubtitleFetchRequest = z.object({
entityId: Id,
siteId: Id,
ref: z.string().min(1).max(500),
title: z.string().max(500).default(""),
});
/** 下载一条在线字幕:搜索结果给 siteId + ref;原站视图里人工打开的字幕页给 sessionId(取当前页与浏览器里的 Cookie) */
export const SubtitleFetchRequest = z
.object({
entityId: Id,
siteId: Id.optional(),
ref: z.string().min(1).max(500).optional(),
sessionId: Id.optional(),
title: z.string().max(500).default(""),
})
.refine((v) => !!v.sessionId || (!!v.siteId && !!v.ref), { message: "给 sessionId,或 siteId 加 ref" });
export type SubtitleFetchRequest = z.input<typeof SubtitleFetchRequest>;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/db",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/domain",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/mapping",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/tasks",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@umt/testkit",
"version": "0.3.24",
"version": "0.3.25",
"exports": { ".": "./src/index.ts" },
"tasks": {
"test": "deno run -A npm:vitest run",
+3 -1
View File
@@ -48,6 +48,8 @@ export interface MockCamofoxSite {
cloudflare?: { mode: "auto" | "interactive" | "captcha"; autoPolls?: number; clearance?: string };
/** 页面 HTML(umt-page 读页面内容时返回);缺省按快照行拼一段简单 HTML */
html?: (url: string) => string;
/** 页面 innerText(缺省按页面行拼);返回 null 时用缺省 */
pageText?: (url: string) => string | null;
}
/** mock 的 Cookie 接口形态:plugin = umt-cookies 插件(读写);upstream = 只有上游导入端点(要求 CAMOFOX_API_KEY);none = 都没有 */
@@ -819,7 +821,7 @@ export async function createMockCamofox(opts: MockCamofoxOptions = {}): Promise<
url: t.url,
title,
html,
text: lines.map((l) => l.text).join("\n"),
text: site?.pageText?.(t.url) ?? lines.map((l) => l.text).join("\n"),
ua: MOCK_CAMOFOX_IDENTITY.userAgent,
},
},