refactor: DLO-16/17/18/20 — CLI simplification, config Pydantic, planner split, type system unification

DLO-16: Reduce cli.py from 1073 to 83 lines by registering Click commands from commands/*.py modules
DLO-17: Migrate Config to Pydantic BaseModel for validation
DLO-18: Split planner.py (826 lines) into orchestration, path rendering, and duplicate handling modules
DLO-20: Unify type system — convert 14 dataclasses to Pydantic BaseModel, keep TypedDicts as JSON schema hints

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
windyboy
2026-09-27 10:47:04 +08:00
co-authored by Claude Sonnet 4.5
parent 8a60aaf9a9
commit fe03a31dd4
23 changed files with 1964 additions and 2714 deletions
+15 -1
View File
@@ -7,7 +7,8 @@ from typing import Optional
import click
from vlm.context import CLIContext
from vlm.cli_helpers import default_artifact_path, resolve_legacy_default_input_path, run_command
from vlm.context import CLIContext, pass_context
from vlm.io import load_inventory_csv, save_identities_json
from vlm.models import (
IdentityRecord,
@@ -170,3 +171,16 @@ def parse_cmd(ctx: CLIContext, input: Path, output: Path, inventory: Optional[Pa
len(series_identities),
output,
)
@click.command()
@click.option("--input", type=click.Path(path_type=Path), default=lambda: default_artifact_path("inventory.csv"))
@click.option("--output", type=click.Path(path_type=Path), default=lambda: default_artifact_path("identities.json"))
@click.option("--inventory", type=click.Path(exists=True, path_type=Path), default=None)
@pass_context
def parse(ctx: CLIContext, input: Path, output: Path, inventory: Optional[Path]):
"""Parse identities from filenames."""
def _run():
input_resolved = resolve_legacy_default_input_path(input, "input", "inventory.csv", "--input")
parse_cmd(ctx, input_resolved, output, inventory)
run_command(ctx, _run, stage="parse", json_errors=True)