# ============================================================ # APS 主目录与目录化 Skill(对标 Codex ~/.codex) # ============================================================ from __future__ import annotations import json from pathlib import Path from server.agent_core.skills import SkillRegistry, reset_skills_registry from server.aps_home import ensure_aps_home, mode, skills_dir def test_ensure_home_layout(tmp_path, monkeypatch): monkeypatch.setenv("APS_HOME", str(tmp_path / "home")) monkeypatch.setenv("APS_MODE", "desktop") root = ensure_aps_home() assert root == (tmp_path / "home").resolve() for name in ("skills", "sessions", "data", "cache", "tmp", "logs"): assert (root / name).is_dir() assert (root / "config.json").exists() assert mode() == "desktop" def test_skills_directory_layout(tmp_path, monkeypatch): monkeypatch.setenv("APS_HOME", str(tmp_path / "home")) monkeypatch.delenv("APS_SKILLS_PATH", raising=False) monkeypatch.setenv("APS_MODE", "desktop") reset_skills_registry() reg = SkillRegistry() # 无 legacy path → 写到 ~/.aps/skills// assert reg.get("algo.stub") is not None folder = skills_dir() / "algo.stub" assert (folder / "manifest.json").exists() data = json.loads((folder / "manifest.json").read_text(encoding="utf-8")) assert data["skill_id"] == "algo.stub" # 再开一个 registry 应从目录扫回 reg2 = SkillRegistry() assert any(s["skill_id"] == "algo.stub" for s in reg2.list()) reset_skills_registry() def test_legacy_skills_file_still_works(tmp_path): path = tmp_path / "skills.json" path.write_text(json.dumps({"skills": [{ "skill_id": "algo.x", "name": "X", "endpoint": "local://stub", "enabled": True, "track": "flex", }]}), encoding="utf-8") reg = SkillRegistry(path=str(path)) assert reg.get("algo.x")["name"] == "X"