Files
mytoolkit/bin/commands/preflight.py
T
Zhengshou Lai 3e4cf618a8 refactor: restructure mytoolkit with new subcommands and md-to-pdf improvements
- Add new subcommands: convert, preflight, server, templates, webpage
- Migrate config from bin/config.json to ~/.config/mytoolkit
- Fix expand_bookmarks to modify writer objects instead of reader
- Improve md_to_pdf with CJK bookmark support
- Update README and project metadata
2026-05-04 17:19:32 +08:00

120 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Pre-flight check for work-order consistency and system health."""
import json
import os
import re
import sys
from pathlib import Path
import click
@click.command(name="preflight")
def preflight_cmd():
"""Run pre-flight checks before executing work orders."""
issues = []
warnings = []
click.secho("Running pre-flight checks...", fg="cyan")
click.echo("")
# === Check 1: work-order.md vs checkpoint JSON consistency ===
work_order = Path.home() / "workspace/assistant/work-order.md"
if work_order.exists():
content = work_order.read_text()
# Find progress numbers like "进度: X/Y 步骤"
progress_match = re.search(r"进度[:]\s*(\d+)/(\d+)\s*步骤", content)
if progress_match:
wo_current = int(progress_match.group(1))
wo_total = int(progress_match.group(2))
# Find checkpoint files referenced in work-order
cp_match = re.search(r"进度档[:]\s*(\S+)", content)
if cp_match:
cp_path = Path.home() / "workspace" / cp_match.group(1)
if cp_path.exists():
try:
cp = json.loads(cp_path.read_text())
cp_current = cp.get("currentStep", 0)
cp_total = cp.get("totalSteps", 0)
cp_completed = len(cp.get("completedSteps", []))
if wo_current != cp_current or wo_total != cp_total:
issues.append(
f"进度不一致: 工作单 {wo_current}/{wo_total} vs 进度档 {cp_current}/{cp_total}"
)
elif cp_current != cp_completed + 1 and cp_current <= cp_total:
# currentStep should be next step to do (completed + 1)
# unless all completed
pass
except json.JSONDecodeError:
warnings.append(f"进度档 JSON 损坏: {cp_path}")
# Check for duplicate step numbers in step list
step_lines = re.findall(r"-\s*\[[x ]\]\s*\d+\.", content)
step_nums = []
for line in step_lines:
m = re.search(r"(\d+)\.", line)
if m:
step_nums.append(int(m.group(1)))
seen = set()
for num in step_nums:
if num in seen:
issues.append(f"步骤 {num} 在清单中重复出现")
seen.add(num)
# Check for gaps in step numbering
if step_nums:
expected = list(range(1, max(step_nums) + 1))
missing = [n for n in expected if n not in seen]
if missing:
warnings.append(f"步骤编号缺失: {missing}")
else:
warnings.append("工作单文件不存在")
# === Check 2: .zshrc PATH references ===
zshrc = Path.home() / ".zshrc"
if zshrc.exists():
zshrc_content = zshrc.read_text()
# Find paths in PATH exports (lines starting with export PATH=)
for line in zshrc_content.splitlines():
if not line.strip().startswith("export PATH="):
continue
refs = re.findall(r"/Users/\S+", line)
for ref in refs:
full_path = Path(ref).expanduser()
if not full_path.exists():
issues.append(f".zshrc PATH 引用失效: {ref}")
else:
warnings.append(".zshrc 不存在")
# === Check 3: Workspace symlink health ===
workspace = Path.home() / "workspace"
if workspace.exists():
for item in workspace.iterdir():
if item.is_symlink():
if not item.exists():
issues.append(f"符号链接失效: {item.name} -> {os.readlink(item)}")
# === Report ===
click.echo("-" * 50)
if issues:
click.secho(f"发现 {len(issues)} 个问题:", fg="red")
for issue in issues:
click.secho(f" [x] {issue}", fg="red")
else:
click.secho("未发现严重问题", fg="green")
if warnings:
click.secho(f"\n{len(warnings)} 个警告:", fg="yellow")
for w in warnings:
click.secho(f" [!] {w}", fg="yellow")
click.echo("-" * 50)
if issues:
sys.exit(1)