Commit Graph
179 Commits
Author SHA1 Message Date
rootandClaude Fable 5.1 1b2dc7aa75 docs(design): agent chat usability review (AGUI-3)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 20:41:30 +08:00
rootandClaude Fable 5.1 3763c86481 docs(plan): show stored versions per title (LIBV-1)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 20:31:04 +08:00
rootandClaude Fable 5.1 eea5bbc6c9 docs(plan): plan page grouping and 智能体 naming (user feedback)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 20:30:01 +08:00
rootandClaude Fable 5.1 d282212a6b docs(plan): de-AI decisions and MP-style search quick filters
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 20:27:45 +08:00
rootandClaude Opus 5.5 e68ccd4030 docs(design): de-AI / de-engineering review of console copy and design (DEAI-1)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 20:24:56 +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 Fable 5.1 2847512501 docs(plan): data hygiene follow-ups after cleanup incident
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 20:09:23 +08:00
root 2bd1b58158 Merge branch 'fix6' 2026-09-29 20:09:03 +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 Fable 5.1 ae6460acf1 docs(plan): lesson on reviewing real-DB dry-run before destructive cleanup
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 19:51:33 +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 a10a39fde1 docs(plan): INT-3 CI and smoke results
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 18:37:35 +08:00
rootandClaude Opus 5.5 de2694cace docs(plan): INT-3 migration table wording
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 18:07:52 +08:00
rootandClaude Opus 5.5 26ce782678 docs(plan): INT-3 integration record and changelog
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 18:07:44 +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
root 80f0fa0c1f Merge branch 'br3' 2026-09-29 17:29:32 +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
rootandClaude Opus 5.5 baf2d6ea04 feat(web): split plan page from tasks (FE-6)
- Nav overview group: 首页 / 任务 / 计划 / Agent 会话; tasks page drops the plan tab
- /console/tasks?tab=plan[&job=] redirects to /console/schedules[?job=]
- Plan page: 自动任务 compact grouped list (switch, interval preset/custom, last result,
  countdown, failure reason, run now/skip/run records) and Agent 巡检 cards (goal,
  allowlist, budget, upstream/model, trigger, cost per run, recent sessions); split stats
- Home plan band: two counts linking to #auto / #checks
- Docs: console-ia §7.4a, glossary, schedules runbook; smoke routes

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 17:13:54 +08:00
rootandClaude Fable 5.1 200550d0c6 docs(plan): VER-3 findings and assignments
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 17:02:53 +08:00
rootandClaude Fable 5.1 4a212ed19e docs(plan): browser session auto-recovery after camofox restart (BR-3)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 16:54:44 +08:00
rootandClaude Fable 5.1 da24380870 docs(plan): Chinese title fallback chain and episode-level metadata (MD-1)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 16:49:49 +08:00
rootandClaude Fable 5.1 c3aaf901ad docs(plan): ID-2 identity matching parity, FE-6 tasks/plan split, CACHE-2 storage budget
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 16:46:45 +08:00
rootandClaude Opus 5.5 d0da4f4add docs(plan): INT-2 integration record and shared-index lesson
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 16:45:44 +08:00
rootandClaude Opus 5.5 04cffcd1f1 feat(sites): on-demand site detail page content (INT-2)
- SiteReleaseDetail.page: description, MediaInfo/BDInfo, screenshots,
  IMDb / Douban / TMDB ids, file list, tags, uploader, plus a parse probe
  (labels found) for layout-change diagnosis. Generic NexusPHP rules
  (field label -> next sibling) starting from the MovieClaw detail
  selectors; site overrides under umt.detail.page (HHClub: div labels).
  M-Team builds the same structure from descr BBCode + mediainfo.
- Fetched only on demand (drawer open without cache, "复核详情",
  release.inspect); content in kv_cache region site.detail for the
  site detail cache period (>= 24 h); within the window the site is not
  requested again. External ids persist in source_release.raw._detail,
  which list snapshots do not overwrite.
- Screenshots only as proxy paths /api/v1/img/site-detail/{rid}/{i}:
  public-address check on every hop, no site credentials, magic-byte
  image check, 8 MB cap. Poster proxy shares the same helper.
- Identity: site ids count as explicit-id evidence; when TMDB is
  queried, a TMDB id goes straight to details and an IMDb id to
  /find (no title search on a hit). Douban only for local recall.
- Release drawer "站点详情页" section; fixtures and tests for HHClub div
  layout, rowhead layout, BBCode, cache/proxy/identity end to end.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 16:21:17 +08:00
rootandClaude Fable 5.1 99e335d13c docs(plan): META-1 follow-up (broaden enrichment sources)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 15:58:56 +08:00
rootandClaude Opus 5.5 f4666a4671 feat(identity): web metadata enrichment for titles missing on TMDB (META-1)
- metadata.enrich (propose, low, replay safe): normalized-title cache (kv_cache
  region enrich, 7 days) -> daily budget -> web.search (title + 短剧 / 电视剧 平台,
  second query limited to whitelist via site:) -> web.fetch of up to 3 relevant
  whitelisted pages (registered site domains never read, redirects out of the
  whitelist dropped) -> upstream model extraction with rule fallback -> server-side
  evidence check (rule_confirmed / multi_evidence / needs_review). Suggestion only.
- POST /identity-pool/{id}/enrich (suggest) and /enrich/apply (console session):
  provisional entity or same-title merge, season/episode units, field-level
  metadata with source web/agent + evidence, aliases, release assignment.
  Poster proxy GET /img/enrich/{id} (og:image from whitelisted pages only).
- Auto-enrich once per pool entry when subscription/rule lookups find nothing on
  TMDB (identity.autoEnrich, off by default); identity.enrichDailyBudget,
  identity.enrichDomains settings; web.fetch now returns og:image.
- Pool sheet "元数据补全" section; entity detail shows evidence links.
- Migration 0049_enrichment (metadata_enrichment, metadata_field.evidence, source
  web). Requires image rebuild / api + worker restart to take effect.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 15:57:48 +08:00
rootandClaude Opus 5.5 28974d1e1a feat(browser): unify site credentials with browser profiles (BR-2)
- Inject the site account Cookie (manual + auto-login session, session wins)
  into the camofox profile before the first tab opens; password accounts
  without a session run refresh-login first; API Key sites are skipped.
- Cookie expired after injection -> credential.status=expired; cookie
  accounts go to waiting/login_required ("log in once, applies site-wide").
- Write back site-domain cookies from the browser on handover, session close,
  every 10 min of activity, and from refresh-login when the stored cookie is
  invalid (verified before saving). user_info.cookieOrigin records
  source=browser; source shown as manual/login/browser in the origin view.
- New camofox plugin umt-cookies (GET/POST /umt/sessions/:userId/cookies
  under the access key); profile dir 0700/files 0600 in the desktop image.
- Single entry: sources-identity/service/credentials.ts.
- Real check: HHClub cookie injected into a fresh profile -> home page
  logged in (logout link present), 5 cookies read back.

Requires rebuilding umt-browser-desktop (docker compose build camofox &&
docker compose up -d camofox) to take effect.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 15:25:07 +08:00
rootandClaude Opus 5.5 901b01d1a1 fix(sites): HHClub parsing, resource list layout and request restraint
HHClub (憨憨) was checked read-only against a real account (one detail
request; list, user data and health came from the product's own fetch).

Parsing fixes:
- list titles carried the site's new-torrent marker "[新]" (58 of 100
  rows; the detail page title has none); stripped with a replace filter
- refreshing a detail overwrote seeders / leechers / snatched / category
  name / H&R with null because the HHClub div detail page lacks them;
  detail values now fall back to the list snapshot (mergeDetailOverList),
  and an unknown detail promotion keeps the list promotion
- level "贵宾" is VIP (umt.vipLevels)
- sanitized minimal fixture HHANCLUB_LIST_PAGE_2026 + tests; README marks
  HHClub as verified 2026-09-29
Size, counts, category ids/names, +08:00 time and subtitle were correct.

Request restraint:
- site definitions may carry umt.defaults; merged with settings.sites
  (longer intervals, fewer pages): new settings defaultSnapshotMaxPages 1,
  defaultHealthCheckIntervalSec 6 h, defaultDetailCacheSec 24 h; default
  burst 2. HHClub: snapshot 60 min page 1 only, health 6 h, search
  concurrency 1, detail cache 24 h, 1 token / 3 s burst 2
- periodic / manual snapshots are capped to that page count; scheduled
  health checks skip sites checked within the interval; detail refresh is
  served from cache inside the window; live searches on one site queue
- every rate-limiter token is counted per site per hour
  (site_request_count, migration 0046); GET /sites/{id}/request-stats;
  site overview and resource list show requests in the last 24 hours

Resource list: two-layer rows. Main line: title + spec tags (episodes,
resolution, source, codec, HDR, group, 国语/中字, site tags) + promotion
with time left + H&R. Second line: subtitle (one line, ellipsis) and
fixed-width category / size / seed-leech-snatched / upload time
(relative, absolute on hover) columns, stale badge, inventory overlay;
folds into a card on phones.

Also aligns identity_candidate.normalized_title order in db types with
the migrations (schema drift test).

Takes effect after the stack is rebuilt (migration 0046).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 15:18:15 +08:00
rootandClaude Fable 5.1 ac478673bc docs(plan): on-demand site detail page parsing (HHClub details.php)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 15:13:35 +08:00
rootandClaude Opus 5.5 94fd48bff2 feat(identity): lazy TMDB lookup and bounded identity pool (DEC-1)
RSS/list releases that match no subscription or local work no longer hit
TMDB or open a pending item; they go to the identity pool as `unmatched`.
TMDB is queried only on a local alias hit, a published new-title rule whose
prefilter passes, manual/Agent retry, search results, or when the new
setting identity.eagerTmdbLookup (default off) is on. Mirrors MoviePilot:
torrents are recognised only when matched to a subscription or searched,
and recognition failures are logged, not alerted.

- Pending items only for related releases (ambiguous after lookup, or
  related to a local work but unresolved); same source + normalized title
  merge into one decision ("来源「X」的 N 条资源待识别"), resolve/dismiss
  applies to the whole group, members detach as they get resolved.
- Pool governance: unmatched reviews capped (daily, 3x), title_alias
  insert trigger wakes similar entries, stale unmatched entries archived
  after identity.poolArchiveDays (30); review idempotency keys include the
  due time.
- Migration 0047_identity_pool: reason/outcome `unmatched`,
  identity_candidate.normalized_title (+trgm index), wake trigger, and
  cleanup of open identity_unresolved items with no related work
  (dismissed, resolution=moved_to_pool).
- Inbox: group by type + work/source with collapse, hide info-only items
  by default (minSeverity=warning), badge counts warning+ only; pool sheet
  gets manual TMDB/local-work assign and dismiss; settings card for the
  new identity settings.
- Runbook docs/runbook/identity.md.

Requires rebuild/restart (migration runs on start).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 15:05:39 +08:00
rootandClaude Fable 5.1 524af64bec docs(plan): unified credentials injected into browser sessions (BR-2)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 14:47:03 +08:00
rootandClaude Fable 5.1 3e59cb4f41 docs(plan): agent drawer history and session layout polish (AGUI-2)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 14:43:52 +08:00
rootandClaude Opus 5.5 4a92dfd2dc feat(feeds): site-scoped RSS add infers account, parser and poll
Adding a feed from a site page now only asks for the URL, purpose
(discover / track / promotion) and an optional note. POST /feed-sources
with siteId infers the site account (passkey holder first), records the
site definition version as parserVersion, defaults the name to
"<site> RSS" and polling to 30 minutes, and returns non-blocking
warnings when the URL host does not match the site. The dialog shows the
redacted URL, fetches once right after saving and reports the item count
or the error.

The generic feed form on the sources page suggests linking a registered
site when the URL host matches (can be undone). name is now optional.

Takes effect after the stack is rebuilt.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 14:43:19 +08:00
rootandClaude Fable 5.1 00ebdda7ed docs(plan): self-enrichment for titles missing on TMDB (META-1)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 14:40:55 +08:00
rootandClaude Fable 5.1 b8e3cbf689 docs(plan): inbox flood root cause and lazy identification decision (DEC-1)
Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-09-29 14:33:03 +08:00