diff --git a/skills/bmad-story-automator/src/story_automator/core/utils.py b/skills/bmad-story-automator/src/story_automator/core/utils.py index f5cb36ad..8c13eab7 100644 --- a/skills/bmad-story-automator/src/story_automator/core/utils.py +++ b/skills/bmad-story-automator/src/story_automator/core/utils.py @@ -123,7 +123,9 @@ def get_project_root() -> str: def get_project_slug(project_root: str | None = None) -> str: - root = Path(project_root or get_project_root()) + # Resolve before .name so a relative root like "." (whose Path(".").name is "") + # doesn't collapse to the generic "project" fallback. Mirrors get_project_hash(). + root = Path(project_root or get_project_root()).resolve() value = re.sub(r"[^a-z0-9]", "", root.name.lower())[:8] return value or "project" diff --git a/tests/test_project_slug.py b/tests/test_project_slug.py new file mode 100644 index 00000000..f161a554 --- /dev/null +++ b/tests/test_project_slug.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +import os +import tempfile +import unittest +from contextlib import contextmanager +from pathlib import Path + +from story_automator.core.utils import get_project_slug + + +@contextmanager +def chdir(path: str): + prev = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(prev) + + +class GetProjectSlugTests(unittest.TestCase): + def test_absolute_root_uses_dir_name(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + target = Path(tmp) / "upmon-automator" + target.mkdir() + self.assertEqual(get_project_slug(str(target)), "upmonaut") + + def test_relative_dot_resolves_instead_of_collapsing_to_generic(self) -> None: + # Regression: `Path(".").name == ""` previously collapsed to "project". + with tempfile.TemporaryDirectory() as tmp: + target = Path(tmp) / "myproject" + target.mkdir() + with chdir(str(target)): + self.assertEqual(get_project_slug("."), "myprojec") + + def test_empty_name_still_falls_back_to_project(self) -> None: + # A root that resolves to a non-alphanumeric name keeps the safe default. + with tempfile.TemporaryDirectory() as tmp: + target = Path(tmp) / "___" + target.mkdir() + self.assertEqual(get_project_slug(str(target)), "project") + + +if __name__ == "__main__": + unittest.main()