diff --git a/backend/apps/swarm/entities/skills.py b/backend/apps/swarm/entities/skills.py index 69ea854e..e223e48f 100644 --- a/backend/apps/swarm/entities/skills.py +++ b/backend/apps/swarm/entities/skills.py @@ -25,12 +25,12 @@ class SkillExportable: @classmethod def load(cls, local_id: str) -> "SkillExportable | None": - md_path, kind = store._skill_md_path(local_id) + md_path, kind = store.p_skill_md_path(local_id) if not md_path: return None with open(md_path, encoding="utf-8") as f: content = f.read() - meta = store._load_index().get(local_id, {}) + meta = store.p_load_index().get(local_id, {}) name = meta.get("name") or local_id.replace("-", " ").replace("_", " ").title() payload = { "slug": local_id, @@ -90,10 +90,10 @@ class SkillExportable: shutil.rmtree(skill_dir, ignore_errors=True) if os.path.isfile(flat): os.remove(flat) - index = store._load_index() + index = store.p_load_index() if local_id in index: index.pop(local_id, None) - store._save_index(index) + store.p_save_index(index) def p_read_supporting_files(skill_dir: str) -> dict[str, bytes]: @@ -115,7 +115,7 @@ def p_read_supporting_files(skill_dir: str) -> dict[str, bytes]: def p_slug_taken(slug: str) -> bool: return ( - slug in store._load_index() + slug in store.p_load_index() or os.path.isfile(os.path.join(store.SKILLS_DIR, f"{slug}.md")) or os.path.isdir(os.path.join(store.SKILLS_DIR, slug)) ) diff --git a/backend/tests/test_skill_registry_seed.py b/backend/tests/test_skill_registry_seed.py index a30d73c8..37115a34 100644 --- a/backend/tests/test_skill_registry_seed.py +++ b/backend/tests/test_skill_registry_seed.py @@ -16,8 +16,8 @@ from backend.apps.skill_registry import skill_registry as sr def test_bundled_snapshot_exists_and_includes_pdf(): # The onboarding step targets the "pdf" skill via /pdf/i; it must be present # in the shipped snapshot or the tour times out even with a populated list. - assert os.path.exists(sr._BUNDLED_SNAPSHOT) - data = json.load(open(sr._BUNDLED_SNAPSHOT, encoding="utf-8")) + assert os.path.exists(sr.P_BUNDLED_SNAPSHOT) + data = json.load(open(sr.P_BUNDLED_SNAPSHOT, encoding="utf-8")) assert isinstance(data, dict) and len(data) >= 10 assert any("pdf" in k.lower() or "pdf" in v.get("folder", "").lower() for k, v in data.items()) @@ -27,7 +27,7 @@ def test_seed_makes_catalog_non_empty_offline(monkeypatch, tmp_path): # Point the disk cache at an empty tmp dir so only the bundled snapshot can # seed; this is the brand-new-install, no-network case. monkeypatch.setenv("OPENSWARM_SKILL_CACHE_DIR", str(tmp_path)) - seeded = sr._load_seed_cache() + seeded = sr.p_load_seed_cache() assert len(seeded) >= 10 sr.CACHE = seeded @@ -41,6 +41,6 @@ def test_disk_cache_roundtrip_and_priority(monkeypatch, tmp_path): sentinel = {"only-skill": {"name": "only-skill", "description": "", "content": "", "folder": "skills/only-skill", "category": "Test", "repositoryUrl": ""}} - sr._save_disk_cache(sentinel) - assert os.path.exists(sr._disk_cache_path()) - assert sr._load_seed_cache() == sentinel + sr.p_save_disk_cache(sentinel) + assert os.path.exists(sr.p_disk_cache_path()) + assert sr.p_load_seed_cache() == sentinel diff --git a/backend/tests/test_skills_folders.py b/backend/tests/test_skills_folders.py index f6de636e..39b35d3d 100644 --- a/backend/tests/test_skills_folders.py +++ b/backend/tests/test_skills_folders.py @@ -37,28 +37,28 @@ def test_corrupt_index_does_not_brick_skills_and_is_preserved(skills_dir): with open(skills_dir / ".skills_index.json", "w") as f: f.write("{ not valid json") # Load returns empty instead of raising, and moves the bad file aside. - assert skills_mod._load_index() == {} + assert skills_mod.p_load_index() == {} assert (skills_dir / ".skills_index.json.corrupt").exists() # Skills still list (name falls back to the filename), so nothing is bricked. - assert "alpha" in {s.id for s in skills_mod._sync_skills()} + assert "alpha" in {s.id for s in skills_mod.sync_skills()} def test_non_object_index_is_rejected(skills_dir): with open(skills_dir / ".skills_index.json", "w") as f: f.write("[1, 2, 3]") - assert skills_mod._load_index() == {} + assert skills_mod.p_load_index() == {} def test_save_index_is_atomic_no_temp_leftover(skills_dir): - skills_mod._save_index({"x": {"name": "X"}}) - assert skills_mod._load_index() == {"x": {"name": "X"}} + skills_mod.p_save_index({"x": {"name": "X"}}) + assert skills_mod.p_load_index() == {"x": {"name": "X"}} leftovers = [n for n in __import__("os").listdir(skills_dir) if n.startswith(".skills_index.") and n.endswith(".tmp")] assert leftovers == [] def test_flat_skill_still_syncs(skills_dir): _write(str(skills_dir / "my-flat.md"), "do the flat thing") - skills = {s.id: s for s in skills_mod._sync_skills()} + skills = {s.id: s for s in skills_mod.sync_skills()} assert "my-flat" in skills s = skills["my-flat"] assert s.content == "do the flat thing" @@ -70,7 +70,7 @@ def test_folder_skill_syncs_with_supporting_files(skills_dir): base = skills_dir / "remotion" _write(str(base / "SKILL.md"), "---\nname: Remotion\ndescription: make videos\n---\nrender stuff") _write(str(base / "helper.py"), "print('hi')") - skills = {s.id: s for s in skills_mod._sync_skills()} + skills = {s.id: s for s in skills_mod.sync_skills()} assert "remotion" in skills s = skills["remotion"] assert "render stuff" in s.content @@ -84,7 +84,7 @@ def test_folder_skill_syncs_with_supporting_files(skills_dir): def test_folder_skill_without_extra_files_flags_false(skills_dir): base = skills_dir / "solo" _write(str(base / "SKILL.md"), "just one file") - s = {x.id: x for x in skills_mod._sync_skills()}["solo"] + s = {x.id: x for x in skills_mod.sync_skills()}["solo"] assert s.dir_path == str(base) assert s.has_supporting_files is False @@ -177,7 +177,7 @@ def test_swarm_import_writes_folder_when_files_present(skills_dir): new_id = SkillExportable.import_(payload, {"scripts/go.py": b"print(1)"}, None) assert os.path.isfile(skills_dir / new_id / "SKILL.md") assert os.path.isfile(skills_dir / new_id / "scripts" / "go.py") - synced = {s.id: s for s in skills_mod._sync_skills()} + synced = {s.id: s for s in skills_mod.sync_skills()} assert synced[new_id].has_supporting_files is True @@ -203,7 +203,7 @@ async def test_create_writes_folder_and_supersedes_legacy_flat(skills_dir): assert sid == "notes" assert os.path.isfile(skills_dir / "notes" / "SKILL.md") assert not (skills_dir / "notes.md").exists() - only = [s for s in skills_mod._sync_skills() if s.id == "notes"] + only = [s for s in skills_mod.sync_skills() if s.id == "notes"] assert len(only) == 1 and only[0].content == "new body" diff --git a/backend/tests/test_swarm_bundle.py b/backend/tests/test_swarm_bundle.py index 4c061556..ac4e02ab 100644 --- a/backend/tests/test_swarm_bundle.py +++ b/backend/tests/test_swarm_bundle.py @@ -27,9 +27,9 @@ def skill_store(tmp_path, monkeypatch): def _make_skill(d, slug, name, content, description="desc"): (d / f"{slug}.md").write_text(content, encoding="utf-8") - index = store._load_index() + index = store.p_load_index() index[slug] = {"name": name, "description": description, "command": slug} - store._save_index(index) + store.p_save_index(index) def test_skill_export_import_round_trip(skill_store): @@ -506,7 +506,7 @@ def test_skill_rollback_removes_it(skill_store): assert (skill_store / sid / "SKILL.md").exists() SkillExportable.rollback(sid) assert not (skill_store / sid).exists() - assert sid not in store._load_index() + assert sid not in store.p_load_index() def test_commit_rolls_back_created_on_failure(skill_store, tmp_path): @@ -527,7 +527,7 @@ def test_commit_rolls_back_created_on_failure(skill_store, tmp_path): ) with pytest.raises(BundleError): closure.commit(str(sb), manifest, []) - assert "rollme" not in store._load_index() + assert "rollme" not in store.p_load_index() assert not (skill_store / "rollme").exists() # the imported folder was rolled back