ework-aio 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/install.sh +100 -23
  2. package/package.json +1 -1
package/bin/install.sh CHANGED
@@ -12,6 +12,13 @@
12
12
 
13
13
  set -euo pipefail
14
14
 
15
+ # ERR trap: when `set -e` kills the script, print the line + last command so
16
+ # the user sees why instead of an empty prompt. Tricky failure modes (root
17
+ # scope + polkit redirect, missing systemd PID 1, journalctl-as-root) all
18
+ # manifest as silent exit at a systemctl call — without this trace, the user
19
+ # just sees the prompt return and assumes install succeeded.
20
+ trap 'rc=$?; if [[ $rc -ne 0 ]]; then echo "${c_red}✗${c_reset} install.sh exited with code $rc at line $LINENO (most recent command: ${BASH_COMMAND})" >&2; echo " If systemd is unavailable on this host, retry with: ework-aio install --no-start" >&2; echo " Then start services with: ework-aio start" >&2; fi' ERR
21
+
15
22
  # ─── Pretty output ──────────────────────────────────────────────────────────
16
23
  c_reset=$'\033[0m'; c_bold=$'\033[1m'; c_dim=$'\033[2m'
17
24
  c_red=$'\033[31m'; c_grn=$'\033[32m'; c_ylw=$'\033[33m'; c_blu=$'\033[34m'
@@ -681,22 +688,59 @@ write_unit_file \
681
688
  ok "Wrote $WEB_UNIT"
682
689
 
683
690
  # ─── Reload + start ework-web ──────────────────────────────────────────────
684
- ctl daemon-reload
685
- if [[ "$NO_START" == "0" ]]; then
691
+ # systemd calls here are best-effort. If systemd isn't functional on this host
692
+ # (containers without systemd PID 1, polkit redirects under sudo, missing
693
+ # /etc/systemd/system) we still want install to complete so the user can run
694
+ # `ework-aio start` (PID-file mode) against the scaffolded .env.
695
+ SYSTEMD_OK=1
696
+ if ! ctl daemon-reload; then
697
+ warn "systemctl daemon-reload failed — systemd may be unavailable on this host."
698
+ SYSTEMD_OK=0
699
+ fi
700
+
701
+ if [[ "$NO_START" == "0" && "$SYSTEMD_OK" == "1" ]]; then
686
702
  log "Starting ework-web..."
687
- ctl enable ework-web.service
688
- ctl restart ework-web.service
703
+ ctl enable ework-web.service || { warn "systemctl enable failed"; SYSTEMD_OK=0; }
704
+ if [[ "$SYSTEMD_OK" == "1" ]]; then
705
+ ctl restart ework-web.service || { warn "systemctl restart failed"; SYSTEMD_OK=0; }
706
+ fi
707
+ if [[ "$SYSTEMD_OK" == "1" ]]; then
708
+ for i in $(seq 1 60); do
709
+ if curl -sf -o /dev/null "http://127.0.0.1:$WORK_PORT/login"; then
710
+ ok "ework-web listening on :$WORK_PORT (after ${i} half-seconds)"
711
+ break
712
+ fi
713
+ sleep 0.5
714
+ [[ $i -eq 60 ]] && { warn "ework-web did not come up via systemd in 30s. Falling back to PID-file mode."; SYSTEMD_OK=0; }
715
+ done
716
+ fi
717
+ else
718
+ warn "--no-start: unit enabled but not started"
719
+ ctl enable ework-web.service 2>/dev/null || true
720
+ fi
721
+
722
+ # ─── PID-file mode fallback for bot bootstrap ──────────────────────────────
723
+ # If systemd couldn't start web (or we're on a host without systemd), bring
724
+ # web up briefly via the PID-file path so the bot user + PAT bootstrap can
725
+ # still complete. We leave web running in PID-file mode so subsequent curl
726
+ # calls to :WORK_PORT succeed.
727
+ if [[ "$NO_START" == "0" && "$SYSTEMD_OK" == "0" ]]; then
728
+ log "Starting ework-web via PID-file mode (nohup) for bot bootstrap..."
729
+ WEB_LOG_FILE="$DATA_DIR/run/web.log"
730
+ mkdir -p "$(dirname "$WEB_LOG_FILE")"
731
+ setsid nohup "$EWORK_WEB_BIN" >>"$WEB_LOG_FILE" 2>&1 </dev/null &
732
+ WEB_PID=$!
733
+ disown "$WEB_PID" 2>/dev/null || true
734
+ printf '%s\n' "$WEB_PID" > "$DATA_DIR/run/web.pid"
735
+ ok "ework-web started in PID-file mode (pid $WEB_PID, log $WEB_LOG_FILE)"
689
736
  for i in $(seq 1 60); do
690
737
  if curl -sf -o /dev/null "http://127.0.0.1:$WORK_PORT/login"; then
691
- ok "ework-web listening on :$WORK_PORT (after ${i} half-seconds)"
738
+ ok "ework-web listening on :$WORK_PORT (after ${i} half-seconds, PID-file mode)"
692
739
  break
693
740
  fi
694
741
  sleep 0.5
695
- [[ $i -eq 60 ]] && die "ework-web did not come up in 30s. Check: journalctl $SCOPENAME -u ework-web.service -n 50"
742
+ [[ $i -eq 60 ]] && die "ework-web did not come up in 30s. Tail of $WEB_LOG_FILE: $(tail -n 20 "$WEB_LOG_FILE" 2>/dev/null)"
696
743
  done
697
- else
698
- warn "--no-start: unit enabled but not started"
699
- ctl enable ework-web.service
700
744
  fi
701
745
 
702
746
  # ─── Bootstrap bot user + PAT (idempotent) ─────────────────────────────────
@@ -709,10 +753,23 @@ COOKIE_SIG=$(printf '%s' "$WORK_TOKEN_VAL" \
709
753
  AUTH_COOKIE="ework_auth=${WORK_TOKEN_VAL}.${COOKIE_SIG}"
710
754
 
711
755
  BOT_TOKEN=""
756
+ BOT_BOOTSTRAP_OK=1
712
757
  if [[ -f "$BOT_TOKEN_FILE" ]]; then
713
758
  BOT_TOKEN=$(cat "$BOT_TOKEN_FILE")
714
759
  ok "Reusing saved bot token from $BOT_TOKEN_FILE"
715
760
  else
761
+ # Pre-flight: web must be reachable for the bot bootstrap HTTP calls below.
762
+ # In --no-start mode OR on hosts where systemd couldn't bring web up, skip
763
+ # the bootstrap entirely — daemon .env still gets written (with empty token)
764
+ # so the user can `ework-aio start` and re-run install later.
765
+ if ! curl -sf -o /dev/null "http://127.0.0.1:$WORK_PORT/login"; then
766
+ warn "ework-web not reachable at :$WORK_PORT — skipping bot bootstrap."
767
+ warn "Daemon will not be able to talk to web until you re-run install with web running."
768
+ BOT_BOOTSTRAP_OK=0
769
+ fi
770
+ fi
771
+
772
+ if [[ "$BOT_BOOTSTRAP_OK" == "1" && ! -f "$BOT_TOKEN_FILE" ]]; then
716
773
  log "Bootstrapping bot user '$BOT_NAME'..."
717
774
  BOT_PW=$(openssl rand -hex 24)
718
775
  CREATE_CODE=$(curl -sS -o /dev/null -w '%{http_code}' -X POST \
@@ -725,9 +782,11 @@ else
725
782
  case "$CREATE_CODE" in
726
783
  303) ok "Bot user '$BOT_NAME' created" ;;
727
784
  400|409) warn "Bot user '$BOT_NAME' already exists (continuing)" ;;
728
- *) die "Failed to create bot user: HTTP $CREATE_CODE" ;;
785
+ *) warn "Failed to create bot user: HTTP $CREATE_CODE — skipping PAT mint; daemon will not be able to talk to web until re-run"; BOT_BOOTSTRAP_OK=0 ;;
729
786
  esac
787
+ fi
730
788
 
789
+ if [[ "$BOT_BOOTSTRAP_OK" == "1" && ! -f "$BOT_TOKEN_FILE" ]]; then
731
790
  log "Logging in as bot to mint PAT..."
732
791
  COOKIE_JAR=$(mktemp)
733
792
  LOGIN_CODE=$(curl -sS -c "$COOKIE_JAR" -X POST "http://127.0.0.1:$WORK_PORT/login" \
@@ -736,18 +795,25 @@ else
736
795
  -o /dev/null -w '%{http_code}') || LOGIN_CODE=000
737
796
  BOT_COOKIE=$(awk '/ework_auth/ {print $7}' "$COOKIE_JAR")
738
797
  rm -f "$COOKIE_JAR"
739
- [[ "$LOGIN_CODE" == "302" && -n "$BOT_COOKIE" ]] \
740
- || die "Bot login failed: HTTP $LOGIN_CODE"
798
+ if [[ "$LOGIN_CODE" != "302" || -z "$BOT_COOKIE" ]]; then
799
+ warn "Bot login failed: HTTP $LOGIN_CODE — skipping PAT mint"
800
+ BOT_BOOTSTRAP_OK=0
801
+ fi
802
+ fi
741
803
 
804
+ if [[ "$BOT_BOOTSTRAP_OK" == "1" && ! -f "$BOT_TOKEN_FILE" ]]; then
742
805
  log "Minting PAT..."
743
806
  PAT_RES=$(curl -sS -X POST "http://127.0.0.1:$WORK_PORT/me/tokens/create" \
744
807
  -H "Cookie: ework_auth=$BOT_COOKIE" \
745
808
  --data-urlencode "name=aio-$(date +%s)")
746
809
  BOT_TOKEN=$(printf '%s' "$PAT_RES" | grep -oE 'id="t">[a-f0-9]{40}<' | grep -oE '[a-f0-9]{40}' | head -1 || true)
747
- [[ -n "$BOT_TOKEN" ]] || die "Could not extract PAT from token-create response"
748
- printf '%s' "$BOT_TOKEN" > "$BOT_TOKEN_FILE"
749
- chmod 600 "$BOT_TOKEN_FILE"
750
- ok "Bot PAT saved to $BOT_TOKEN_FILE"
810
+ if [[ -z "$BOT_TOKEN" ]]; then
811
+ warn "Could not extract PAT from token-create response — daemon .env will have empty token"
812
+ else
813
+ printf '%s' "$BOT_TOKEN" > "$BOT_TOKEN_FILE"
814
+ chmod 600 "$BOT_TOKEN_FILE"
815
+ ok "Bot PAT saved to $BOT_TOKEN_FILE"
816
+ fi
751
817
  fi
752
818
 
753
819
  # ─── Write ework-daemon .env ───────────────────────────────────────────────
@@ -766,19 +832,30 @@ write_unit_file \
766
832
  # (trailing " \"\"" is a no-op separator; kept for future extra env injection)
767
833
  ok "Wrote $DAEMON_UNIT"
768
834
 
769
- ctl daemon-reload
770
- if [[ "$NO_START" == "0" ]]; then
835
+ ctl daemon-reload 2>/dev/null || true
836
+ if [[ "$NO_START" == "0" && "$SYSTEMD_OK" == "1" ]]; then
771
837
  log "Starting ework-daemon..."
772
- ctl enable ework-daemon.service
773
- ctl restart ework-daemon.service
838
+ ctl enable ework-daemon.service 2>/dev/null || true
839
+ ctl restart ework-daemon.service 2>/dev/null || warn "ework-daemon restart via systemd failed; use 'ework-aio start daemon' for PID-file mode"
774
840
  sleep 1
775
- if ctl is-active --quiet ework-daemon.service; then
841
+ if ctl is-active --quiet ework-daemon.service 2>/dev/null; then
776
842
  ok "ework-daemon active"
777
843
  else
778
- warn "ework-daemon did not report active; check: journalctl $SCOPENAME -u ework-daemon.service -n 50"
844
+ warn "ework-daemon did not report active; run 'ework-aio start daemon' for PID-file mode"
779
845
  fi
780
846
  else
781
- ctl enable ework-daemon.service
847
+ ctl enable ework-daemon.service 2>/dev/null || true
848
+ fi
849
+
850
+ if [[ "$SYSTEMD_OK" == "0" ]]; then
851
+ hr
852
+ warn "systemd mode did not come up cleanly on this host."
853
+ warn "Services are scaffolded but not auto-started under systemd."
854
+ warn "Use PID-file mode instead:"
855
+ echo " ework-aio start # start web + daemon in background"
856
+ echo " ework-aio ps # check status"
857
+ echo " ework-aio logs web # tail web log"
858
+ hr
782
859
  fi
783
860
 
784
861
  # ─── Register opencode-ework plugin ────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ework-aio",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "description": "All-in-one installer for ework (issue tracker) + ework-daemon (AI bridge) + opencode-ework (plugin). One command: npm i -g ework-aio && ework-aio install.",
5
5
  "type": "module",
6
6
  "license": "MIT",