Commit Graph
201 Commits
Author SHA1 Message Date
root 1ce937345e Merge branch 'cf2'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	docs/plan/00-first-version-plan.md
2026-09-30 21:27:34 +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
root 389c49dd12 Merge branch 'det2'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	packages/adapters/src/sites/definitions/audiences.json
#	scripts/mp-sync/movieclaw-overrides/audiences.json
2026-09-30 20:50:04 +08:00
rootandClaude Opus 5.5 92830c3ef3 fix(adapters): 观众详情页按真实页面适配(DET-2)
- 促销:详情 h1 是 font.free / font.halfdown 等 + 剩余时间 span[title],新增 umt.detail.promo 覆盖列表促销字段(以前一律判成无促销并覆盖列表的免费)
- 标题去掉 h1 里的「剩余时间:」;发布时间不再取标题区的促销到期时间
- 做种 / 下载 / 完成数、种子 Hash:umt.detail.fields.seeders / leechers / snatched / infoHash
- 副标题去掉评分徽标;标签只取最内层;上传者取 span.torrent-uploader-wrap,标签精确匹配(避开「发布者带宽」)
- 简介:去掉站点声明(page.descriptionStrip)与 MediaInfo 控件(codetop / show / hide),源码换行不再算一行
- 截图排除豆瓣海报与站点横幅
- 列表副标题改取 span.torrent-subtitle-text(以前前面粘着标签文字)
- 脱敏真实样本:详情 2 页进 differential/detail.test.ts,列表 1 页进 MP 差分

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 20:49:29 +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 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 Opus 5.5 0508f3418f feat(agent): require Chinese thinking and reports in subagent prompts (AG-4)
Subagent / vision subflow prompts (audience=agent) get a dedicated section:
report goes to the parent session, and thinking, step notes and reports stay
in Chinese even when the goal, tool results or web pages are in English.
Prompt regression test covers both the shared hard rule and the new section.

Child reports reaching the user are already humanized: the child session page
uses the same FIX-7 report-humanize path, and the parent's final report resolves
child run IDs to their goal titles; agent.spawn/await tool rows show no raw summary.

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 Opus 5.5 ebd07c9230 feat(browser): fixed Windows identity and per-site egress in umt-cookies plugin (BR-4)
- browser:launching hook generates a Windows fingerprint once (camoufox-js,
  os=windows), persists it to /root/.camofox/umt-identity.json and reuses it
  on every launch; Firefox/Camoufox upgrades only bump UA/version fields
- Windows fontconfig with absolute font dir (upstream path was broken)
- GET /umt/identity (public UA/OS/version) and PUT /umt/sessions/:id/proxy
  (per-context proxy; Firefox no longer uses container HTTP_PROXY env)
- adapter identity()/setEgress(), splitBrowserOnlyCookies for cf_clearance/__cf_bm

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 03:17:06 +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 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
root 606e97815f Merge branch 'dl2b'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	apps/web/app/components/library/versions.tsx
2026-09-29 22:15:35 +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
rootandClaude Opus 5.5 3f1c4d6c3b fix(downloads): humanized reasons and TechInfo on the download panel (DL-2b)
- board organize hint uses DEAI-2 reasonLine; add transfer_failed, blocked,
  blocked_by_conflict, main_failed, not_imported_kind, target_root_not_managed,
  download_removed to the reason table with tests
- download detail / plans tab: internal ids, raw codes and JSON moved into TechInfo
- library versions tech block switched to TechInfo (TODO(DEAI-2))
- copy: glossary terms (no 接管/候选), plan reason codes no longer shown raw

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 22:00:04 +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
rootandClaude Opus 5.5 6e68ea5a9d docs(design): DEAI-2 逐条处理情况与不做原因;补下载器原因码
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 21:10:46 +08:00
rootandClaude Fable 5.1 700e8d8a49 fix(db): renumber download task migration to 0054 after merge
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 21:05:48 +08:00
rootandClaude Fable 5.1 8e47d8715b Merge branch 'qb1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 21:05:25 +08:00
root 3f1ff01689 Merge branch 'libv1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	docs/plan/00-first-version-plan.md
2026-09-29 21:03:08 +08:00