Commit Graph
184 Commits
Author SHA1 Message Date
rootandClaude Opus 5.5 51e82f1cd9 feat(organize): record filters, stats and delete with files (HIS-1)
List query gains kind/since/organizeOnly and wildcard/hash search; new
GET /organization-records/stats and POST /organization-records/delete
(optional source/library files to trash via files delete). Public record
adds posterPath, sizeBytes and download summary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 23:57:19 +08:00
rootandClaude Fable 5.1 006549a49f chore(release): v0.3.6
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 22:53:47 +08:00
root 511ad93077 Merge branch 'search4'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	docs/plan/00-first-version-plan.md
2026-09-30 22:41:26 +08:00
rootandClaude Opus 5.5 d9cf8f1c3a feat(search): align quick-filter facets with MP (SEARCH-4)
Add audioCodec, subtitle, dub, feature, year, category, size and seeders
facets with disjunctive counts; parser records dub languages (audioLangs).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:40:55 +08:00
root 2e83107f68 Merge branch 'scr1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	CHANGELOG.md
#	docs/plan/00-first-version-plan.md
2026-09-30 22:36:46 +08:00
rootandClaude Opus 5.5 f38eca419e feat(server): scrapeMedia 刮削任务,入库后自动刮削(SCR-1)
- 文件道任务 scrapeMedia:NFO 原子写入、图片经图片缓存下载(并发 4,失败不阻塞 NFO)、只补缺失 / 全部覆盖
- 设置 organize.scrapeAfterImport / scrapeMode / scrapeImages / scrapeEpisodeThumbs
- POST /library/{id}/scrape、详情 scrape 状态;files/scrape writeNfo 与 scrape-batch write 走同一任务
- 迁移 0057_media_scrape、原因码、审计 organize.scrape
- 与 MP 输出的 NFO 差分测试(apps/server/test/scrape)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:36:14 +08:00
rootandClaude Fable 5.1 b137f365c5 chore(release): v0.3.5
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 21:39:55 +08:00
rootandClaude Opus 5.5 16083942c0 feat(sites): 出口统一与 Cloudflare 过挑战级联(CF-2)
- 出口:站点请求不再隐式继承 HTTP(S)_PROXY,没开代理明确直连(创建客户端时临时拿掉代理环境变量,Deno 2.9 语义见 egress.ts),
  开了走站点代理;TMDB / Brave / 图片改为显式按环境变量(行为不变)
- CloudflareGate:浏览器代理期直接代抓 → HTTP(可复用时带 cf_clearance)→ 挑战 → 浏览器过挑战(同站 30 分钟一次、单飞)
  → cf_clearance 仅在 UA 跟随浏览器且两端同出口时给 HTTP,重试 1 次记 cfReuse → 仍被挑战则浏览器代抓并进入 6 小时代理期
- 浏览器:solveSiteChallenge(自动放行 ≤15s / 系统发起视觉子流程最多 2 次 / 真验证码转人工待处理)、fetchSiteHtml(profile 锁 + 站点令牌)、
  交还后读回 cf_clearance 继续;site.config.cloudflare 状态契约

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:26:54 +08:00
rootandClaude Opus 5.5 6b14b0da45 feat(browser): 插件真实坐标点击与页面内容读取(CF-2)
- umt 插件 POST /umt/tabs/{id}/mouse-click:page.mouse.click,跨域 iframe 的 Turnstile 也点得到;click 坐标优先走它,旧镜像退回 elementFromPoint
- 适配器 pageContent(地址 / 标题 / outerHTML / 正文 / navigator.userAgent);setEgress 返回插件出口模式
- mock camofox 增加 Cloudflare 模式(auto / interactive / captcha)与插件鼠标点击

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:26:53 +08:00
rootandClaude Opus 5.5 a11ef16e40 fix(sites): Cloudflare 挑战不算凭据错误(CF-2)
- http.ts:cf-mitigated: challenge 或 403/503/429 挑战页 → SiteError(challenge),503 不再算维护、403 不再落到 auth_invalid
- 挑战页分类 classifyChallengePage:自动 / 可点(Turnstile)/ 真验证码
- 刷新登录 / 用户数据遇 Cloudflare 挑战只记 last_error,账号状态不变、不开登录失效事项

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:26:53 +08:00
rootandClaude Opus 5.5 b1d30bd6ee fix(sites): 观众健康检查误报未登录,健康失败原因细分(HC-1)
观众 2026 版首页没有 <a href=logout>:退出按钮在 userbar 的 data-uploader-actions JSON
里由脚本渲染,旧登录标志 a[href*="logout"] 永远不命中,健康检查报"未登录"而用户数据正常。

- audiences 定义 loginSuccess 改为 #info_block / usercp.php / logout 任一(0.2.1)
- 健康检查判定细分:登录页 / 权限页 / 疑似人机验证 / 找不到登录标志(带选择器),
  原始判定写入 last_health.detail,站点概览技术信息展示
- 首页只是找不到登录标志时,以 24 小时内用户数据解析成功为已登录证据(同 MP)
- 新 SiteError 类 challenge(cf-mitigated: challenge),不算凭据错误;健康状态 challenge
- testkit mock 增加 setHeaderLayout;加观众首页脱敏结构样本的差分测试

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 20:38:48 +08:00
rootandClaude Fable 5.1 5ddc88d928 chore(release): v0.3.4
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 19:56:29 +08:00
rootandClaude Opus 5.5 3ec2a10993 docs(agent): 巡检 Skill 要求需要批准的检查实际调用一次,补 e16 断言(FIX-9)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 19:29:54 +08:00
rootandClaude Fable 5.1 395417f298 chore(release): v0.3.3
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 19:10:41 +08:00
root 15cec13f42 Merge branch 'ag5'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	CHANGELOG.md
#	apps/server/src/modules/agent/runner.ts
#	packages/agent/src/index.ts
#	packages/agent/src/system-prompt.ts
2026-09-30 18:48:24 +08:00
rootandClaude Opus 5.5 425415b3ba test(agent): prompt eval with fake model and real-model comparison harness
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:47:15 +08:00
rootandClaude Opus 5.5 21b7e8ff23 feat(agent): layered system prompt, environment facts and intent-routed skills
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:47:15 +08:00
rootandClaude Opus 5.5 0f20c19b7c feat(agent): add read-only download.list capability
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:47:15 +08:00
root 6f5371be2d Merge branch 'meta2'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	CHANGELOG.md
2026-09-30 18:40:42 +08:00
rootandClaude Opus 5.5 9489e40e0c feat(identity): source-aware short-drama enrichment with snippet mode and hit rate (META-2)
- classify enrich sources: encyclopedia, platform pages (hongguo, kuaikaw, video
  platforms), douban (search snippet only) and other sites' search snippets
  (snippet mode, pages never opened); one extractor per source, fields carry
  source kind and confidence, merged by noisy-OR across hosts
- new cast field (applied as MediaCredit with placeholder ids)
- robots.txt check (cached per host 1 day) and login-wall/captcha give-up
- per-enrichment source attempts + GET /identity/enrich-stats, 30-day hit-rate
  table under settings -> metadata -> identity
- setting identity.enrichSnippetAllSites (default on); default domains add
  baike.com and kuaikaw.cn
- replay fixtures from the real run on the 4 user-library short dramas
  (sanitized Brave responses, hongguo page, robots.txt)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:40:19 +08:00
root 09bac0ea39 Merge branch 'ag4'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	CHANGELOG.md
2026-09-30 18:21:57 +08:00
rootandClaude Opus 5.5 1fcfcac885 feat(browser): keep sessions alive during desktop, takeover and agent use (AG-4)
camofox reaps a tab after TAB_INACTIVITY_MS (5 min) without API tool calls;
desktop-mode input goes straight to Selkies and screenshots don't count, so
tabs disappeared under the user during takeover.

- BrowserKeepalive (in-process): sessions held by an open desktop WebSocket
  (ref-counted), a human takeover lease, or a running/queued agent run that
  used browser.* get a keepalive every BROWSER_KEEPALIVE_MS (default 120s,
  0 = off). Holds are re-checked each round; release/lease expiry/agent end/
  session close stop it and camofox reaps as usual.
- Keepalive call: camofox 1.17 has no keepalive/touch endpoint and /stats does
  not bump toolCalls; use GET /tabs/{id}/downloads without includeData/consume
  (read-only metadata). Goes through BrowserService.run so restarts or reaped
  tabs self-heal via BR-3 reconnect; no lastAutomationAt, no control needed.
- Runbook browser.md §12, deploy env table, compose env; tests against the
  testkit mock camofox.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:05:12 +08:00
rootandClaude Opus 5.5 f9901b514b feat(metadata): overview falls back to Chinese variants only (MD-2)
- adapters: overviewLanguages() limits overview/tagline chain to Chinese
  variants (zh-CN→zh-SG→zh-TW→zh-HK); titles keep full chain; season
  supplement fetch skips languages useless for overview
- setting metadata.overviewNonChineseFallback (default off) + UI switch
- media detail shows "暂无简介" for empty entity/episode overview
- scripts/overview-recompute.ts: recompute stored non-Chinese overviews
  from kv_cache only (no TMDB requests), dry-run by default, --apply
- tests: chain unit tests, Heart Signal (103147) fixture, server
  recompute test, MP differential for episode overview
- runbook + CHANGELOG

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:04:23 +08:00
rootandClaude Opus 5.5 01653b0427 feat(agent): dedupe agent.spawn by normalized goal within a parent session (AG-4)
A spawn whose goal (NFKC, case, whitespace and punctuation folded) matches a
child of the same parent that is still queued/running, or succeeded/waiting
within the last 10 minutes, returns that child instead of creating a new one:
output gets reused=true, a message ("已有同目标子会话…") and the child's
current result summary. Failed/cancelled/over-budget children are not reused.
Spawn decisions are serialized per parent in-process so parallel duplicate
calls in one batch create a single child. Replays keyed by idempotency still
hit the original child as before. The subagent constraint in the system prompt
asks for Chinese sub-goals and no duplicate spawns.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 17:58:08 +08:00
rootandClaude Fable 5.1 04460fa98e chore(release): v0.3.2
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 03:29:04 +08:00
rootandClaude Opus 5.5 adc853aa64 feat(sites): site requests follow browser UA, smooth UA switch, CF cookies browser-only (BR-4)
- every outbound site request (adapter list/search/detail/download/health,
  RSS, login, user data) carries the account UA via SourcesRuntime.siteFetch;
  no more Deno default UA
- priority: account manual > pending > global setting > browser identity
  (fallback: same-shape Windows Firefox UA); settings UA default is empty
- migration 0056: existing cookie/password accounts keep their old UA as
  ua_pending until re-login or browser cookie write-back switches cookie+UA
  in one transaction; browser_provider.identity caches the browser identity
- cf_clearance/__cf_bm stripped on browser write-back (names kept only)
- browser sessions get per-site egress (same proxy as HTTP, or direct)
- site account page shows UA source; raw UA in tech info

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 03:17:13 +08:00
rootandClaude Fable 5.1 9296161683 chore(release): v0.3.1
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 01:26:48 +08:00
rootandClaude Fable 5.1 85aa9d47d0 Merge branch 'dl3'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 01:15:40 +08:00
rootandClaude Opus 5.5 a9147e647d feat(downloads): fold download plans into download panel (DL-3)
- Waiting plans (approval / disk space / automation off / queued) are
  active-segment rows on /download-tasks/board, merged by created_at,
  counted, with approve / cancel actions; ?plan= deep links and legacy
  /downloads/plans routes redirect to the panel
- Download detail shows "why this download" (source, purpose, replaced
  version, reasons); raw evaluation in tech info
- Failed / cancelled / expired plans appear in the entity download
  history; rejected / revoked / expired approvals close draft plans
- New GET /acquisition-plans/{id}/why, POST /acquisition-plans/{id}/cancel
- User-facing copy no longer says 下载计划; glossary updated

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 01:15:25 +08:00
root 7a24d23bbf Merge branch 'ia2'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	CHANGELOG.md
#	docs/plan/00-first-version-plan.md
#	packages/agent/src/system-prompt.ts
2026-09-30 00:30:42 +08:00
rootandClaude Opus 5.5 ec65435328 feat(server): gate scheduling, search and login by site capabilities (IA-2)
- snapshots only for sites with list; feed polling only for RSS kinds;
  user data / health checks only for sites with login; search site set
  only includes searchable sites; live search / snapshot skip with
  reason unsupported instead of hitting the site
- refresh-login / credentials need login, manual snapshot needs list (400)
- POST /sites accepts kind and rssUrl (site + feed in one transaction,
  key generated from host); RSS belongs to a site: feeds created without
  siteId go to the same-host custom RSS source site, siteId cannot be
  cleared
- fix: secret name clash when a site gets a second default-named feed
- command palette regrouped; agent site.list returns kind and
  capabilities; system prompt notes RSS lives under sites

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 00:29:56 +08:00
rootandClaude Opus 5.5 89d2c81de6 feat(sources): site kinds and capabilities (IA-2)
site.kind: pt / public_bt / rss_feed / torznab. Each kind declares the
acquisition modes it may support (search, list, rss, detail, login,
userinfo); a site's effective capabilities = kind ∩ site definition.
torznab only defines TorznabSiteConfig and cannot be added yet.

Migration 0055: generic_rss sites become rss_feed, the rest pt; feeds
without a site are grouped by host into new custom RSS source sites
(cursor window and conditional headers cleared so the next fetch writes
releases). User DB read-only dry-run: 0 orphan feeds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 00:29:56 +08:00
rootandClaude Fable 5.1 62b4969c32 Merge branch 'wk1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 00:25:47 +08:00
rootandClaude Opus 5.5 da33cad81d feat(worker): IO Worker 分道(WK-1)
io worker 进程内按任务声明的 lane 分文件 / 网络 / 维护三条道,各自并发(缺省 2/4/1)、
各自排队;维护道在文件道或网络道有排队/运行时让路(连续 10 分钟放行一个),调度器内联的
清理/回填/保留期裁剪也走维护道。并发在 设置 → 自动化 → 高级 热生效,env 覆盖;旧
WORKER_CONCURRENCY 映射到网络道。运行状态页按道显示运行中/并发/排队。归属表写进
docs/runbook/dev.md,ci 与注册表逐项核对。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 00:24:21 +08:00
rootandClaude Fable 5.1 9ef2e8554c Merge branch 'fix8'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-30 00:10:57 +08:00
rootandClaude Opus 5.5 fa344a7184 feat(web): token 数以 K 输入显示,已存凭证显示掩码占位(FIX-8)
- 新增 UnitInput 与 kind=tokens:上下文预算、单次 token 上限、自定义模型上下文窗口以 K 输入(允许小数),存储仍为原始 token 数;校验与提示用 K 表述;列表/详情 token 数统一 K/M 简写(formatTokens)
- 新增 SecretInput 与 kind=secret:已保存时显示「已设置 ••••••••」(有服务端掩码时带末 4 位),聚焦直接输入替换,留空保持,「清除」确认后保存生效;替换模型服务、TMDB、网页搜索、下载器、媒体服务器、浏览器服务、站点账号、Passkey、本机 Token 各处
- 统一只写凭证服务端语义:省略或空串 = 不变,null = 清除(contracts secretInput);下载器/媒体服务器新增清除;站点凭证同类更新可留空保持密码/Cookie/API Key/TOTP,TOTP 可 null 清除,不再误删 TOTP 与 UA
- contextBudget 最小值 4096→4000、contextWindow 1024→1000,便于按 K 填写
- 测试:换算与校验、SecretInput 渲染与状态、各接口留空不变/显式清除

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 00:10:46 +08:00
rootandClaude Opus 5.5 3c17fa3356 fix: 文件与作品页的低优先级问题(FIX-7)
- 文件列表「主文件」只认视频扩展名(字幕自成资产时位置 is_primary 也为真)
- 行内悬浮操作只在鼠标悬浮时出现,选中行不再常驻遮挡大小/时间
- 种子详情按识别状态说人话,解析结果 JSON 跟随技术信息默认收起
- 作品页空收录版本写「没设收录要求」,版本行写「库里有 N 个版本」

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 00:00:03 +08:00
rootandClaude Opus 5.5 23bd8cfe45 fix(web): 巡检目标模板的占位符显示成名称(FIX-7)
执行时 renderGoal 已正确替换(补单测);界面显示的是模板本身,{{now}} 等改成「当前时间」标签。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 00:00:03 +08:00
rootandClaude Opus 5.5 1b22bb5131 feat(agent): downloader.list 能力与汇报计数规则(FIX-7)
智能体原先只能从 site.list 推断下载器,会把没看到汇报成下载器不在系统内。
新增只读能力 downloader.list(下载器与媒体服务器、连通状态、管理的任务数);
原因码表补能力错误、下载盘判定、站点登录与待处理类型,带分类前缀的码按后半段查;
汇报格式加「数量以工具返回为准」。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 23:59:51 +08:00
rootandClaude Fable 5.1 8c50e4672f chore(release): v0.3.0
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 22:55:20 +08:00
rootandClaude Fable 5.1 0055db6cf9 Merge branch 'agui3'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 22:43:07 +08:00
rootandClaude Opus 5.5 2ab6d452dd feat(agent): 系统提示规定汇报格式(AGUI-3)
新增「汇报格式」一节:第一句写结论;对象用名字,不写函数名、工具名、字段名、UUID 或 hash;
不超过 10 行;列举 3 个以上资源才用表格;不写标题和 HTML。证据规则改为写对象名称和关键数值。
方案规则改为只在真有分歧时给方案,并说明方案绑定计划、选定即批准的用法;步骤标题不写工具名。
子会话与视觉子流程汇报给父会话(audience: agent),不加用户汇报格式。
加 prompt 回归测试,快照断言汇报格式的关键约束句。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 22:41:13 +08:00
rootandClaude Opus 5.5 4e0e6712da feat(agent): 选定方案即批准,服务端绑定计划(AGUI-3)
- agent.propose_options 的方案可带 action(capabilityId + planId)。提出方案时服务端按计划当前的
  payload hash + revision 绑定,并用计划本身生成动作要点(对象、大小 / 文件数)发给界面,不用模型的说法。
- 控制台管理员会话选定绑定了计划的方案时,建一份 scope.via=option 的已批准单次审批(审计 approval.approved);
  执行时授权器 optionApproval 核对能力、计划类型 + ID、payload hash、revision、有效期后放行,用后 consumed,
  不再出第二张审批卡。API Key 作答、超时自动选、计划已变化都不算批准;移动 / 替换文件的整理与发布策略
  (删除、覆盖类)选定后仍单独确认。会话停止时撤销没用掉的这类审批。
- contracts:CAPABILITY_ACTIVITY 给每个能力加 verb / noun(会话进度行的人话计数);agent.plan /
  agent.propose_options 标为 hidden。
- e12 补测试:管理员选定 → 无 approval_requested、审批绑定同一计划并 consumed、换 hash 不放行;
  API Key 选定 → 仍出审批卡。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 22:40:57 +08:00
rootandClaude Opus 5.5 c9c6505d71 fix(agent): 超预算待处理事项先于会话终态写入
e15「超预算」偶发失败(全量 ci 负载下 decision.agent_run_id 仍是上一次运行)是产品竞态,不是测试等待不足:
finalize 先把 agent_run 写成 budget_exceeded,之后才 upsert 同根因的超预算待处理事项(和任务行)。
观察者(测试、会话页、待处理中心)在两次写入之间看到终态时,事项还指向上一次运行。

改为先写待处理事项与任务行,最后写会话终态:看到 budget_exceeded 时事项已指向这次运行。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 22:40:39 +08:00
rootandClaude Fable 5.1 7bbe0d4de7 Merge branch 'polish1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 22:06:58 +08:00
rootandClaude Opus 5.5 71b129d85a feat(web): merge search filters into one row and tidy episode versions (POLISH-1)
- H&R becomes a quick-filter facet (yes/no/unknown, with counts) on search
  results and the site resources tab; drop the old free/H&R selects, keep
  size range and sort on the same row (mobile: drawer), single clear button
- legacy free/hr URL params migrate into quick filters; stored selections
  keep the same localStorage key
- search timing and query terms move into TechInfo
- library episode versions: click the whole row to expand, versions listed
  as sibling rows, details only under the selected version, raw values in
  TechInfo
- slot comparison gaps get reason codes (matchGapText in contracts
  reasons.ts): "可换成 2160p", "缺 HDR 版本"

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 22:06:32 +08:00
root 8315ece4d1 Merge branch 'dl2'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	apps/web/app/routes/console/downloads.tsx
#	docs/plan/00-first-version-plan.md
2026-09-29 21:45:15 +08:00
rootandClaude Opus 5.5 3b340745bf feat(downloads): live speeds and active/completed split on the download panel (DL-2)
- GET /download-tasks/board?state=active|completed: per-torrent dl/up speed,
  ETA, seeds/leechs, downloader total speed (transfer/info), counts for both
  groups, latest organize result (status, reason code, open decision)
- live qB data cached per instance for 2 s with in-flight coalescing
- panel: total speed line, 进行中 / 已完成 segments remembered locally,
  4 s polling while the page is visible, mobile layout, "—" for zero speed

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 21:44:34 +08:00
rootandClaude Opus 5.5 289e8b297a feat(files): wide file manager layout and basic previews (FM-2)
- Files page uses a wide layout (route handle layout:"wide"): no max width,
  full-height directory tree docked next to the sidebar, resizable
  (200-520px, remembered, double-click resets) and collapsible; mobile keeps
  the tree in a drawer.
- GET /files/preview (admin console session only, same path guards as
  download): text/NFO with encoding detection (BOM/UTF-16/UTF-8/GB18030/Big5),
  subtitles first 200 cues (SRT/VTT/ASS/SSA, PGS timings), .torrent file
  list/trackers (passkey masked)/infohash, image dimensions. Reads at most
  1 MiB of text; .torrent capped at 4 MiB.
- Download also allows text files, .torrent and avif/gif.
- Research notes in docs/design/file-preview-research.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 21:44:13 +08:00
root 12bc4664b6 Merge branch 'deai2'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	apps/server/src/modules/acquisition-organize/services/organize.ts
#	apps/web/app/routes/console/sites.$siteId.tsx
2026-09-29 21:26:16 +08:00