Fetch the detail page (cached, rate-limited, per-site hourly cap
identity.detailIdsPerSiteHour) for search results, subscription-related
candidates, pool enrich and manual re-identify; resolve IMDb/TMDB via TMDB,
douban via cached douban subjects (site detail info block / META-2 snippets).
No identity_unresolved decisions for releases with site IDs.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
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]>
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]>
- 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]>
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]>
- 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]>
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]>
- 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]>
- 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]>
- 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]>
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]>