1919INSTALLER_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
2020LIB_DIR=" $INSTALLER_DIR /lib"
2121AGENT_PACK_CLONE_ROOT=" "
22+ AGENT_PACK_TEMP_ROOT=" "
23+
24+ _ap_cleanup () {
25+ if [ -n " $AGENT_PACK_TEMP_ROOT " ] && [ -d " $AGENT_PACK_TEMP_ROOT " ]; then
26+ rm -rf " $AGENT_PACK_TEMP_ROOT "
27+ fi
28+ }
29+
30+ trap _ap_cleanup EXIT
2231
2332# If running via curl | bash, download the full package first.
2433# This bootstrap can't read config/defaults.json yet (we haven't fetched it),
@@ -28,6 +37,7 @@ AGENT_PACK_REPO="https://github.com/SenseTime-FVG/agent_pack.git"
2837if [ ! -d " $LIB_DIR " ]; then
2938 echo " [*] Downloading Agent Pack installer..."
3039 TMPDIR=$( mktemp -d)
40+ AGENT_PACK_TEMP_ROOT=" $TMPDIR "
3141 _cloned=0
3242 _bootstrap_try () {
3343 git clone -q --depth 1 " $1 " " $TMPDIR /agent-pack" 2> /dev/null
8797# install_openclaw can share the same source tree. Runs after CN detection
8898# so prefetch itself honors mirrors.
8999if [ -z " $AGENT_PACK_CLONE_ROOT " ]; then
90- AGENT_PACK_CLONE_ROOT=" $( mktemp -d) /agent_pack"
100+ AGENT_PACK_TEMP_ROOT=" $( mktemp -d) "
101+ AGENT_PACK_CLONE_ROOT=" $AGENT_PACK_TEMP_ROOT /agent_pack"
91102 echo " [*] Pre-fetching agent_pack (shared across product installs)..."
92103 if ! bash " $_AP_SHARED_DIR /prefetch-agent-pack.sh" " $AGENT_PACK_CLONE_ROOT " ; then
93104 echo " [!] Failed to pre-fetch agent_pack." >&2
@@ -106,24 +117,26 @@ echo ""
106117# Ask up front (mirrors the Windows installer wizard) so the user is done
107118# with interactive prompts before the long-running installs start.
108119collect_llm_config
120+ verify_llm_config_interactive || exit 1
109121
110122# ---- Step 2: Product Selection ----
111- echo " "
112- echo " Which products would you like to install?"
113- echo " 1) Hermes Agent"
114- echo " 2) OpenClaw"
115- echo " 3) Both"
116- echo " "
117- read -rp " Choice [1]: " product_choice
118- product_choice=" ${product_choice:- 1} "
119-
120123SELECTED_PRODUCTS=()
121- case " $product_choice " in
122- 1) SELECTED_PRODUCTS=(" hermes" ) ;;
123- 2) SELECTED_PRODUCTS=(" openclaw" ) ;;
124- 3) SELECTED_PRODUCTS=(" hermes" " openclaw" ) ;;
125- * ) echo " Invalid choice. Defaulting to Hermes Agent." ; SELECTED_PRODUCTS=(" hermes" ) ;;
126- esac
124+ while true ; do
125+ echo " "
126+ echo " Which products would you like to install?"
127+ echo " 1) Hermes Agent"
128+ echo " 2) OpenClaw"
129+ echo " 3) Both"
130+ echo " "
131+ read -rp " Choice [1/2/3]: " product_choice
132+
133+ case " $product_choice " in
134+ 1) SELECTED_PRODUCTS=(" hermes" ) ; break ;;
135+ 2) SELECTED_PRODUCTS=(" openclaw" ) ; break ;;
136+ 3) SELECTED_PRODUCTS=(" hermes" " openclaw" ) ; break ;;
137+ * ) echo " Please choose 1, 2, or 3." ;;
138+ esac
139+ done
127140
128141echo " "
129142echo " Selected: ${SELECTED_PRODUCTS[*]} "
@@ -185,31 +198,89 @@ _ap_augment_path() {
185198 export PATH
186199}
187200
201+ _ap_resolve_cli () {
202+ local name=" $1 "
203+ local candidate=" "
204+
205+ hash -r 2> /dev/null || true
206+ candidate=" $( command -v " $name " 2> /dev/null || true) "
207+ if [ -n " $candidate " ] && [ -x " $candidate " ]; then
208+ printf ' %s\n' " $candidate "
209+ return 0
210+ fi
211+
212+ case " $name " in
213+ hermes)
214+ for candidate in \
215+ " $HOME /.local/bin/hermes" \
216+ " $HOME /.hermes/node/bin/hermes" \
217+ " $HERMES_INSTALL_DIR /node/bin/hermes" \
218+ " /usr/local/bin/hermes" \
219+ " /usr/bin/hermes" ; do
220+ if [ -n " $candidate " ] && [ -x " $candidate " ]; then
221+ printf ' %s\n' " $candidate "
222+ return 0
223+ fi
224+ done
225+ ;;
226+ openclaw)
227+ for candidate in \
228+ " $HOME /.local/bin/openclaw" \
229+ " /usr/local/bin/openclaw" \
230+ " /usr/bin/openclaw" ; do
231+ if [ -n " $candidate " ] && [ -x " $candidate " ]; then
232+ printf ' %s\n' " $candidate "
233+ return 0
234+ fi
235+ done
236+ ;;
237+ esac
238+
239+ return 1
240+ }
241+
188242_ap_schedule_dashboard () {
243+ local openclaw_cli=" $1 "
189244 # Give the gateway a few seconds to bind before opening the browser
190245 # (dashboard itself doesn't probe, so we sleep for the user's sake).
191- ( sleep 3 && openclaw dashboard > /dev/null 2>&1 ) &
246+ ( sleep 3 && " $openclaw_cli " dashboard > /dev/null 2>&1 ) &
192247 disown 2> /dev/null || true
193248}
194249
195250_ap_augment_path
196251
252+ _HERMES_CLI=" $( _ap_resolve_cli hermes || true) "
253+ _OPENCLAW_CLI=" $( _ap_resolve_cli openclaw || true) "
254+
255+ if _ap_has hermes && [ -z " $_HERMES_CLI " ]; then
256+ echo " [!] Hermes was installed but the hermes CLI could not be found." >&2
257+ exit 1
258+ fi
259+
260+ if _ap_has openclaw && [ -z " $_OPENCLAW_CLI " ]; then
261+ echo " [!] OpenClaw was installed but the openclaw CLI could not be found." >&2
262+ exit 1
263+ fi
264+
265+ trap - EXIT
266+ _ap_cleanup
267+
197268if _ap_has openclaw && _ap_has hermes; then
198269 _openclaw_log=" $HOME /.openclaw/gateway.log"
199270 mkdir -p " $( dirname " $_openclaw_log " ) "
200271 echo " [*] Starting openclaw gateway in the background (log: $_openclaw_log )..."
201- nohup openclaw gateway --verbose > " $_openclaw_log " 2>&1 &
272+ nohup " $_OPENCLAW_CLI " gateway --verbose > " $_openclaw_log " 2>&1 &
202273 disown 2> /dev/null || true
203- _ap_schedule_dashboard
274+ _ap_schedule_dashboard " $_OPENCLAW_CLI "
204275 echo " [*] Opening OpenClaw dashboard in your browser shortly..."
205276 echo " [*] Starting hermes in this window..."
206- exec hermes
277+ exec " $_HERMES_CLI "
207278elif _ap_has hermes; then
208279 echo " [*] Starting hermes in this window..."
209- exec hermes
280+ exec " $_HERMES_CLI "
210281elif _ap_has openclaw; then
211- _ap_schedule_dashboard
282+ _ap_schedule_dashboard " $_OPENCLAW_CLI "
212283 echo " [*] Opening OpenClaw dashboard in your browser shortly..."
213284 echo " [*] Starting openclaw gateway in this window..."
214- exec openclaw gateway --verbose
285+ exec " $_OPENCLAW_CLI " gateway --verbose
215286fi
0 commit comments