import json import tomllib from pathlib import Path from phase_memory.cli import main FIXTURES = Path(__file__).parent / "fixtures" ROOT = Path(__file__).resolve().parents[1] def test_pyproject_exposes_phase_memory_console_script() -> None: pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8")) assert pyproject["project"]["scripts"]["phase-memory"] == "phase_memory.cli:main" def test_cli_profile_plan_emits_json(capsys) -> None: code = main(["profile", "plan", str(FIXTURES / "memory-profile.json")]) output = json.loads(capsys.readouterr().out) assert code == 0 assert output["operation"] == "profile.plan" assert output["data"]["plan"]["ready"] is True def test_cli_graph_lifecycle_emits_dry_run_actions(capsys) -> None: code = main( [ "graph", "lifecycle", str(FIXTURES / "memory-graph.json"), "--stale-after-days", "7", "--delete-after-days", "30", "--refresh-digest", "event.restart=new", "--compact-node", "event.restart", ] ) output = json.loads(capsys.readouterr().out) assert code == 0 assert output["operation"] == "graph.lifecycle.plan" assert [action["action"] for action in output["data"]["dry_run_actions"]][:2] == ["mark_stale", "refresh"] def test_cli_graph_lifecycle_can_use_profile_rules(capsys) -> None: code = main( [ "graph", "lifecycle", str(FIXTURES / "memory-graph.json"), "--profile", str(FIXTURES / "memory-profile.json"), "--refresh-digest", "event.restart=new", ] ) output = json.loads(capsys.readouterr().out) actions = {(action["target_id"], action["action"]) for action in output["data"]["dry_run_actions"]} assert code == 0 assert output["operation"] == "graph.lifecycle.plan" assert output["data"]["profile_id"] == "phase-memory-fixture-profile" assert output["data"]["rule_config"]["retention_default"]["stale_after_days"] == 7 assert ("event.restart", "mark_stale") in actions assert ("event.restart", "refresh") in actions def test_cli_graph_activate_emits_selection(capsys) -> None: code = main( [ "graph", "activate", str(FIXTURES / "memory-graph.json"), "--max-items", "2", "--max-tokens", "18", "--profile-id", "phase-memory-fixture-profile", "--priority-node", "decision.boundary", ] ) output = json.loads(capsys.readouterr().out) assert code == 0 assert output["operation"] == "graph.activation.plan" assert output["data"]["activation_plan"]["selection"]["profile"] == "phase-memory-fixture-profile" def test_cli_summary_format_is_concise(capsys) -> None: code = main(["profile", "plan", str(FIXTURES / "memory-profile.json"), "--format", "summary"]) output = capsys.readouterr().out assert code == 0 assert "profile.plan memory_profile:phase-memory-fixture-profile" in output assert "ready=true" in output def test_cli_store_import_export_and_repair(tmp_path, capsys) -> None: store = tmp_path / "memory-store" import_code = main( [ "store", "import", "--store", str(store), "--profile", str(FIXTURES / "memory-profile.json"), "--graph", str(FIXTURES / "memory-graph.json"), ] ) imported = json.loads(capsys.readouterr().out) export_code = main(["store", "export", "--store", str(store), "--graph-id", "cli-export"]) exported = json.loads(capsys.readouterr().out) repair_code = main(["store", "repair", "--store", str(store)]) repair = json.loads(capsys.readouterr().out) assert import_code == 0 assert imported["operation"] == "store.import" assert (store / "phase-memory.json").exists() assert export_code == 0 assert exported["data"]["graph"]["id"] == "cli-export" assert len(exported["data"]["graph"]["nodes"]) == 4 assert repair_code == 0 assert repair["data"]["diagnostic_count"] == 0