Files
dl-organizer/src/vlm/plan_structure_preview.py
T
windyboyandCursor 5f0b531269 Improve plan review UX with enriched rows, TUI filters, and execute gate.
Make review-plan easier to act on: Chinese risk labels, relative paths,
verdict/next-step footer, optional identity/analysis enrichment, grouping,
spot-check sampling, and structure preview. Extend the TUI with filters,
duplicate-group reject, and quality context. Persist review_context on
plan operations and add --require-review for confirmed execute.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 09:27:12 +08:00

65 lines
2.0 KiB
Python

"""Build a target library tree preview from an execution plan."""
from __future__ import annotations
from collections import defaultdict
from pathlib import Path
from vlm.models import ExecutionPlan
from vlm.review_display import display_path
def build_structure_preview_lines(
plan: ExecutionPlan,
library_root: Path,
*,
max_titles: int = 40,
max_paths_per_title: int = 8,
) -> list[str]:
"""Return ASCII lines showing where move/rename operations will place files."""
by_title: dict[str, list[str]] = defaultdict(list)
for op in plan.operations:
if op.operation_type not in ("move", "rename") or not op.destination_path:
continue
ctx = op.review_context if isinstance(op.review_context, dict) else {}
title = str(ctx.get("title") or op.destination_path.parent.parent.name)
rel = display_path(op.destination_path, library_root)
by_title[title].append(rel)
lines = [
"Target library structure preview (move/rename destinations)",
f"Library root: {library_root}",
"",
]
if not by_title:
lines.append("(no move/rename destinations)")
return lines
sorted_titles = sorted(by_title.keys())[:max_titles]
for title in sorted_titles:
paths = sorted(set(by_title[title]))[:max_paths_per_title]
lines.append(f"{title}/")
for p in paths:
lines.append(f" {p}")
remaining = len(by_title[title]) - len(paths)
if remaining > 0:
lines.append(f" ... +{remaining} more path(s)")
lines.append("")
if len(by_title) > max_titles:
lines.append(f"... +{len(by_title) - max_titles} more title(s)")
return lines
def write_structure_preview(
plan: ExecutionPlan,
library_root: Path,
output_path: Path,
) -> None:
"""Write structure preview text to a file."""
lines = build_structure_preview_lines(plan, library_root)
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text("\n".join(lines) + "\n", encoding="utf-8")