File size: 4,906 Bytes
2c46c74
1d05a2c
 
5c39dd3
2c9c3c7
2c46c74
5c39dd3
ec24da1
5c39dd3
104455d
5c39dd3
 
 
 
 
 
 
b1e4956
5c39dd3
b1e4956
2c9c3c7
 
 
 
5c39dd3
2c9c3c7
 
 
 
 
 
94f12f4
 
b1e4956
 
 
 
 
 
2c9c3c7
 
b1e4956
 
5c39dd3
b1e4956
5c39dd3
2c9c3c7
5c39dd3
b1e4956
2c9c3c7
 
b1e4956
 
 
 
 
 
 
 
 
 
ec24da1
b1e4956
 
 
 
 
 
 
 
 
2c9c3c7
5c39dd3
b1e4956
2c46c74
 
ec24da1
b1e4956
ec24da1
b1e4956
 
ec24da1
 
2c9c3c7
 
b1e4956
2c9c3c7
 
b1e4956
 
 
 
ec24da1
 
b1e4956
ec24da1
5c39dd3
2c46c74
b1e4956
2c9c3c7
 
 
b1e4956
2c9c3c7
b1e4956
 
 
 
 
 
5c39dd3
 
b1e4956
2c46c74
 
 
b1e4956
2c9c3c7
b1e4956
5c39dd3
b1e4956
 
5c39dd3
 
ec24da1
2c9c3c7
b1e4956
 
 
 
 
 
5c39dd3
 
 
b1e4956
5c39dd3
b1e4956
 
 
 
 
 
5c39dd3
 
b1e4956
5c39dd3
 
1d05a2c
5c39dd3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# syntax=docker/dockerfile:1
FROM lbjlaq/antigravity-manager:latest

USER root
RUN apt-get update && apt-get install -y --no-install-recommends curl jq && rm -rf /var/lib/apt/lists/*

ENV DATA_DIR=/root/.antigravity_tools
ENV SYNC_INTERVAL=150
EXPOSE 8045

COPY --chmod=755 <<'SCRIPT' /entrypoint.sh
#!/bin/bash
set -e

DATA_DIR="${DATA_DIR:-/root/.antigravity_tools}"
SYNC_INTERVAL="${SYNC_INTERVAL:-30}"
LAST_SYNC="/tmp/.last_sync"
SUPABASE_PREFIX="antigravity_tools"

# ── Helpers ──────────────────────────────────────────────────────
supabase_list() {
  local prefix="$1" response files folders
  response=$(curl -s -X POST \
    "${SUPABASE_URL}/storage/v1/object/list/${SUPABASE_BUCKET}" \
    -H "Authorization: Bearer ${SUPABASE_KEY}" \
    -H "Content-Type: application/json" \
    -d "{\"prefix\":\"${prefix}\",\"limit\":1000}" 2>/dev/null)
  files=$(echo "$response" | jq -r '.[]? | select(.id != null) | .name' 2>/dev/null)
  folders=$(echo "$response" | jq -r '.[]? | select(.id == null) | .name' 2>/dev/null)
  for f in $files; do [ -n "$f" ] && echo "${prefix}${f}"; done
  for d in $folders; do [ -n "$d" ] && supabase_list "${prefix}${d}/"; done
}

supabase_download() {
  local remote_path="$1" local_path="$2"
  mkdir -p "$(dirname "$local_path")"
  curl -s -o "$local_path" \
    "${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/${remote_path}" \
    -H "Authorization: Bearer ${SUPABASE_KEY}"
}

supabase_upload() {
  local local_path="$1" remote_path="$2"
  curl -s -X POST \
    "${SUPABASE_URL}/storage/v1/object/${SUPABASE_BUCKET}/${remote_path}" \
    -H "Authorization: Bearer ${SUPABASE_KEY}" \
    -H "Content-Type: application/octet-stream" \
    -H "x-upsert: true" \
    --data-binary "@${local_path}" > /dev/null 2>&1
}

supabase_has_data() {
  local r
  r=$(curl -s -X POST \
    "${SUPABASE_URL}/storage/v1/object/list/${SUPABASE_BUCKET}" \
    -H "Authorization: Bearer ${SUPABASE_KEY}" \
    -H "Content-Type: application/json" \
    -d "{\"prefix\":\"${SUPABASE_PREFIX}/\",\"limit\":1}" 2>/dev/null)
  [ "$(echo "$r" | jq 'length' 2>/dev/null)" != "0" ]
}

# ── Pull: Download all files from Supabase ──────────────────────
pull_from_supabase() {
  echo "[Sync] Pulling from Supabase..."
  local count=0
  supabase_list "${SUPABASE_PREFIX}/" | while read -r remote_path; do
    local rel="${remote_path#${SUPABASE_PREFIX}/}"
    local local_path="$DATA_DIR/$rel"
    supabase_download "$remote_path" "$local_path"
    echo "[Sync]   <- $rel"
    count=$((count + 1))
  done
  touch "$LAST_SYNC"
  echo "[Sync] Pull complete!"
}

# ── Push: Upload entire directory to Supabase ───────────────────
push_all() {
  echo "[Sync] Pushing entire directory..."
  find "$DATA_DIR" -type f | while read -r filepath; do
    local rel="${filepath#$DATA_DIR/}"
    supabase_upload "$filepath" "${SUPABASE_PREFIX}/${rel}"
    echo "[Sync]   -> $rel"
  done
  touch "$LAST_SYNC"
  echo "[Sync] Push complete at $(date '+%H:%M:%S')"
}

# ── Push changed: Only upload files modified since last sync ────
push_changed() {
  find "$DATA_DIR" -type f -newer "$LAST_SYNC" 2>/dev/null | while read -r filepath; do
    local rel="${filepath#$DATA_DIR/}"
    supabase_upload "$filepath" "${SUPABASE_PREFIX}/${rel}"
    echo "[Sync]   -> $rel"
  done
  touch "$LAST_SYNC"
}

# ── Main ─────────────────────────────────────────────────────────
SYNC=""
[ -n "$SUPABASE_URL" ] && [ -n "$SUPABASE_KEY" ] && [ -n "$SUPABASE_BUCKET" ] && SYNC="1"

# Step 1: Pull existing data from Supabase
if [ -n "$SYNC" ]; then
  echo "[Sync] Checking Supabase for existing data..."
  if supabase_has_data; then
    pull_from_supabase
  else
    echo "[Sync] Empty bucket β€” first run."
  fi
fi

# Step 2: Start the app
/app/antigravity-tools --headless &
APP_PID=$!

# Step 3: First run β€” wait for data dir, then push initial state
if [ -n "$SYNC" ] && [ ! -f "$LAST_SYNC" ]; then
  echo "[Sync] Waiting for app to create data..."
  while [ ! -d "$DATA_DIR" ]; do sleep 2; done
  sleep 5
  push_all
fi

# Step 4: Background sync β€” push changed files every N seconds
if [ -n "$SYNC" ]; then
  (
    while kill -0 $APP_PID 2>/dev/null; do
      sleep "$SYNC_INTERVAL"
      push_changed || true
    done
  ) &
  SYNC_PID=$!
fi

# Step 5: Final push on shutdown
cleanup() {
  echo "[Sync] Shutting down β€” final push..."
  [ -n "$SYNC" ] && [ -d "$DATA_DIR" ] && push_all
  kill $APP_PID 2>/dev/null
  [ -n "$SYNC_PID" ] && kill $SYNC_PID 2>/dev/null
  wait $APP_PID 2>/dev/null
  exit 0
}
trap cleanup SIGTERM SIGINT

wait $APP_PID
SCRIPT

ENTRYPOINT ["/entrypoint.sh"]