lllin000_PaperForge/paperforge/commands/deep.py
Research Assistant 05629bce82 refactor: v2.1 contract hardening — PFResult unification, ErrorCode expansion, adapter cleanup, SyncService orchestration
Core contract:
- ErrorCode: 8→26 with _missing_() graceful degradation for unknown codes
- PFResult: +warnings/next_actions, PFError: +suggestions
- OcrStatus: 4→9 granular states (NONE/QUEUED/BLOCKED/NO_PDF/DONE_INCOMPLETE restored 1:1)
- field_registry.yaml: +owner/deprecated/replacement/enum values/default

Adapter cleanup:
- new core/io.py (read_json/write_json), core/date_utils.py (extract_year)
- new adapters/collections.py (build_collection_lookup)
- adapters/bbt.py: cut worker dependency, _private→public+alias
- worker/_utils.py + _domain.py: re-export from core instead of duplicate defs

Command unification:
- All 6 commands (sync/status/ocr/deep/repair/dashboard) → PFResult
- cli.py --json dest unified to 'json' (was json_output on status/doctor)
- commands/sync.py → SyncService (no more int/dict/PFResult mixing)

Service hardening:
- SyncService.run() orchestrates full sync lifecycle (select→index→clean)
- cleanup loops (orphaned records, flat notes) migrated from worker
- worker/sync.py: freeze line + services→worker one-way dependency
- plugin/main.js: formal-library.json fallback deprecation warning

Verification: 181/181 tests, 0 new lint errors
2026-05-09 22:20:07 +08:00

77 lines
2.2 KiB
Python

"""Deep-reading queue command."""
import argparse
import logging
from pathlib import Path
from paperforge import __version__
from paperforge.core.result import PFResult
logger = logging.getLogger(__name__)
def _get_run_deep_reading():
"""Get run_deep_reading, preferring cli patches if available."""
try:
from paperforge.cli import run_deep_reading
if run_deep_reading is not None:
return run_deep_reading
except Exception:
pass
import sys
repo_root = Path(__file__).resolve().parent.parent.parent
if str(repo_root) not in sys.path:
sys.path.insert(0, str(repo_root))
from paperforge.worker.deep_reading import run_deep_reading
return run_deep_reading
def run(args: argparse.Namespace) -> int:
"""Run deep-reading queue check. Supports --json for PFResult output."""
vault = getattr(args, "vault_path", None)
if vault is None:
from paperforge.config import resolve_vault
vault = resolve_vault(cli_vault=getattr(args, "vault", None))
json_output = getattr(args, "json", False)
run_deep_reading = _get_run_deep_reading()
exit_code = run_deep_reading(vault, verbose=getattr(args, "verbose", False))
if json_output:
from paperforge.worker._utils import get_analyze_queue
queue = get_analyze_queue(vault)
ready = [r for r in queue if r.get("ocr_status") == "done"]
blocked = [r for r in queue if r.get("ocr_status") != "done"]
pf = PFResult(
ok=True,
command="deep-reading",
version=__version__,
data={
"queue": [
{
"zotero_key": r["zotero_key"],
"domain": r["domain"],
"title": r["title"],
"ocr_status": r.get("ocr_status", "pending"),
"ready": r.get("ocr_status") == "done",
}
for r in queue
],
"summary": {
"total": len(queue),
"ready": len(ready),
"blocked": len(blocked),
},
},
)
print(pf.to_json())
return 0
return exit_code