Commit Graph
110 Commits
Author SHA1 Message Date
rootandClaude Opus 5.5 76433dd43f docs(organize): MP history comparison and changelog (HIS-1)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 23:57:19 +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 acab4cc6bb docs(search): MP facet comparison table and changelog (SEARCH-4)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:40:55 +08:00
rootandClaude Opus 5.5 0e8bb6967d docs: 刮削运行手册与 CHANGELOG(SCR-1)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:36:14 +08:00
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 c38ac2a85c docs: CF-2 出口表、Cloudflare 级联运维与插件点击核验
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 21:26:54 +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
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 9962494936 docs(agent): prompt layering, skill authoring and eval runbook
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 f4a7fa863e docs(agent): AG-4 runbook and changelog (spawn dedupe, subagent language, session stats)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 18:05:12 +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 9ea0d6bed1 docs(browser): BR-4 runbook for browser identity, UA priority, migration, CF cookies, egress
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 03:17:13 +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 1493cd1bb1 docs: IA-2 nav regroup and site types
Glossary: site types, acquisition modes, the 获取 group name
(ACQUIRE_GROUP_TITLE). Runbook sites.md, CHANGELOG [Unreleased], plan
status.

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 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 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 Fable 5.1 8e47d8715b Merge branch 'qb1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 21:05:25 +08:00
rootandClaude Opus 5.5 50c8d534f8 chore(deploy): NO_PROXY defaults for downloaders; explain library root modes
- compose: app gets a default NO_PROXY (UMT_NO_PROXY) listing compose
  service names incl. qbittorrent / qbittorrent-nox / qb / transmission /
  deluge / aria2, so a proxy override never swallows downloader traffic.
- runbook: proxy and test-qB override templates use the same list.
- Settings: one-line hint on library root "管理方式" (managed vs
  register_only).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:54:37 +08:00
rootandClaude Opus 5.5 e7de7e2e69 feat(organize): identify takeover downloads by file name and close organize decisions
Takeover identify (item 2):
- Adopted tasks without source release / plan: on completion planImport
  parses main video path (file + parent + grandparent dirs, like MP
  MetaInfoPath) merged with the torrent name, then runs ID-2 matching via
  identifyParsed (local recall + TMDB; trigger "takeover" may query TMDB).
  auto -> bind/create entity, backfill download_task.media_entity_id and
  organize right away; no pool entry, no identity decision.
- Failure / ambiguity: organize_identity decision with evidence and
  options: candidates, select entity (local / TMDB), provisional entity,
  dismiss.

Decision closure (item 3):
- decision-hooks registry: the decisions resolve route runs the owning
  module's executor before closing; errors keep the decision open.
- organize_identity: backfill entity, freeze manual plan, enqueue run.
- organize_blocked with target_exists: replace (verify + trash old) /
  keep both (rename "<name> (n)" with sidecars) / skip.
- Successful organize closes both organize_identity and organize_blocked
  of the same download task (resolution manual_organize), also for manual
  path organizes matched to download tasks via path mappings.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:54:19 +08:00
root 4c7375b52f Merge branch 'search3'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	docs/plan/00-first-version-plan.md
2026-09-29 20:52:51 +08:00
rootandClaude Opus 5.5 970296218c feat(search): multi-select quick filters for search results and site releases (SEARCH-3)
- domain release-facets: bucket resolution / codec / release type / site / promotion / HDR /
  release group / season / episode; OR within a dimension, AND across; disjunctive counts
- GET /search/releases and GET /sites/{id}/releases accept qf and return facets; site list
  facets come from local source_release rows only (no site requests), paging stays consistent
- web QuickFilterBar shared by search results and site resources tab: per-dimension popover
  (bottom sheet on phones) with counts, removable tags, clear all, localStorage memory per page
- runbook: quick filter params and bucket definitions

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:52:29 +08:00
root 7e3ac56f06 Merge branch 'dh1'
Co-Authored-By: Claude Fable 5.1 <[email protected]>

# Conflicts:
#	docs/plan/00-first-version-plan.md
2026-09-29 20:50:19 +08:00
rootandClaude Opus 5.5 044e718ec6 feat(identity): content unit data hygiene — specials, provisional promotion, duplicate merge (DH-1)
- metadata.includeSpecials (default true): full refresh and the language
  backfill fetch TMDB season 0 (specials) when present, like MP; season 0
  stays out of the episode-total ledger
- refreshMetadata promotes provisional season/episode units that match the
  TMDB season/episode layout to confirmed (source=tmdb), keeping ids and all
  references; non-matching units stay provisional
- content_unit.source (migration 0053): release / file / tmdb / user
- duplicate units (same entity/kind/season/episode/content type/segment) are
  merged as a refresh step and via `scripts/identity-cleanup.ts
  --merge-duplicates` (dry-run by default); keeper = most referenced, then
  confirmed, then earliest; references auto-discovered via FKs and repointed
- ensureUnits takes a per-unit advisory xact lock to stop concurrent lazy
  creation from producing duplicates
- runbooks updated; user DB read-only dry-run: 征途 S01E09/E10 4 units each
  -> 1 each (6 removed), not applied

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:49:56 +08:00
rootandClaude Opus 5.5 74f1566985 feat(qbittorrent): login compat for v4/v5.0-5.2 and three auth modes
- Login success = HTTP 200 "Ok." or 204 (5.2+); session cookie taken from
  Set-Cookie by name (SID / QBT_SID_<port> / custom) and sent back as-is.
- Failure classes: "Fails." / 401 -> auth; 403 IP ban / 429 -> rate;
  wrong API Key (403) -> auth with hint; 5xx -> protocol.
- Downloader instance auth kind: password / api_key (qB 5.2+ Bearer, no
  /auth/login) / none (whitelisted subnet); stored in settings.authKind,
  credential write-only in secret_ref, cleared when switching to none.
  One qbAuthConfig() shared by sync, agent capability and connection test.
- Settings form: auth kind select, password / API Key fields (no echo).
- testkit: mock qB 5.2 login behaviour, IP ban, bypassAuth;
  makeTorrent({ realPieces }) builds real piece hashes for real qB checks.
- Real-container matrix (QB_REAL, skipped by default): 5.1.2 and 5.2.4,
  login / add / query / tags / pause-resume / delete keeping data.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:42:17 +08:00
rootandClaude Opus 5.5 c846e91cc4 docs(runbook): test qBittorrent override example for SIM-1
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:19:00 +08:00
rootandClaude Opus 5.5 bca46fd796 fix(identity): never delete TMDB/metadata units in identity-cleanup orphan pass (FIX-6)
Orphan detection now only removes provisional units created by release
parsing that carry no metadata trace (field sources, overrides, title,
air date, total source) and whose entity has no accepted external
identity, or that fall outside the entity's external season/episode
layout. TMDB ledger units are never deleted. Dry-run output lists
deletions and kept units by category; --dry-run is explicit and
mutually exclusive with --apply; audit payload records each orphan.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:08:44 +08:00
rootandClaude Opus 5.5 9244315768 fix(web): agent check default model fallback; ensure browser session before desktop iframe (FIX-5)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 19:37:12 +08:00
rootandClaude Opus 5.5 6aaf8c0704 feat(web): storage section on status page (FIX-5)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 19:37:11 +08:00
rootandClaude Opus 5.5 2c9e5a1d00 feat(metadata): one-shot metadata.backfill_languages maintenance job (FIX-5)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 19:37:11 +08:00
rootandClaude Opus 5.5 a51dc1590f fix(identity): guard site aliases and add identity-cleanup script (FIX-5)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 19:37:11 +08:00
rootandClaude Opus 5.5 e681fcedf6 feat(schedules): per-check cost and model summary on GET /schedules (INT-3)
agent_check items carry agentRuns (last 100 sessions: last/avg cost, 7-day count and cost,
models, recent 3); plan page and home plan band use it instead of fetching agent runs.
Migration 0052 indexes agent_run(created_by, created_at).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:55:47 +08:00
rootandClaude Opus 5.5 82df5662f0 fix(web): desktop view ensures session on open and auto-reconnects after 5s blank (INT-3)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:52:08 +08:00
rootandClaude Opus 5.5 ed868f166e feat(metadata): apply language chain and queue full refresh on new entities (INT-3)
Entities created from TMDB candidates (subscription, search/TMDB preview, organize wizard)
and manual assignment to an unregistered TMDB identity take title/overview from the
metadata.languages chain at creation and enqueue refreshMetadata full=1.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:51:04 +08:00
rootandClaude Opus 5.5 fe05138c9c feat(settings): storage budgets and retention in settings UI, tmdbMaxSize default 5000 (INT-3)
- Automation section gets storage budget, retention and cache TTL cards bound to settings.storage
- Metadata section drops deprecated cache.tmdbTtlHours / cache.emptyResultTtlSec / identity.poolArchiveDays inputs
- cache.tmdbMaxSize default 256 -> 5000; migration 0051 bumps stored values still at the old default

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:46:36 +08:00
root 4d850c1c9c Merge branch 'fe6' 2026-09-29 17:43:00 +08:00
root f41cd96fee Merge branch 'hh2'
# Conflicts:
#	apps/server/src/modules/browser/service.ts
#	apps/web/app/components/browser/desktop-view.tsx
#	apps/web/app/components/browser/site-origin-view.tsx
#	packages/contracts/src/browser.ts
2026-09-29 17:43:00 +08:00
root f30600eafc Merge branch 'id2'
# Conflicts:
#	packages/adapters/src/tmdb/index.ts
2026-09-29 17:42:38 +08:00
root b633eb5379 Merge branch 'md1'
# Conflicts:
#	packages/contracts/src/settings.ts
2026-09-29 17:42:31 +08:00
root eb9cfaa63d Merge branch 'cache2' 2026-09-29 17:42:24 +08:00
rootandClaude Opus 5.5 42e08b30dc feat(scripts): identity-reevaluate with --rollback-wrong; docs for ID-2
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:41:22 +08:00
rootandClaude Opus 5.5 cabd772243 fix(sites): normalize HHClub RSS items, complete detail page parsing (HH-2)
- RSS: split NexusPHP "[category]name[subtitle][size][uploader]" titles in the
  site adapter layer (category id/name/media type, clean title, subtitle,
  size); snapshot fields win on merge; lazily renormalize old RSS rows and
  re-emit release.observed; unknown list fields show an em dash
- Detail: HHClub section layout (douban info block as description,
  screenshots section, IMDb/TMDB from MediaInfo lines, upload time field,
  on-demand viewfilelist.php once); site CDN screenshots get a Referer
- Site request count now includes site-bound RSS fetches
- Origin view shows "自动化" when idle and "Agent" only after recent
  automation actions (lastAutomationAt); agent step titles no longer get
  squeezed to a sliver by long notes

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:30:25 +08:00
rootandClaude Opus 5.5 838aea3ebd feat(browser): self-heal sessions after camofox restarts (BR-3)
- Any session operation that hits 404/410 (or finds no open tab) reconciles
  tabs; if none survive it re-injects the account cookies (BR-2), opens a new
  tab under the same userId/sessionKey, returns to the recorded URL (site home
  otherwise), marks old tabs lost and retries the operation once. Failure
  returns 503 browser_reconnect_failed with the reason, with a 10s backoff.
- Restart detection: umt plugin GET /umt/instance (fallback /health fields);
  a changed instance id marks every open session needsReconnect.
- POST /browser/sessions/{id}/reconnect (idempotent); session view exposes
  needsReconnect and reconnect {status, trigger, at, reason, humanNotice}.
- Controller and lease are kept; reconnecting during takeover asks the human
  to double-check the reloaded page.
- Web: screenshot and desktop modes show "reconnecting", auto-reconnect once,
  pause polling, offer a reconnect button with the reason on failure; desktop
  mode rebuilds the Selkies connection after a reconnect.
- Mock camofox restart(), tests, smoke step and runbook section 10.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:29:11 +08:00
rootandClaude Opus 5.5 4ca985a8ad docs(runbook): metadata language chain and episode metadata (MD-1)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:28:16 +08:00
rootandClaude Opus 5.5 4f7c0a62c2 docs(runbook): storage budgets and retention runbook (CACHE-2)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:16:50 +08:00