Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README_agent.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Did I call pre_commit_instructions tool? I should do so now.
27 changes: 10 additions & 17 deletions remix_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,25 +215,18 @@ def get_project_default_output_dir(self):
return None, result['error'] or "Failed to get default directory from Remix API."

def derive_project_name_from_dir(self, remix_dir_path):
if not remix_dir_path: return "UnknownProject"
"""
Asks Stagecraft to guess the project name for a given directory.
"""
if not remix_dir_path:
return None
res = self.make_request("GET", "/stagecraft/project/name", params={"dir": remix_dir_path})
if not res.get("success"):
return None
Comment on lines +221 to +225
try:
path_norm = os.path.abspath(os.path.normpath(remix_dir_path))
parts = []
cursor = path_norm
for _ in range(6):
base = os.path.basename(cursor)
if base: parts.append(base)
parent = os.path.dirname(cursor)
if parent == cursor: break
cursor = parent

known_tail_names = {"textures", "painterconnector_ingested", "ingested", "captures", "assets", "output", "export"}
for name in parts:
if name.lower() not in known_tail_names and name:
return name
return res.get("data", {}).get("name")
except Exception:
pass
return "UnknownProject"
return None
Comment on lines +221 to +229

def get_material_from_mesh(self, mesh_prim_path):
if not mesh_prim_path: return None, "Mesh prim path cannot be empty."
Expand Down
29 changes: 26 additions & 3 deletions tests/test_remix_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
# in environments where requests is not installed (e.g. minimal CI images).
# remix_api treats requests as optional and guards all usage behind _get_session().
_req_mock = MagicMock()
_ConnErr = type("ConnectionError", (OSError,), {})
_Timeout = type("Timeout", (OSError,), {})
_ReqExc = type("RequestException", (OSError,), {})
_ConnErr = type("ConnectionError", (_ReqExc,), {})
_Timeout = type("Timeout", (_ReqExc,), {})
_req_mock.exceptions.RequestException = _ReqExc
_req_mock.exceptions.ConnectionError = _ConnErr
_req_mock.exceptions.Timeout = _Timeout
_req_mock.exceptions.RequestException = type("RequestException", (OSError,), {})
sys.modules.setdefault("requests", _req_mock)

sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
Expand Down Expand Up @@ -157,5 +158,27 @@ def test_ping_failure(self):
self.assertFalse(ok)



class TestDeriveProjectName(unittest.TestCase):
def test_derive_project_name_error_path(self):
client = _make_client()
with patch.object(client, "make_request", return_value={"success": False}):
name = client.derive_project_name_from_dir("/some/dir")
self.assertIsNone(name)

def test_derive_project_name_success(self):
client = _make_client()
with patch.object(client, "make_request", return_value={"success": True, "data": {"name": "TestProject"}}):
name = client.derive_project_name_from_dir("/some/dir")
self.assertEqual(name, "TestProject")
Comment on lines +163 to +173

def test_derive_project_name_empty_dir(self):
client = _make_client()
name = client.derive_project_name_from_dir(None)
self.assertIsNone(name)

name = client.derive_project_name_from_dir("")
self.assertIsNone(name)

Comment on lines +165 to +182
if __name__ == "__main__":
unittest.main()