Update recursive_context.py
Browse files- recursive_context.py +70 -17
recursive_context.py
CHANGED
|
@@ -704,37 +704,90 @@ class RecursiveContextManager:
|
|
| 704 |
# =====================================================================
|
| 705 |
# GIT TOOLS
|
| 706 |
# =====================================================================
|
| 707 |
-
|
| 708 |
-
"""
|
| 709 |
token = os.getenv("GITHUB_TOKEN")
|
| 710 |
repo = os.getenv("GITHUB_REPO")
|
| 711 |
-
|
| 712 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 713 |
try:
|
|
|
|
| 714 |
if not (self.repo_path / ".git").exists():
|
| 715 |
subprocess.run(["git", "init"], cwd=self.repo_path, check=True)
|
| 716 |
-
subprocess.run(["git", "
|
| 717 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 718 |
subprocess.run(["git", "add", "."], cwd=self.repo_path, check=True)
|
| 719 |
-
|
| 720 |
-
|
| 721 |
-
|
| 722 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 723 |
|
| 724 |
def pull_from_github(self, branch="main"):
|
| 725 |
"""Hard reset: Destroys local changes and pulls clean code from GitHub."""
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
|
| 730 |
try:
|
|
|
|
| 731 |
if not (self.repo_path / ".git").exists():
|
| 732 |
subprocess.run(["git", "init"], cwd=self.repo_path, check=True)
|
| 733 |
subprocess.run(["git", "remote", "add", "origin", remote_url], cwd=self.repo_path)
|
|
|
|
|
|
|
| 734 |
subprocess.run(["git", "fetch", "origin"], cwd=self.repo_path, check=True)
|
| 735 |
-
res = subprocess.run(
|
| 736 |
-
|
| 737 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 738 |
|
| 739 |
# =====================================================================
|
| 740 |
# WORKING MEMORY NOTEBOOK (Structured List)
|
|
|
|
| 704 |
# =====================================================================
|
| 705 |
# GIT TOOLS
|
| 706 |
# =====================================================================
|
| 707 |
+
def _get_authenticated_remote_url(self):
|
| 708 |
+
"""Helper to construct the correct authenticated URL."""
|
| 709 |
token = os.getenv("GITHUB_TOKEN")
|
| 710 |
repo = os.getenv("GITHUB_REPO")
|
| 711 |
+
|
| 712 |
+
if not token or not repo:
|
| 713 |
+
return None
|
| 714 |
+
|
| 715 |
+
# Clean the repo string if it's already a full URL
|
| 716 |
+
if repo.startswith("https://github.com/"):
|
| 717 |
+
repo = repo.replace("https://github.com/", "")
|
| 718 |
+
if repo.endswith(".git"):
|
| 719 |
+
repo = repo[:-4]
|
| 720 |
+
|
| 721 |
+
return f"https://{token}@github.com/{repo}.git"
|
| 722 |
+
|
| 723 |
+
def push_to_github(self, commit_message="Auto-backup from Clawdbot"):
|
| 724 |
+
"""Pushes the current workspace to the configured GitHub repository."""
|
| 725 |
+
remote_url = self._get_authenticated_remote_url()
|
| 726 |
+
if not remote_url:
|
| 727 |
+
return "❌ Error: GITHUB_TOKEN or GITHUB_REPO secret is missing."
|
| 728 |
+
|
| 729 |
try:
|
| 730 |
+
# 1. Initialize if needed
|
| 731 |
if not (self.repo_path / ".git").exists():
|
| 732 |
subprocess.run(["git", "init"], cwd=self.repo_path, check=True)
|
| 733 |
+
subprocess.run(["git", "config", "user.email", "clawdbot@e-t-systems.ai"], cwd=self.repo_path)
|
| 734 |
+
subprocess.run(["git", "config", "user.name", "Clawdbot"], cwd=self.repo_path)
|
| 735 |
+
subprocess.run(["git", "branch", "-M", "main"], cwd=self.repo_path)
|
| 736 |
+
|
| 737 |
+
# 2. Configure Remote (Idempotent)
|
| 738 |
+
subprocess.run(["git", "remote", "remove", "origin"], cwd=self.repo_path, stderr=subprocess.DEVNULL)
|
| 739 |
+
subprocess.run(["git", "remote", "add", "origin", remote_url], cwd=self.repo_path, check=True)
|
| 740 |
+
|
| 741 |
+
# 3. Add, Commit, Push
|
| 742 |
subprocess.run(["git", "add", "."], cwd=self.repo_path, check=True)
|
| 743 |
+
|
| 744 |
+
# Commit (allow empty if nothing changed)
|
| 745 |
+
commit_res = subprocess.run(
|
| 746 |
+
["git", "commit", "-m", commit_message],
|
| 747 |
+
cwd=self.repo_path, capture_output=True, text=True
|
| 748 |
+
)
|
| 749 |
+
|
| 750 |
+
# Push (force is safer for a backup mirror)
|
| 751 |
+
push_res = subprocess.run(
|
| 752 |
+
["git", "push", "-u", "origin", "main", "--force"],
|
| 753 |
+
cwd=self.repo_path, capture_output=True, text=True
|
| 754 |
+
)
|
| 755 |
+
|
| 756 |
+
if push_res.returncode == 0:
|
| 757 |
+
repo_name = os.getenv("GITHUB_REPO").replace("https://github.com/", "").replace(".git", "")
|
| 758 |
+
return f"✅ Successfully pushed to GitHub: https://github.com/{repo_name}"
|
| 759 |
+
else:
|
| 760 |
+
return f"⚠️ Git Push Failed: {push_res.stderr}"
|
| 761 |
+
|
| 762 |
+
except Exception as e:
|
| 763 |
+
return f"❌ Critical Git Error: {e}"
|
| 764 |
|
| 765 |
def pull_from_github(self, branch="main"):
|
| 766 |
"""Hard reset: Destroys local changes and pulls clean code from GitHub."""
|
| 767 |
+
remote_url = self._get_authenticated_remote_url()
|
| 768 |
+
if not remote_url:
|
| 769 |
+
return "❌ Error: GITHUB_TOKEN or GITHUB_REPO secret is missing."
|
| 770 |
+
|
| 771 |
try:
|
| 772 |
+
# 1. Init if missing
|
| 773 |
if not (self.repo_path / ".git").exists():
|
| 774 |
subprocess.run(["git", "init"], cwd=self.repo_path, check=True)
|
| 775 |
subprocess.run(["git", "remote", "add", "origin", remote_url], cwd=self.repo_path)
|
| 776 |
+
|
| 777 |
+
# 2. Fetch and Reset
|
| 778 |
subprocess.run(["git", "fetch", "origin"], cwd=self.repo_path, check=True)
|
| 779 |
+
res = subprocess.run(
|
| 780 |
+
["git", "reset", "--hard", f"origin/{branch}"],
|
| 781 |
+
cwd=self.repo_path, capture_output=True, text=True
|
| 782 |
+
)
|
| 783 |
+
|
| 784 |
+
if res.returncode == 0:
|
| 785 |
+
return f"✅ RESTORE COMPLETED. Local files replaced with GitHub/{branch}."
|
| 786 |
+
else:
|
| 787 |
+
return f"⚠️ Pull Failed: {res.stderr}"
|
| 788 |
+
|
| 789 |
+
except Exception as e:
|
| 790 |
+
return f"❌ Critical Git Error: {e}"
|
| 791 |
|
| 792 |
# =====================================================================
|
| 793 |
# WORKING MEMORY NOTEBOOK (Structured List)
|