e4dcfc49aa
Tests / Lint and Format (push) Waiting to run
Tests / Web Node Tests (push) Waiting to run
Tests / Import Check (Python 3.11) (push) Waiting to run
Tests / Import Check (Python 3.12) (push) Waiting to run
Tests / Import Check (Python 3.13) (push) Waiting to run
Tests / Import Check (Python 3.14) (push) Waiting to run
Tests / Python Tests (Python 3.11) (push) Blocked by required conditions
Tests / Python Tests (Python 3.12) (push) Blocked by required conditions
Tests / Python Tests (Python 3.13) (push) Blocked by required conditions
Tests / Python Tests (Python 3.14) (push) Blocked by required conditions
Tests / Test Summary (push) Blocked by required conditions
62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
"""``deeptutor book ...`` CLI commands for the new BookEngine.
|
|
|
|
Currently exposes maintenance commands. (Authoring/reading still goes through
|
|
the API + web frontend.)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
import typer
|
|
|
|
from .common import console
|
|
|
|
|
|
def register(app: typer.Typer) -> None:
|
|
@app.command("list")
|
|
def list_books() -> None:
|
|
"""List all books in the local workspace."""
|
|
from deeptutor.book import get_book_engine
|
|
|
|
engine = get_book_engine()
|
|
books = engine.list_books()
|
|
if not books:
|
|
console.print("[yellow]No books yet.[/yellow]")
|
|
return
|
|
for book in books:
|
|
stale = len(book.stale_page_ids or [])
|
|
stale_label = f" [red]({stale} stale)[/red]" if stale else ""
|
|
console.print(
|
|
f"[bold]{book.title or '(untitled)'}[/bold] "
|
|
f"[dim]{book.id}[/dim] "
|
|
f"[cyan]{book.status.value}[/cyan]"
|
|
f"{stale_label}"
|
|
)
|
|
|
|
@app.command("health")
|
|
def health(
|
|
book_id: str = typer.Argument(..., help="Book id."),
|
|
) -> None:
|
|
"""Inspect KB drift + log.md health for a book."""
|
|
from deeptutor.book import get_book_engine
|
|
|
|
engine = get_book_engine()
|
|
drift = engine.kb_drift_report(book_id)
|
|
log = engine.log_health(book_id)
|
|
console.print_json(json.dumps({"kb_drift": drift, "log_health": log}))
|
|
|
|
@app.command("refresh-fingerprints")
|
|
def refresh_fingerprints(
|
|
book_id: str = typer.Argument(..., help="Book id."),
|
|
) -> None:
|
|
"""Re-snapshot KB fingerprints; clears the stale-page list."""
|
|
from deeptutor.book import get_book_engine
|
|
|
|
engine = get_book_engine()
|
|
result = engine.refresh_kb_fingerprints(book_id)
|
|
if result is None:
|
|
console.print(f"[red]Book {book_id} not found.[/red]")
|
|
raise typer.Exit(code=1)
|
|
console.print_json(json.dumps(result))
|