agenshield 0.11.3 → 0.11.4-beta.537

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/agenshield +69 -6
  2. package/package.json +1 -1
package/bin/agenshield CHANGED
@@ -90,6 +90,43 @@ find_installed() {
90
90
  return 1
91
91
  }
92
92
 
93
+ # ── Detect leftover AgenShield artifacts when no runnable binary remains ─────
94
+ # A half-finished prior uninstall (or a manually-deleted binary) leaves system
95
+ # state behind that deleting the binary alone does NOT remove: a dangling
96
+ # /usr/local/bin/agenshield symlink, the node-ca-trust LaunchAgent, a stale
97
+ # NODE_EXTRA_CA_CERTS in the launchd session, ~/.agenshield, the .app,
98
+ # LaunchDaemons, … `uninstall` uses this to decide whether to bootstrap the
99
+ # real uninstaller vs. report "nothing to do". `if`-guards (not `&&` chains)
100
+ # keep this safe under `set -e`.
101
+ agenshield_residue_present() {
102
+ if [ -L /usr/local/bin/agenshield ] || [ -e /usr/local/bin/agenshield ]; then return 0; fi
103
+ if [ -d "$HOME/.agenshield" ]; then return 0; fi
104
+ if [ -d /Library/AgenShield ]; then return 0; fi
105
+ if [ -d /opt/agenshield ]; then return 0; fi
106
+ if [ -d /Applications/AgenShield.app ]; then return 0; fi
107
+ if [ -f /Library/LaunchDaemons/com.frontegg.AgenShield.daemon.plist ]; then return 0; fi
108
+ if [ -f /Library/LaunchDaemons/com.frontegg.AgenShield.privilege-helper.plist ]; then return 0; fi
109
+ if [ -f "$HOME/Library/LaunchAgents/com.frontegg.AgenShield.node-ca-trust.plist" ]; then return 0; fi
110
+ if [ -f "$HOME/Library/LaunchAgents/com.frontegg.AgenShield.menubar.plist" ]; then return 0; fi
111
+ if command -v launchctl >/dev/null 2>&1; then
112
+ _ca="$(launchctl getenv NODE_EXTRA_CA_CERTS 2>/dev/null || true)"
113
+ if [ -n "$_ca" ]; then return 0; fi
114
+ fi
115
+ return 1
116
+ }
117
+
118
+ # Manual remediation printed when we cannot bootstrap the real uninstaller.
119
+ print_manual_cleanup_hint() {
120
+ echo " Remove the leftover artifacts manually:" >&2
121
+ echo " sudo rm -f /usr/local/bin/agenshield" >&2
122
+ echo " sudo rm -rf /Library/AgenShield /opt/agenshield /Applications/AgenShield.app" >&2
123
+ echo " rm -rf \"\$HOME/.agenshield\"" >&2
124
+ echo " rm -f \"\$HOME/Library/LaunchAgents/com.frontegg.AgenShield.\"*.plist" >&2
125
+ echo " launchctl unsetenv NODE_EXTRA_CA_CERTS; unset NODE_EXTRA_CA_CERTS" >&2
126
+ echo " Then fully quit & reopen your terminal and GUI apps (Cursor, Claude Desktop, VS Code)" >&2
127
+ echo " so they drop the stale NODE_EXTRA_CA_CERTS value." >&2
128
+ }
129
+
93
130
  # ── `install` → run the full installer with the user's args ─────────────────
94
131
  # install.sh handles the macOS .pkg / Linux tarball download + checksum verify
95
132
  # + enrollment (--token/--cloud-url/--org) + service setup.
@@ -110,17 +147,43 @@ if [ "${1:-}" = "install" ]; then
110
147
  exec env AGENSHIELD_VERSION="$WRAPPER_VERSION" sh "$INSTALLER" "$@"
111
148
  fi
112
149
 
113
- # ── `uninstall` → delegate if installed; NEVER bootstrap-install ─────────────
114
- # `npx agenshield uninstall` must never reinstall AgenShield just to remove it.
115
- # The generic path below bootstraps (downloads + runs install.sh) whenever no
116
- # binary is found so a SECOND `uninstall` after the first one removed the
117
- # binary used to re-download and launch the INSTALLER. If the binary is already
118
- # gone, there is nothing to uninstall: report and exit cleanly instead.
150
+ # ── `uninstall` → delegate if installed, else bootstrap+run when residue remains ─
151
+ # `npx agenshield uninstall` must remove AgenShield even after the binary itself
152
+ # is gone but system residue remains. Three cases:
153
+ # 1. A runnable binary exists delegate to it (the real, thorough uninstaller).
154
+ # 2. No binary, but residue → bootstrap the signed binary from GitHub Releases
155
+ # detected (--skip-services) and run the REAL uninstaller
156
+ # the only thing that removes the keychain CA,
157
+ # sandbox users, ACLs, the node-ca-trust LaunchAgent
158
+ # + its NODE_EXTRA_CA_CERTS env, LaunchDaemons, etc.
159
+ # If the bootstrap download fails (offline / no
160
+ # published release), print manual cleanup steps.
161
+ # 3. No binary, no residue → genuinely nothing to do; report and exit 0.
162
+ # Bootstrapping ONLY when residue is present avoids the re-download churn the old
163
+ # code guarded against: a successful uninstall removes the residue, so the next
164
+ # run lands in case 3 and exits cleanly.
119
165
  if [ "${1:-}" = "uninstall" ]; then
120
166
  BIN="$(find_installed || true)"
121
167
  if [ -n "$BIN" ]; then
122
168
  exec "$BIN" "$@"
123
169
  fi
170
+ if agenshield_residue_present; then
171
+ if [ ! -f "$INSTALLER" ]; then
172
+ echo "agenshield: leftover AgenShield artifacts detected, but the bundled installer is missing." >&2
173
+ print_manual_cleanup_hint
174
+ exit 1
175
+ fi
176
+ echo "agenshield: binary missing but leftover artifacts detected — bootstrapping${WRAPPER_VERSION:+ v$WRAPPER_VERSION} to run a full uninstall…" >&2
177
+ if AGENSHIELD_VERSION="$WRAPPER_VERSION" sh "$INSTALLER" --skip-services >&2; then
178
+ BIN="$(find_installed || true)"
179
+ if [ -n "$BIN" ]; then
180
+ exec "$BIN" "$@"
181
+ fi
182
+ fi
183
+ echo "agenshield: could not bootstrap the uninstaller (download or install failed)." >&2
184
+ print_manual_cleanup_hint
185
+ exit 1
186
+ fi
124
187
  echo "agenshield: not installed — nothing to uninstall." >&2
125
188
  exit 0
126
189
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenshield",
3
- "version": "0.11.3",
3
+ "version": "0.11.4-beta.537",
4
4
  "description": "AgenShield — AI Agent Security Platform",
5
5
  "bin": {
6
6
  "agenshield": "bin/agenshield"