Fresh start - excluded large ROM JSON files
This commit is contained in:
23
scripts/backup-clawdbot.ps1
Normal file
23
scripts/backup-clawdbot.ps1
Normal file
@@ -0,0 +1,23 @@
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd_HHmmss"
|
||||
$backupDir = "C:\Users\admin\clawd\backups"
|
||||
$backupFile = "$backupDir\backup_$timestamp.zip"
|
||||
|
||||
Write-Host "Creating Clawdbot backup: $backupFile" -ForegroundColor Green
|
||||
|
||||
$tempBase = "C:\Users\admin\.clawdbot-backup-temp"
|
||||
Remove-Item -Recurse -Force $tempBase -ErrorAction SilentlyContinue | Out-Null
|
||||
$tempDir = "$tempBase\clawd"
|
||||
|
||||
xcopy "C:\Users\admin\clawd\skills" "$tempDir\skills\" /E /I /Q 2>$null | Out-Null
|
||||
xcopy "C:\Users\admin\clawd\projects" "$tempDir\projects\" /E /I /Q 2>$null | Out-Null
|
||||
xcopy "C:\Users\admin\clawd\docs" "$tempDir\docs\" /E /I /Q 2>$null | Out-Null
|
||||
xcopy "C:\Users\admin\clawd\memory" "$tempDir\memory\" /E /I /Q 2>$null | Out-Null
|
||||
|
||||
xcopy "C:\Users\admin\.clawdbot\agents\main\agent" "$tempDir\agents\" /E /I /Q /EXCLUDE:C:\Users\admin\clawd\backup-exclude.txt 2>$null | Out-Null
|
||||
|
||||
Compress-Archive -Path "$tempDir\*" -DestinationPath $backupFile -Force
|
||||
|
||||
Remove-Item -Recurse -Force $tempBase 2>$null | Out-Null
|
||||
|
||||
$sizeMB = [math]::Round((Get-Item $backupFile).Length / 1MB, 2)
|
||||
Write-Host "Backup complete: $backupFile ($sizeMB MB)" -ForegroundColor Green
|
||||
118
scripts/backup-memory.py
Normal file
118
scripts/backup-memory.py
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Backup MEMORY.md and daily memory files to Supermemory
|
||||
Runs via cron every 6 hours
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import requests
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
# Load API key from .env file manually
|
||||
def load_env():
|
||||
# Get the directory where this script is located
|
||||
script_dir = Path(__file__).parent
|
||||
# Look for .env in the parent directory (workspace root)
|
||||
env_path = script_dir.parent / '.env'
|
||||
if env_path.exists():
|
||||
with open(env_path, 'r') as f:
|
||||
for line in f:
|
||||
if line.strip() and not line.startswith('#'):
|
||||
if '=' in line:
|
||||
key, value = line.strip().split('=', 1)
|
||||
os.environ[key] = value
|
||||
|
||||
load_env()
|
||||
API_KEY = os.getenv('SUPERMEMORY_API_KEY')
|
||||
|
||||
if not API_KEY:
|
||||
print("Error: SUPERMEMORY_API_KEY not found in .env")
|
||||
sys.exit(1)
|
||||
|
||||
API_BASE = "https://api.supermemory.ai/v3"
|
||||
HEADERS = {
|
||||
"Authorization": f"Bearer {API_KEY}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
def read_file(path):
|
||||
"""Read file content, return None if not found"""
|
||||
try:
|
||||
with open(path, 'r', encoding='utf-8') as f:
|
||||
return f.read()
|
||||
except UnicodeDecodeError:
|
||||
# Fallback to Windows-1252 for files with em-dashes, etc.
|
||||
try:
|
||||
with open(path, 'r', encoding='cp1252') as f:
|
||||
return f.read()
|
||||
except:
|
||||
return None
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
|
||||
def backup_to_supermemory():
|
||||
"""Backup memory files to Supermemory"""
|
||||
|
||||
# Get workspace directory (parent of script directory)
|
||||
workspace_dir = Path(__file__).parent.parent
|
||||
|
||||
# Read MEMORY.md
|
||||
memory_content = read_file(workspace_dir / 'MEMORY.md')
|
||||
|
||||
# Read today's memory file
|
||||
today = datetime.now().strftime('%Y-%m-%d')
|
||||
daily_memory = read_file(workspace_dir / 'memory' / f'{today}.md')
|
||||
|
||||
if not memory_content and not daily_memory:
|
||||
print("No memory files to backup")
|
||||
return
|
||||
|
||||
# Combine content
|
||||
full_backup = f"""# Memory Backup - {today}
|
||||
|
||||
## Long-term Memory (MEMORY.md)
|
||||
{memory_content if memory_content else "(No long-term memory yet)"}
|
||||
|
||||
## Daily Notes (memory/{today}.md)
|
||||
{daily_memory if daily_memory else "(No daily notes yet)"}
|
||||
"""
|
||||
|
||||
# Use correct Supermemory endpoint: POST /v3/documents
|
||||
payload = {
|
||||
"content": full_backup,
|
||||
"containerTag": "clawdbot-memory",
|
||||
"customId": f"memory-backup-{today}",
|
||||
"metadata": {
|
||||
"type": "memory-backup",
|
||||
"date": today,
|
||||
"source": "clawdbot"
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{API_BASE}/documents",
|
||||
headers=HEADERS,
|
||||
json=payload,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code == 200 or response.status_code == 201:
|
||||
result = response.json()
|
||||
print(f"[OK] Successfully backed up memory to Supermemory")
|
||||
print(f" Document ID: {result.get('id', 'unknown')}")
|
||||
print(f" Status: {result.get('status', 'unknown')}")
|
||||
# Write backup timestamp
|
||||
with open('.last-backup', 'w') as f:
|
||||
f.write(datetime.now().isoformat())
|
||||
else:
|
||||
print(f"[ERROR] Failed to backup: {response.status_code}")
|
||||
print(f" Response: {response.text}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Error backing up: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
backup_to_supermemory()
|
||||
10
scripts/backup-zip.ps1
Normal file
10
scripts/backup-zip.ps1
Normal file
@@ -0,0 +1,10 @@
|
||||
$t = "C:\Users\admin\.clawdbot-backup-temp\clawd"
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd_HHmmss"
|
||||
$b = "P:\Clawdbot-Backups\backup_$timestamp.zip"
|
||||
|
||||
Compress-Archive -Path "$t\*" -DestinationPath $b -Force
|
||||
$s = [math]::Round((Get-Item $b).Length / 1MB, 2)
|
||||
|
||||
Write-Host "Backup complete: $b ($s MB)" -ForegroundColor Green
|
||||
|
||||
Remove-Item -Recurse -Force "C:\Users\admin\.clawdbot-backup-temp" -ErrorAction SilentlyContinue
|
||||
31
scripts/check_memory.py
Normal file
31
scripts/check_memory.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import sqlite3
|
||||
from pathlib import Path
|
||||
|
||||
db_path = Path.home() / '.openclaw' / 'memory.db'
|
||||
if db_path.exists():
|
||||
conn = sqlite3.connect(str(db_path))
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Get embedding count
|
||||
cursor.execute("SELECT COUNT(*) FROM memory_embeddings")
|
||||
count = cursor.fetchone()[0]
|
||||
print(f"[OK] Vector embeddings: {count}")
|
||||
|
||||
# Get recent entries
|
||||
cursor.execute("SELECT COUNT(*) FROM memory_entries")
|
||||
entries = cursor.fetchone()[0]
|
||||
print(f"[OK] Memory entries: {entries}")
|
||||
|
||||
# Check DB size
|
||||
size_kb = db_path.stat().st_size / 1024
|
||||
print(f"[OK] DB size: {size_kb:.1f} KB")
|
||||
|
||||
# Show recent embeddings
|
||||
cursor.execute("SELECT source_path, created_at FROM memory_embeddings ORDER BY created_at DESC LIMIT 5")
|
||||
print("\nRecent embeddings:")
|
||||
for row in cursor.fetchall():
|
||||
print(f" - {row[0]} ({row[1]})")
|
||||
|
||||
conn.close()
|
||||
else:
|
||||
print("[ERR] Database not found")
|
||||
3
scripts/close-cover.ps1
Normal file
3
scripts/close-cover.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmM2QzZWU1NGQyMWI0NGVkYWJmZGE4OGFiMTE3OTQ0MyIsImlhdCI6MTc2OTYxMzM0MiwiZXhwIjoyMDg0OTczMzQyfQ.L5atWZ-zyn-gA7QELxzRXoMnVilyz338hApOuL5MFas"
|
||||
$body = @{entity_id = "cover.door1"} | ConvertTo-Json
|
||||
Invoke-WebRequest -Uri "http://192.168.0.39:8123/api/services/cover/close_cover" -Method Post -Headers @{Authorization="Bearer " + $token} -ContentType "application/json" -Body $body
|
||||
103
scripts/extract_memory.py
Normal file
103
scripts/extract_memory.py
Normal file
@@ -0,0 +1,103 @@
|
||||
import sqlite3
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
# Yesterday's date: Feb 25, 2026
|
||||
yesterday = "2026-02-25"
|
||||
|
||||
# Read yesterday's memory file
|
||||
with open(r'C:\Users\admin\.openclaw\workspace\memory\2026-02-25.md', 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
print(f"=== Processing {yesterday} ===")
|
||||
print(f"File size: {len(content)} characters")
|
||||
print(f"Content preview:\n{content[:500]}\n")
|
||||
|
||||
# Connect to database
|
||||
conn = sqlite3.connect(r'C:\Users\admin\.openclaw\memory.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Parse structured data
|
||||
entries = []
|
||||
|
||||
# Extract sections by headers
|
||||
sections = re.split(r'\n## ', content)
|
||||
print(f"Found {len(sections)} sections")
|
||||
|
||||
for section in sections:
|
||||
section = section.strip()
|
||||
if not section:
|
||||
continue
|
||||
|
||||
lines = section.split('\n')
|
||||
heading = lines[0].replace('#', '').strip()
|
||||
body = '\n'.join(lines[1:]).strip()
|
||||
|
||||
# Classify entry type
|
||||
entry_type = "note"
|
||||
if any(x in heading.lower() for x in ['bug', 'issue', 'error', 'problem', 'failed']):
|
||||
entry_type = "bug"
|
||||
elif any(x in heading.lower() for x in ['todo', 'action', 'task', 'next']):
|
||||
entry_type = "action_item"
|
||||
elif any(x in heading.lower() for x in ['decision', 'decided', 'chose', 'selected']):
|
||||
entry_type = "decision"
|
||||
elif any(x in heading.lower() for x in ['system', 'status', 'check', 'cron']):
|
||||
entry_type = "system_status"
|
||||
elif any(x in heading.lower() for x in ['morning', 'evening', 'afternoon']):
|
||||
entry_type = "log"
|
||||
|
||||
# Extract tags from content
|
||||
tags = []
|
||||
if 'ha ' in body.lower() or 'home assistant' in body.lower():
|
||||
tags.append('ha')
|
||||
if 'cron' in body.lower():
|
||||
tags.append('cron')
|
||||
if 'discord' in body.lower():
|
||||
tags.append('discord')
|
||||
if 'memory' in body.lower():
|
||||
tags.append('memory')
|
||||
|
||||
tags_str = ','.join(tags) if tags else None
|
||||
|
||||
entries.append({
|
||||
'source_date': yesterday,
|
||||
'entry_type': entry_type,
|
||||
'title': heading[:200],
|
||||
'content': body[:2000] if body else None,
|
||||
'tags': tags_str
|
||||
})
|
||||
|
||||
print(f" Extracted: {entry_type} - {heading[:60]}")
|
||||
|
||||
# Insert into database
|
||||
inserted_count = 0
|
||||
for entry in entries:
|
||||
cursor.execute("""
|
||||
INSERT INTO memory_entries (source_date, entry_type, title, content, tags)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
""", (entry['source_date'], entry['entry_type'], entry['title'],
|
||||
entry['content'], entry['tags']))
|
||||
inserted_count += 1
|
||||
|
||||
# Log the extraction
|
||||
cursor.execute("""
|
||||
INSERT INTO extraction_log (date, items_extracted, errors)
|
||||
VALUES (?, ?, ?)
|
||||
""", (yesterday, inserted_count, None if inserted_count > 0 else "Minimal content to extract"))
|
||||
|
||||
# Update daily_summary
|
||||
cursor.execute("""
|
||||
INSERT OR REPLACE INTO daily_summary
|
||||
(source_date, total_entries, system_status, other, processed_at)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
""", (yesterday, inserted_count,
|
||||
sum(1 for e in entries if e['entry_type'] == 'system_status'),
|
||||
sum(1 for e in entries if e['entry_type'] not in ['bug', 'action_item', 'decision', 'system_status']),
|
||||
datetime.now().isoformat()))
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
print(f"\n=== Summary ===")
|
||||
print(f"Entries extracted: {inserted_count}")
|
||||
print(f"Written to database: C:\\Users\\admin\\.openclaw\\memory.db")
|
||||
29
scripts/get-battery-levels.ps1
Normal file
29
scripts/get-battery-levels.ps1
Normal file
@@ -0,0 +1,29 @@
|
||||
$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmM2QzZWU1NGQyMWI0NGVkYWJmZGE4OGFiMTE3OTQ0MyIsImlhdCI6MTc2OTYxMzM0MiwiZXhwIjoyMDg0OTczMzQyfQ.L5atWZ-zyn-gA7QELxzRXoMnVilyz338hApOuL5MFas"
|
||||
$baseUrl = "http://192.168.0.39:8123/api/states/"
|
||||
$sensors = @(
|
||||
"sensor.front_door_battery",
|
||||
"sensor.pantry_door_sensor_battery",
|
||||
"sensor.garage_entrance_door_battery",
|
||||
"sensor.office_door_sensor_battery",
|
||||
"sensor.master_closet_door_sensor_battery",
|
||||
"sensor.shower_door_battery",
|
||||
"sensor.hue_motion_sensor_2_battery",
|
||||
"sensor.hue_motion_sensor_3_battery",
|
||||
"sensor.motion_sensor_battery_state",
|
||||
"sensor.pir_battery",
|
||||
"sensor.guest_bath_motion_battery",
|
||||
"sensor.master_bath_motion_battery",
|
||||
"sensor.office_motion_battery",
|
||||
"sensor.master_pooper_battery"
|
||||
)
|
||||
|
||||
foreach ($sensor in $sensors) {
|
||||
try {
|
||||
$r = Invoke-WebRequest -Uri ($baseUrl + $sensor) -Headers @{Authorization="Bearer " + $token} -TimeoutSec 3
|
||||
$s = $r.Content | ConvertFrom-Json
|
||||
$unit = if ($s.attributes.unit_of_measurement) { $s.attributes.unit_of_measurement } else { "-" }
|
||||
Write-Host "$($sensor): $($s.state) $unit"
|
||||
} catch {
|
||||
Write-Host "$sensor - ERROR"
|
||||
}
|
||||
}
|
||||
29
scripts/install-mailspring.ps1
Normal file
29
scripts/install-mailspring.ps1
Normal file
@@ -0,0 +1,29 @@
|
||||
# PowerShell script to download and install Mailspring
|
||||
# Run as Administrator
|
||||
|
||||
$downloadUrl = "https://github.com/Foundry376/Mailspring/releases/download/1.17.3/MailspringSetup.exe"
|
||||
$installerPath = "$env:TEMP\MailspringSetup.exe"
|
||||
|
||||
Write-Host "[INFO] Downloading Mailspring..."
|
||||
Write-Host "[INFO] This may take a few minutes (approx 200MB)..."
|
||||
|
||||
try {
|
||||
# Download the installer
|
||||
Invoke-WebRequest -Uri $downloadUrl -OutFile $installerPath -UseBasicParsing
|
||||
Write-Host "[OK] Download complete: $installerPath"
|
||||
|
||||
# Run the installer silently
|
||||
Write-Host "[INFO] Installing Mailspring..."
|
||||
Start-Process -FilePath $installerPath -ArgumentList "/S" -Wait
|
||||
|
||||
Write-Host "[OK] Mailspring installed successfully!"
|
||||
Write-Host "[INFO] You can find Mailspring in your Start Menu"
|
||||
|
||||
# Cleanup
|
||||
Remove-Item $installerPath -Force
|
||||
Write-Host "[INFO] Cleanup complete"
|
||||
|
||||
} catch {
|
||||
Write-Host "[ERROR] Installation failed: $_"
|
||||
exit 1
|
||||
}
|
||||
3
scripts/list-covers.ps1
Normal file
3
scripts/list-covers.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
$data = Get-Content covers.json -Raw | ConvertFrom-Json
|
||||
$covers = $data | Where-Object { $_.entity_id -match '^cover\.' }
|
||||
$covers | ForEach-Object { $_.entity_id }
|
||||
3
scripts/list-sensors.ps1
Normal file
3
scripts/list-sensors.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
$data = Get-Content ha_states.json -Raw | ConvertFrom-Json
|
||||
$sensors = $data | Where-Object { $_.entity_id -match '^sensor\.' }
|
||||
$sensors | ForEach-Object { $_.entity_id }
|
||||
35
scripts/memory-embeddings-cron.ps1
Normal file
35
scripts/memory-embeddings-cron.ps1
Normal file
@@ -0,0 +1,35 @@
|
||||
# Memory Embeddings Cron Job
|
||||
# Processes memory files and stores with embeddings
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$pythonPath = "python"
|
||||
$scriptPath = "$env:USERPROFILE\.openclaw\workspace\tools\memory_embedding_worker.py"
|
||||
|
||||
Write-Host "Starting Memory Embedding Worker..."
|
||||
|
||||
# Check if Ollama is running
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri "http://localhost:11434/api/tags" -TimeoutSec 5
|
||||
Write-Host "[OK] Ollama is running"
|
||||
} catch {
|
||||
Write-Host "[ERROR] Ollama not available. Cannot generate embeddings." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if nomic-embed-text is available
|
||||
$hasModel = $response.models | Where-Object { $_.name -like "*nomic-embed-text*" }
|
||||
if (-not $hasModel) {
|
||||
Write-Host "[WARNING] nomic-embed-text model not found. Pulling..." -ForegroundColor Yellow
|
||||
& $pythonPath -c "import requests; requests.post('http://localhost:11434/api/pull', json={'model': 'nomic-embed-text'}).json()"
|
||||
}
|
||||
|
||||
# Run the worker
|
||||
& $pythonPath $scriptPath
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "[ERROR] Worker failed with exit code $LASTEXITCODE" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
Write-Host "[OK] Memory embeddings complete"
|
||||
26
scripts/memory-worker-daily.ps1
Normal file
26
scripts/memory-worker-daily.ps1
Normal file
@@ -0,0 +1,26 @@
|
||||
# Memory Worker Daily
|
||||
# Creates daily memory file if missing, does basic maintenance
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$memoryDir = "$env:USERPROFILE\.openclaw\workspace\memory"
|
||||
$today = Get-Date -Format "yyyy-MM-dd"
|
||||
$todayFile = "$memoryDir\$today.md"
|
||||
|
||||
Write-Host "Memory Worker Daily - $today"
|
||||
|
||||
# Create today''s file if missing
|
||||
if (-not (Test-Path $todayFile)) {
|
||||
New-Item -Path $todayFile -ItemType File -Force | Out-Null
|
||||
Write-Host "[OK] Created $today.md"
|
||||
} else {
|
||||
Write-Host "[OK] $today.md exists"
|
||||
}
|
||||
|
||||
# Check memory directory exists
|
||||
if (Test-Path $memoryDir) {
|
||||
$fileCount = (Get-ChildItem $memoryDir -Filter "*.md" -Recurse).Count
|
||||
Write-Host "[OK] $fileCount memory files in directory"
|
||||
}
|
||||
|
||||
Write-Host "[OK] Memory worker complete"
|
||||
3
scripts/open-garage.ps1
Normal file
3
scripts/open-garage.ps1
Normal file
@@ -0,0 +1,3 @@
|
||||
$token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJmM2QzZWU1NGQyMWI0NGVkYWJmZGE4OGFiMTE3OTQ0MyIsImlhdCI6MTc2OTYxMzM0MiwiZXhwIjoyMDg0OTczMzQyfQ.L5atWZ-zyn-gA7QELxzRXoMnVilyz338hApOuL5MFas"
|
||||
$body = @{entity_id = "cover.garage_door"} | ConvertTo-Json
|
||||
Invoke-WebRequest -Uri "http://192.168.0.39:8123/api/services/cover/open_cover" -Method Post -Headers @{Authorization="Bearer " + $token} -ContentType "application/json" -Body $body
|
||||
8
scripts/parse-brave.ps1
Normal file
8
scripts/parse-brave.ps1
Normal file
@@ -0,0 +1,8 @@
|
||||
$data = Get-Content brave_results.json -Raw | ConvertFrom-Json
|
||||
$results = $data.web.results | Select-Object -First 5
|
||||
foreach ($r in $results) {
|
||||
Write-Host "=== $($r.title) ==="
|
||||
Write-Host "$($r.url)"
|
||||
Write-Host "$($r.description)"
|
||||
Write-Host ""
|
||||
}
|
||||
36
scripts/session-archive-weekly.py
Normal file
36
scripts/session-archive-weekly.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""Session Archive Weekly
|
||||
Archives old session files from openclaw data directory.
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
# Paths
|
||||
DATA_DIR = Path(os.environ.get("OPENCLAW_DATA", os.path.expanduser("~/.openclaw")))
|
||||
ARCHIVE_DIR = DATA_DIR / "workspace" / "memory" / "archive"
|
||||
|
||||
def archive_old_sessions():
|
||||
"""Archive session files older than 7 days."""
|
||||
ARCHIVE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
cutoff = datetime.now() - timedelta(days=7)
|
||||
archived_count = 0
|
||||
|
||||
# Archive old session logs if they exist
|
||||
session_dir = DATA_DIR / "sessions"
|
||||
if session_dir.exists():
|
||||
for f in session_dir.glob("**/*.json"):
|
||||
if datetime.fromtimestamp(f.stat().st_mtime) < cutoff:
|
||||
dest = ARCHIVE_DIR / f.name
|
||||
if not dest.exists():
|
||||
shutil.copy2(f, dest)
|
||||
archived_count += 1
|
||||
|
||||
print(f"Archived {archived_count} old session files")
|
||||
return archived_count
|
||||
|
||||
if __name__ == "__main__":
|
||||
count = archive_old_sessions()
|
||||
print(f"[OK] Weekly archive complete - {count} files archived")
|
||||
20
scripts/setup-backup-task.ps1
Normal file
20
scripts/setup-backup-task.ps1
Normal file
@@ -0,0 +1,20 @@
|
||||
# PowerShell script to create a Windows Scheduled Task for memory backup
|
||||
# Run this as Administrator
|
||||
|
||||
$taskName = "OpenClaw Memory Backup"
|
||||
$description = "Backup MEMORY.md to Supermemory every 6 hours"
|
||||
|
||||
# Task action - run the Python script
|
||||
$action = New-ScheduledTaskAction -Execute "python" -Argument "scripts\backup-memory.py" -WorkingDirectory "$env:USERPROFILE\.openclaw\workspace"
|
||||
|
||||
# Trigger - every 6 hours
|
||||
$trigger = New-ScheduledTaskTrigger -Daily -At "00:00" -RepetitionInterval (New-TimeSpan -Hours 6) -RepetitionDuration (New-TimeSpan -Days 1)
|
||||
|
||||
# Settings
|
||||
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
|
||||
|
||||
# Register the task
|
||||
Register-ScheduledTask -TaskName $taskName -Action $action -Trigger $trigger -Settings $settings -Description $description -RunLevel Limited
|
||||
|
||||
Write-Host "[OK] Scheduled task '$taskName' created successfully!"
|
||||
Write-Host " Runs every 6 hours starting at midnight"
|
||||
36
scripts/sync-obsidian.ps1
Normal file
36
scripts/sync-obsidian.ps1
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env powershell
|
||||
# sync-obsidian.ps1 - Syncs OpenClaw config and memory to Obsidian
|
||||
# Runs via cron daily
|
||||
|
||||
$date = Get-Date -Format "yyyy-MM-dd"
|
||||
$vaultPath = "C:\Users\admin\Documents\Corey\OpenClaw"
|
||||
$workspacePath = "C:\Users\admin\.openclaw\workspace"
|
||||
|
||||
# Ensure directory exists
|
||||
if (!(Test-Path $vaultPath)) {
|
||||
New-Item -ItemType Directory -Path $vaultPath -Force | Out-Null
|
||||
}
|
||||
|
||||
# Copy TOOLS.md to Obsidian (Discord config section is there)
|
||||
Copy-Item "$workspacePath\TOOLS.md" "$vaultPath\Tools Reference.md" -Force
|
||||
|
||||
# Copy MEMORY.md
|
||||
Copy-Item "$workspacePath\MEMORY.md" "$vaultPath\MEMORY Index.md" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
# Create daily sync note
|
||||
$syncContent = @"
|
||||
# OpenClaw Sync - $date
|
||||
|
||||
## Files Synced
|
||||
- Tools Reference.md (from TOOLS.md)
|
||||
- MEMORY Index.md (from MEMORY.md)
|
||||
|
||||
## Notes
|
||||
Last updated: $((Get-Date).ToString('HH:mm'))
|
||||
|
||||
---
|
||||
"@
|
||||
|
||||
$syncContent | Out-File -FilePath "$vaultPath\Sync History $date.md" -Encoding utf8
|
||||
|
||||
Write-Host "Obsidian sync completed at $((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))"
|
||||
Reference in New Issue
Block a user