merve HF Staff commited on
Commit
8e01a03
Β·
verified Β·
1 Parent(s): 7308820

Shadow HERMES_HOME pattern: .env stays local, bucket symlinks in

Browse files
Files changed (1) hide show
  1. bootstrap.sh +79 -29
bootstrap.sh CHANGED
@@ -4,22 +4,30 @@
4
  # ============================================================================
5
  # Creates your own HF bucket from the merve/hermes-agent template, mounts it,
6
  # installs Hermes, sets up Telegram, and launches the agent.
7
- # Idempotent: re-runs are safe.
 
 
 
 
 
 
 
 
 
 
 
8
  #
9
  # bash <(curl -fsSL https://huggingface.co/merve/hermes-agent-bootstrap/resolve/main/bootstrap.sh)
10
  #
11
- # What it touches:
12
- # <YOUR_HF_USERNAME>/hermes-agent β€” your personal bucket (created if missing)
13
- # ~/hermes-bucket β€” local mount of your bucket
14
- # ~/.hermes-secrets.env β€” your local secrets (mode 600, NEVER uploaded)
15
- # ~/.hermes/ β€” Hermes code + venv
16
- # ~/.local/bin/{hf,hermes,hf-mount} β€” installed CLIs
17
  # ============================================================================
18
  set -euo pipefail
19
 
20
  TEMPLATE="merve/hermes-agent"
21
  MOUNT="$HOME/hermes-bucket"
22
- SECRETS="$HOME/.hermes-secrets.env"
 
 
23
 
24
  G='\033[0;32m'; Y='\033[0;33m'; C='\033[0;36m'; R='\033[0;31m'; N='\033[0m'
25
  say() { printf "${C}β†’${N} %s\n" "$*"; }
@@ -107,7 +115,7 @@ else
107
  fi
108
 
109
  # ----------------------------------------------------------------------------
110
- # 6. Hermes Agent
111
  # ----------------------------------------------------------------------------
112
  if ! command -v hermes >/dev/null 2>&1; then
113
  say "Installing Hermes Agent (this takes a minute)..."
@@ -117,7 +125,38 @@ fi
117
  ok "Hermes: $(command -v hermes)"
118
 
119
  # ----------------------------------------------------------------------------
120
- # 7. Telegram (required step)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  # ----------------------------------------------------------------------------
122
  printf "\n${C}Telegram setup${N}\n"
123
 
@@ -162,11 +201,11 @@ except Exception:
162
  fi
163
 
164
  # ----------------------------------------------------------------------------
165
- # 8. Write secrets file (outside the bucket, mode 600)
166
  # ----------------------------------------------------------------------------
167
  umask 077
168
  cat > "$SECRETS" <<EOF
169
- # Hermes secrets β€” DO NOT commit, DO NOT put in the bucket
170
  HF_TOKEN=$HF_TOKEN_VAL
171
  TELEGRAM_BOT_TOKEN=$TG_TOKEN
172
  TELEGRAM_ALLOWED_USERS=$USER_ID
@@ -176,7 +215,7 @@ chmod 600 "$SECRETS"
176
  ok "Secrets saved to $SECRETS (mode 600)"
177
 
178
  # ----------------------------------------------------------------------------
179
- # 9. Shell aliases
180
  # ----------------------------------------------------------------------------
181
  SHELL_NAME="${SHELL##*/}"
182
  case "$SHELL_NAME" in
@@ -185,29 +224,41 @@ case "$SHELL_NAME" in
185
  *) SHELL_RC="$HOME/.profile" ;;
186
  esac
187
 
188
- if ! grep -q "# hermes-bucket aliases" "$SHELL_RC" 2>/dev/null; then
189
- cat >> "$SHELL_RC" <<EOF
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
 
191
- # hermes-bucket aliases (added by bootstrap.sh)
192
- alias hermes-here='HERMES_HOME=\$HOME/hermes-bucket bash -c "set -a; source \$HOME/.hermes-secrets.env; set +a; exec hermes"'
193
- alias hermes-gateway='HERMES_HOME=\$HOME/hermes-bucket bash -c "set -a; source \$HOME/.hermes-secrets.env; set +a; exec hermes gateway start"'
194
  EOF
195
- ok "Added shell aliases to $SHELL_RC"
196
- else
197
- ok "Shell aliases already present in $SHELL_RC"
198
- fi
199
 
200
  # ----------------------------------------------------------------------------
201
- # 10. Summary + launch
202
  # ----------------------------------------------------------------------------
203
  cat <<EOF
204
 
205
  ${G}βœ“ Ready.${N}
206
 
207
- Your bucket: https://huggingface.co/buckets/$BUCKET
208
- Mount: $MOUNT
209
- Secrets: $SECRETS
210
- Model: Qwen/Qwen3.6-35B-A3B (HF Inference Providers β†’ deepinfra)
211
 
212
  ${C}hermes-here${N} β€” chat in your terminal
213
  ${C}hermes-gateway${N} β€” start Telegram bot (talk from your phone)
@@ -217,8 +268,7 @@ EOF
217
  if [ -t 0 ] && [ -t 1 ]; then
218
  say "Launching Hermes now..."
219
  sleep 1
220
- export HERMES_HOME="$MOUNT"
221
- set -a; source "$SECRETS"; set +a
222
  exec hermes
223
  else
224
  say "Run ${C}source $SHELL_RC${N} then ${C}hermes-here${N} to start chatting."
 
4
  # ============================================================================
5
  # Creates your own HF bucket from the merve/hermes-agent template, mounts it,
6
  # installs Hermes, sets up Telegram, and launches the agent.
7
+ #
8
+ # Layout:
9
+ # ~/hermes-bucket mount of YOUR bucket (config, SOUL, skills, memories, ...)
10
+ # ~/.hermes-home HERMES_HOME (LOCAL). Secrets live here, everything else
11
+ # is symlinked to ~/hermes-bucket so Hermes data syncs.
12
+ # ~/.hermes Hermes Python install (code + venv)
13
+ #
14
+ # Why the shadow dir: Hermes hardcodes its secrets file at $HERMES_HOME/.env
15
+ # and atomically rewrites it on `hermes setup` / sanitization. If HERMES_HOME
16
+ # were the mount, those writes would land in a public bucket. The shadow dir
17
+ # keeps .env local while every other Hermes write still passes through to the
18
+ # bucket via symlink.
19
  #
20
  # bash <(curl -fsSL https://huggingface.co/merve/hermes-agent-bootstrap/resolve/main/bootstrap.sh)
21
  #
22
+ # Idempotent: re-runs are safe.
 
 
 
 
 
23
  # ============================================================================
24
  set -euo pipefail
25
 
26
  TEMPLATE="merve/hermes-agent"
27
  MOUNT="$HOME/hermes-bucket"
28
+ HOME_DIR="$HOME/.hermes-home"
29
+ LEGACY_SECRETS="$HOME/.hermes-secrets.env"
30
+ SECRETS="$HOME_DIR/.env"
31
 
32
  G='\033[0;32m'; Y='\033[0;33m'; C='\033[0;36m'; R='\033[0;31m'; N='\033[0m'
33
  say() { printf "${C}β†’${N} %s\n" "$*"; }
 
115
  fi
116
 
117
  # ----------------------------------------------------------------------------
118
+ # 6. Hermes Agent install
119
  # ----------------------------------------------------------------------------
120
  if ! command -v hermes >/dev/null 2>&1; then
121
  say "Installing Hermes Agent (this takes a minute)..."
 
125
  ok "Hermes: $(command -v hermes)"
126
 
127
  # ----------------------------------------------------------------------------
128
+ # 7. Shadow HERMES_HOME β€” keeps .env local, symlinks everything else to bucket
129
+ # ----------------------------------------------------------------------------
130
+ say "Setting up shadow HERMES_HOME at $HOME_DIR..."
131
+ mkdir -p "$HOME_DIR" "$HOME_DIR/audio_cache" "$HOME_DIR/image_cache" "$HOME_DIR/logs"
132
+
133
+ # Make sure bucket subdirs that Hermes writes to exist (so symlinks resolve)
134
+ for d in memories cron hooks pairing sessions; do
135
+ mkdir -p "$MOUNT/$d"
136
+ done
137
+
138
+ # Files mirrored from the bucket (read mostly; if Hermes ever rewrites one
139
+ # atomically the symlink severs and the local copy takes over β€” safe but no
140
+ # longer syncing for that file)
141
+ for f in config.yaml SOUL.md README.md .env.example; do
142
+ ln -sfn "$MOUNT/$f" "$HOME_DIR/$f"
143
+ done
144
+ # Directory trees that Hermes appends to: writes inside flow through to bucket
145
+ for d in skills memories cron hooks pairing sessions; do
146
+ ln -sfn "$MOUNT/$d" "$HOME_DIR/$d"
147
+ done
148
+ ok "Shadow dir wired: $HOME_DIR (.env stays local, data symlinks β†’ $MOUNT)"
149
+
150
+ # Migrate legacy secrets file from a previous bootstrap, if present
151
+ if [ -f "$LEGACY_SECRETS" ] && [ ! -f "$SECRETS" ]; then
152
+ cp "$LEGACY_SECRETS" "$SECRETS"
153
+ chmod 600 "$SECRETS"
154
+ warn "Migrated legacy $LEGACY_SECRETS β†’ $SECRETS"
155
+ warn " You can delete $LEGACY_SECRETS once you confirm things work."
156
+ fi
157
+
158
+ # ----------------------------------------------------------------------------
159
+ # 8. Telegram (required step)
160
  # ----------------------------------------------------------------------------
161
  printf "\n${C}Telegram setup${N}\n"
162
 
 
201
  fi
202
 
203
  # ----------------------------------------------------------------------------
204
+ # 9. Write secrets file (LOCAL, never reaches the bucket)
205
  # ----------------------------------------------------------------------------
206
  umask 077
207
  cat > "$SECRETS" <<EOF
208
+ # Hermes secrets β€” local-only ($HOME_DIR is HERMES_HOME, not a mount)
209
  HF_TOKEN=$HF_TOKEN_VAL
210
  TELEGRAM_BOT_TOKEN=$TG_TOKEN
211
  TELEGRAM_ALLOWED_USERS=$USER_ID
 
215
  ok "Secrets saved to $SECRETS (mode 600)"
216
 
217
  # ----------------------------------------------------------------------------
218
+ # 10. Shell aliases
219
  # ----------------------------------------------------------------------------
220
  SHELL_NAME="${SHELL##*/}"
221
  case "$SHELL_NAME" in
 
224
  *) SHELL_RC="$HOME/.profile" ;;
225
  esac
226
 
227
+ # Rewrite the aliases block if we already added one (keeps users on the
228
+ # latest definition β€” old runs used a different layout)
229
+ if [ -f "$SHELL_RC" ] && grep -q "# hermes-bucket aliases" "$SHELL_RC"; then
230
+ python3 - "$SHELL_RC" <<'PY'
231
+ import sys, pathlib
232
+ p = pathlib.Path(sys.argv[1])
233
+ text = p.read_text()
234
+ start = text.find("# hermes-bucket aliases")
235
+ if start == -1:
236
+ sys.exit(0)
237
+ end = text.find("\n\n", start)
238
+ end = len(text) if end == -1 else end
239
+ p.write_text(text[:start].rstrip() + "\n" + text[end:].lstrip("\n"))
240
+ PY
241
+ fi
242
+
243
+ cat >> "$SHELL_RC" <<EOF
244
 
245
+ # hermes-bucket aliases (added by bootstrap.sh β€” safe to remove if you'd rather export HERMES_HOME yourself)
246
+ alias hermes-here='HERMES_HOME=\$HOME/.hermes-home hermes'
247
+ alias hermes-gateway='HERMES_HOME=\$HOME/.hermes-home hermes gateway start'
248
  EOF
249
+ ok "Shell aliases written to $SHELL_RC"
 
 
 
250
 
251
  # ----------------------------------------------------------------------------
252
+ # 11. Summary + launch
253
  # ----------------------------------------------------------------------------
254
  cat <<EOF
255
 
256
  ${G}βœ“ Ready.${N}
257
 
258
+ Your bucket: https://huggingface.co/buckets/$BUCKET
259
+ Bucket mount: $MOUNT
260
+ HERMES_HOME: $HOME_DIR (secrets local; everything else symlinks to mount)
261
+ Model: Qwen/Qwen3.6-35B-A3B (HF Inference Providers β†’ deepinfra)
262
 
263
  ${C}hermes-here${N} β€” chat in your terminal
264
  ${C}hermes-gateway${N} β€” start Telegram bot (talk from your phone)
 
268
  if [ -t 0 ] && [ -t 1 ]; then
269
  say "Launching Hermes now..."
270
  sleep 1
271
+ export HERMES_HOME="$HOME_DIR"
 
272
  exec hermes
273
  else
274
  say "Run ${C}source $SHELL_RC${N} then ${C}hermes-here${N} to start chatting."