- workspace: capmetro-monitor, github-notifications, model-selector - workspace-security: vt-monitor, monitor-unauthorized - workspace-home: cron-manager, monitor-unauthorized - extensions: vt-sentinel (VT-Sentinel plugin) Includes sync.sh for pull/push, README, AGENTS.md, .gitignore.
115 lines
3.3 KiB
Bash
Executable File
115 lines
3.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Sync OpenClaw custom skills between docker-test:/opt/openclaw and local openclaw-skills.
|
|
# Run from this directory. Uses scp (rsync not available on docker-test).
|
|
|
|
set -euo pipefail
|
|
|
|
REMOTE="${REMOTE:-docker-test}"
|
|
OPENCLAW_BASE="/opt/openclaw"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# Runtime files to exclude from sync (tokens, cache, state)
|
|
EXCLUDE_PATTERNS=(
|
|
"state.json"
|
|
"seen-connections.json"
|
|
"authorized-ips.json"
|
|
"memory"
|
|
"*.bak"
|
|
)
|
|
|
|
# Skills to skip during pull (duplicates or deprecated versions on remote)
|
|
SKIP_SKILLS=(
|
|
"workspace-home/monitor-unauthorized" # superseded by workspace-security version
|
|
)
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 [direction]
|
|
|
|
Sync custom OpenClaw skills between $REMOTE:$OPENCLAW_BASE and local openclaw-skills.
|
|
|
|
direction: pull (default) | push
|
|
pull - Sync FROM docker-test TO local (download new/updated skills)
|
|
push - Sync FROM local TO docker-test (upload local changes)
|
|
|
|
Sources on remote:
|
|
- workspace/skills/ (capmetro-monitor, github-notifications, model-selector)
|
|
- state/workspace-security/skills/
|
|
- state/workspace-home/skills/
|
|
- state/extensions/openclaw-plugin-vt-sentinel/skills/
|
|
|
|
Environment:
|
|
REMOTE - SSH host (default: docker-test)
|
|
EOF
|
|
}
|
|
|
|
pull_skill_dir() {
|
|
local remote_path="$1"
|
|
local local_path="$2"
|
|
echo "Pulling $remote_path -> $local_path"
|
|
mkdir -p "$local_path"
|
|
scp -r "${REMOTE}:${OPENCLAW_BASE}/${remote_path}/"* "$local_path/" 2>/dev/null || true
|
|
}
|
|
|
|
push_skill_dir() {
|
|
local local_path="$1"
|
|
local remote_path="$2"
|
|
echo "Pushing $local_path -> $remote_path"
|
|
ssh "$REMOTE" "mkdir -p ${OPENCLAW_BASE}/${remote_path}"
|
|
for skill in "$local_path"/*/; do
|
|
[ -d "$skill" ] || continue
|
|
skill_name="$(basename "$skill")"
|
|
scp -r "$skill" "${REMOTE}:${OPENCLAW_BASE}/${remote_path}/"
|
|
done
|
|
}
|
|
|
|
remove_runtime_files() {
|
|
find . -name 'state.json' -delete 2>/dev/null || true
|
|
find . -name 'seen-connections.json' -delete 2>/dev/null || true
|
|
find . -name 'authorized-ips.json' -delete 2>/dev/null || true
|
|
find . -type d -name 'memory' -exec rm -rf {} + 2>/dev/null || true
|
|
find . -name '*.bak' -delete 2>/dev/null || true
|
|
}
|
|
|
|
remove_skipped_skills() {
|
|
for skip in "${SKIP_SKILLS[@]}"; do
|
|
if [ -d "$skip" ]; then
|
|
echo " Removing skipped skill: $skip"
|
|
rm -rf "$skip"
|
|
fi
|
|
done
|
|
}
|
|
|
|
pull() {
|
|
echo "=== Pulling skills from $REMOTE ==="
|
|
pull_skill_dir "workspace/skills" "workspace"
|
|
pull_skill_dir "state/workspace-security/skills" "workspace-security"
|
|
pull_skill_dir "state/workspace-home/skills" "workspace-home"
|
|
pull_skill_dir "state/extensions/openclaw-plugin-vt-sentinel/skills" "extensions"
|
|
remove_runtime_files
|
|
remove_skipped_skills
|
|
echo "Done. Run 'git status' to see changes."
|
|
}
|
|
|
|
push() {
|
|
echo "=== Pushing skills to $REMOTE ==="
|
|
push_skill_dir "workspace" "workspace/skills"
|
|
push_skill_dir "workspace-security" "state/workspace-security/skills"
|
|
push_skill_dir "workspace-home" "state/workspace-home/skills"
|
|
push_skill_dir "extensions" "state/extensions/openclaw-plugin-vt-sentinel/skills"
|
|
echo "Done. Restart OpenClaw or start a new session to pick up changes."
|
|
}
|
|
|
|
main() {
|
|
local direction="${1:-pull}"
|
|
case "$direction" in
|
|
pull) pull ;;
|
|
push) push ;;
|
|
-h|--help) usage ;;
|
|
*) echo "Unknown direction: $direction"; usage; exit 1 ;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|