Files
Salon_Assistant/skills/setup-education/scripts/build_capability_report.py
T
Ty 76df8b7ab6 Implement E1 setup-education and capability report (fixtures).
Add owner-safe lesson catalog, fixture-backed capability statuses, CLI, and unit tests without live OAuth or connect scripts.
2026-07-27 13:10:57 -07:00

115 lines
3.1 KiB
Python

#!/usr/bin/env python3
"""Build a capability report from setup fixtures.
Usage:
python build_capability_report.py [--fixtures PATH] [--salon NAME] [--format text|json]
All data is labeled as fixture/offline — never silent fake live data.
"""
from __future__ import annotations
import argparse
import json
import pathlib
import sys
# Ensure the _lib package is importable regardless of cwd.
_REPO_ROOT = pathlib.Path(__file__).resolve().parents[3]
sys.path.insert(0, str(_REPO_ROOT / "skills" / "_lib"))
from lumina_skills.providers.setup.fixture_provider import (
load_capability_fixture,
load_fixture_metadata,
)
from lumina_skills.setup.capability_report import format_capability_report_text
from lumina_skills.setup.lesson_catalog import (
format_all_lessons_text,
format_lesson_text,
get_lesson,
get_all_lessons,
)
# Default fixture: Claire Bennett demo capability matrix.
_DEFAULT_FIXTURE = _REPO_ROOT / "data" / "fixtures" / "setup" / "capability_matrix.json"
def main() -> int:
parser = argparse.ArgumentParser(
description="Build a capability report from setup fixture data.",
)
parser.add_argument(
"--fixtures",
type=pathlib.Path,
default=_DEFAULT_FIXTURE,
help="Path to capability fixture JSON file.",
)
parser.add_argument(
"--salon",
type=str,
default=None,
help="Override salon name.",
)
parser.add_argument(
"--format",
choices=["text", "json"],
default="text",
help="Output format (default: text).",
)
parser.add_argument(
"--lesson",
type=int,
default=None,
help="Show a specific setup lesson (1-7) instead of the capability report.",
)
parser.add_argument(
"--all-lessons",
action="store_true",
help="Show all setup lessons instead of the capability report.",
)
args = parser.parse_args()
# Lesson mode.
if args.lesson is not None:
lesson = get_lesson(args.lesson)
if lesson is None:
print(f"Error: No lesson found for step {args.lesson}", file=sys.stderr)
return 1
print(format_lesson_text(lesson))
return 0
if args.all_lessons:
print(format_all_lessons_text())
return 0
# Capability report mode.
try:
report = load_capability_fixture(args.fixtures)
except FileNotFoundError as exc:
print(f"Error: {exc}", file=sys.stderr)
return 1
except (json.JSONDecodeError, KeyError, ValueError) as exc:
print(f"Error parsing fixture: {exc}", file=sys.stderr)
return 1
# Override salon name if requested.
if args.salon:
from lumina_skills.setup.capability_report import build_capability_report
report = build_capability_report(
capabilities=report.capabilities,
salon_name=args.salon,
is_fixture=report.is_fixture,
)
# Output.
if args.format == "json":
print(json.dumps(report.to_dict(), indent=2))
else:
print(format_capability_report_text(report))
return 0
if __name__ == "__main__":
raise SystemExit(main())