from __future__ import annotations import importlib.util import json import sys from pathlib import Path SCRIPT_PATH = ( Path(__file__).resolve().parents[2] / "optional-skills" / "migration" / "openclaw-migration" / "scripts" / "openclaw_to_hermes.py" ) def load_module(): spec = importlib.util.spec_from_file_location("openclaw_to_hermes", SCRIPT_PATH) module = importlib.util.module_from_spec(spec) assert spec.loader is not None sys.modules[spec.name] = module spec.loader.exec_module(module) return module def test_extract_markdown_entries_promotes_heading_context(): mod = load_module() text = """# MEMORY.md - Long-Term Memory ## Tyler Williams - Founder of VANTA Research - Timezone: America/Los_Angeles ### Active Projects - Hermes Agent """ entries = mod.extract_markdown_entries(text) assert "Tyler Williams: Founder of VANTA Research" in entries assert "Tyler Williams: Timezone: America/Los_Angeles" in entries assert "Tyler Williams > Active Projects: Hermes Agent" in entries def test_merge_entries_respects_limit_and_reports_overflow(): mod = load_module() existing = ["alpha"] incoming = ["beta", "gamma is too long"] merged, stats, overflowed = mod.merge_entries(existing, incoming, limit=12) assert merged == ["alpha", "beta"] assert stats["added"] == 1 assert stats["overflowed"] == 1 assert overflowed == ["gamma is too long"] def test_migrator_copies_skill_and_merges_allowlist(tmp_path: Path): mod = load_module() source = tmp_path / ".openclaw" target = tmp_path / ".hermes" (source / "workspace" / "skills" / "demo-skill").mkdir(parents=True) (source / "workspace" / "skills" / "demo-skill" / "SKILL.md").write_text( "---\nname: demo-skill\ndescription: demo\n---\n\nbody\n", encoding="utf-8", ) (source / "exec-approvals.json").write_text( json.dumps( { "agents": { "*": { "allowlist": [ {"pattern": "/usr/bin/*"}, {"pattern": "/home/test/**"}, ] } } } ), encoding="utf-8", ) (target / "config.yaml").write_text("command_allowlist:\n - /usr/bin/*\n", encoding="utf-8") migrator = mod.Migrator( source_root=source, target_root=target, execute=True, workspace_target=None, overwrite=False, migrate_secrets=False, output_dir=target / "migration-report", ) report = migrator.migrate() imported_skill = target / "skills" / mod.SKILL_CATEGORY_DIRNAME / "demo-skill" / "SKILL.md" assert imported_skill.exists() assert "/home/test/**" in (target / "config.yaml").read_text(encoding="utf-8") assert report["summary"]["migrated"] >= 2 def test_migrator_optionally_imports_supported_secrets_and_messaging_settings(tmp_path: Path): mod = load_module() source = tmp_path / ".openclaw" target = tmp_path / ".hermes" (source / "credentials").mkdir(parents=True) (source / "openclaw.json").write_text( json.dumps( { "agents": {"defaults": {"workspace": "/tmp/openclaw-workspace"}}, "channels": {"telegram": {"botToken": "123:abc"}}, } ), encoding="utf-8", ) (source / "credentials" / "telegram-default-allowFrom.json").write_text( json.dumps({"allowFrom": ["111", "222"]}), encoding="utf-8", ) target.mkdir() migrator = mod.Migrator( source_root=source, target_root=target, execute=True, workspace_target=None, overwrite=False, migrate_secrets=True, output_dir=target / "migration-report", ) migrator.migrate() env_text = (target / ".env").read_text(encoding="utf-8") assert "MESSAGING_CWD=/tmp/openclaw-workspace" in env_text assert "TELEGRAM_ALLOWED_USERS=111,222" in env_text assert "TELEGRAM_BOT_TOKEN=123:abc" in env_text