diff --git a/tests/test_setup_wizard.py b/tests/test_setup_wizard.py index a016b440..89b39de5 100644 --- a/tests/test_setup_wizard.py +++ b/tests/test_setup_wizard.py @@ -317,3 +317,143 @@ class TestEnvCheckerCheckJson: checker = EnvChecker(tmp_path) result = checker.check_json() assert result.passed is False + + +# =================================================================== +# Integration smoke tests for headless_setup +# =================================================================== + + +def test_headless_setup_claude_skill_directory(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """Claude Code uses skill_directory format - creates .claude/skills/literature-qa/ with scripts, prompts, chart-reading.""" + from paperforge.setup_wizard import headless_setup + import paperforge.setup_wizard as sw + + def patched_check_deps(self) -> CheckResult: + r = CheckResult("Dependencies") + r.passed = True + r.detail = "mocked" + return r + + monkeypatch.setattr(sw.EnvChecker, "check_dependencies", patched_check_deps) + + rv = headless_setup( + vault=tmp_path, + agent_key="claude", + system_dir="99_System", + resources_dir="03_Resources", + literature_dir="Literature", + control_dir="LiteratureControl", + base_dir="05_Bases", + skip_checks=True, + ) + + assert rv == 0, f"claude install failed with code {rv}" + skill_dir = tmp_path / ".claude" / "skills" / "literature-qa" + assert skill_dir.exists(), f"skill dir not created: {skill_dir}" + ld_deep = skill_dir / "scripts" / "ld_deep.py" + assert ld_deep.exists(), f"ld_deep.py not created: {ld_deep}" + prompt = skill_dir / "prompt_deep_subagent.md" + assert prompt.exists(), f"prompt not created: {prompt}" + chart_dir = skill_dir / "chart-reading" + assert chart_dir.exists(), f"chart-reading dir not created: {chart_dir}" + assert (chart_dir / "INDEX.md").exists(), "chart INDEX.md not created" + + +def test_headless_setup_opencode_flat_command(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """OpenCode uses flat_command format - creates .opencode/command/pf-deep.md.""" + from paperforge.setup_wizard import headless_setup + import paperforge.setup_wizard as sw + + def patched_check_deps(self) -> CheckResult: + r = CheckResult("Dependencies") + r.passed = True + r.detail = "mocked" + return r + + monkeypatch.setattr(sw.EnvChecker, "check_dependencies", patched_check_deps) + + rv = headless_setup( + vault=tmp_path, + agent_key="opencode", + system_dir="99_System", + resources_dir="03_Resources", + literature_dir="Literature", + control_dir="LiteratureControl", + base_dir="05_Bases", + skip_checks=True, + ) + + assert rv == 0, f"opencode install failed with code {rv}" + cmd_dir = tmp_path / ".opencode" / "command" + assert cmd_dir.exists(), f"command dir not created: {cmd_dir}" + pf_deep = cmd_dir / "pf-deep.md" + assert pf_deep.exists(), f"pf-deep.md not created: {pf_deep}" + pf_paper = cmd_dir / "pf-paper.md" + assert pf_paper.exists(), f"pf-paper.md not created: {pf_paper}" + + +def test_headless_setup_codex_skill_directory(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """Codex uses skill_directory format with $ prefix.""" + from paperforge.setup_wizard import headless_setup + import paperforge.setup_wizard as sw + + def patched_check_deps(self) -> CheckResult: + r = CheckResult("Dependencies") + r.passed = True + r.detail = "mocked" + return r + + monkeypatch.setattr(sw.EnvChecker, "check_dependencies", patched_check_deps) + + rv = headless_setup( + vault=tmp_path, + agent_key="codex", + system_dir="99_System", + resources_dir="03_Resources", + literature_dir="Literature", + control_dir="LiteratureControl", + base_dir="05_Bases", + skip_checks=True, + ) + + assert rv == 0, f"codex install failed with code {rv}" + skill_dir = tmp_path / ".codex" / "skills" / "literature-qa" + assert skill_dir.exists(), f"skill dir not created: {skill_dir}" + ld_deep = skill_dir / "scripts" / "ld_deep.py" + assert ld_deep.exists(), f"ld_deep.py not created: {ld_deep}" + prompt = skill_dir / "prompt_deep_subagent.md" + assert prompt.exists(), f"prompt not created: {prompt}" + + +def test_headless_setup_cline_rules_file(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + """Cline uses rules_file format - creates .clinerules directory with skill content.""" + from paperforge.setup_wizard import headless_setup + import paperforge.setup_wizard as sw + + def patched_check_deps(self) -> CheckResult: + r = CheckResult("Dependencies") + r.passed = True + r.detail = "mocked" + return r + + monkeypatch.setattr(sw.EnvChecker, "check_dependencies", patched_check_deps) + + rv = headless_setup( + vault=tmp_path, + agent_key="cline", + system_dir="99_System", + resources_dir="03_Resources", + literature_dir="Literature", + control_dir="LiteratureControl", + base_dir="05_Bases", + skip_checks=True, + ) + + assert rv == 0, f"cline install failed with code {rv}" + skill_dir = tmp_path / ".clinerules" + assert skill_dir.exists(), f".clinerules dir not created: {skill_dir}" + literature_qa = skill_dir / "literature-qa" + assert literature_qa.exists(), f"literature-qa subdir not created under .clinerules" + ld_deep = literature_qa / "scripts" / "ld_deep.py" + assert ld_deep.exists(), f"ld_deep.py not created under .clinerules"