nox-openclaw-hunter 1.0.0

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 (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +140 -0
  3. package/bin/nox.js +2 -0
  4. package/dist/branding.d.ts +39 -0
  5. package/dist/branding.d.ts.map +1 -0
  6. package/dist/branding.js +66 -0
  7. package/dist/branding.js.map +1 -0
  8. package/dist/cli.d.ts +15 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +94 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/export.d.ts +21 -0
  13. package/dist/commands/export.d.ts.map +1 -0
  14. package/dist/commands/export.js +616 -0
  15. package/dist/commands/export.js.map +1 -0
  16. package/dist/commands/index.d.ts +8 -0
  17. package/dist/commands/index.d.ts.map +1 -0
  18. package/dist/commands/index.js +8 -0
  19. package/dist/commands/index.js.map +1 -0
  20. package/dist/commands/isolate.d.ts +30 -0
  21. package/dist/commands/isolate.d.ts.map +1 -0
  22. package/dist/commands/isolate.js +547 -0
  23. package/dist/commands/isolate.js.map +1 -0
  24. package/dist/commands/purge.d.ts +22 -0
  25. package/dist/commands/purge.d.ts.map +1 -0
  26. package/dist/commands/purge.js +295 -0
  27. package/dist/commands/purge.js.map +1 -0
  28. package/dist/commands/scan.d.ts +23 -0
  29. package/dist/commands/scan.d.ts.map +1 -0
  30. package/dist/commands/scan.js +155 -0
  31. package/dist/commands/scan.js.map +1 -0
  32. package/dist/detector/app-bundle.d.ts +13 -0
  33. package/dist/detector/app-bundle.d.ts.map +1 -0
  34. package/dist/detector/app-bundle.js +27 -0
  35. package/dist/detector/app-bundle.js.map +1 -0
  36. package/dist/detector/cli-binary.d.ts +12 -0
  37. package/dist/detector/cli-binary.d.ts.map +1 -0
  38. package/dist/detector/cli-binary.js +66 -0
  39. package/dist/detector/cli-binary.js.map +1 -0
  40. package/dist/detector/config.d.ts +21 -0
  41. package/dist/detector/config.d.ts.map +1 -0
  42. package/dist/detector/config.js +337 -0
  43. package/dist/detector/config.js.map +1 -0
  44. package/dist/detector/detection-config.d.ts +24 -0
  45. package/dist/detector/detection-config.d.ts.map +1 -0
  46. package/dist/detector/detection-config.js +242 -0
  47. package/dist/detector/detection-config.js.map +1 -0
  48. package/dist/detector/docker.d.ts +10 -0
  49. package/dist/detector/docker.d.ts.map +1 -0
  50. package/dist/detector/docker.js +94 -0
  51. package/dist/detector/docker.js.map +1 -0
  52. package/dist/detector/index.d.ts +50 -0
  53. package/dist/detector/index.d.ts.map +1 -0
  54. package/dist/detector/index.js +155 -0
  55. package/dist/detector/index.js.map +1 -0
  56. package/dist/detector/network.d.ts +34 -0
  57. package/dist/detector/network.d.ts.map +1 -0
  58. package/dist/detector/network.js +205 -0
  59. package/dist/detector/network.js.map +1 -0
  60. package/dist/detector/process.d.ts +16 -0
  61. package/dist/detector/process.d.ts.map +1 -0
  62. package/dist/detector/process.js +47 -0
  63. package/dist/detector/process.js.map +1 -0
  64. package/dist/detector/service.d.ts +17 -0
  65. package/dist/detector/service.d.ts.map +1 -0
  66. package/dist/detector/service.js +51 -0
  67. package/dist/detector/service.js.map +1 -0
  68. package/dist/enforcer/docker-cleaner.d.ts +30 -0
  69. package/dist/enforcer/docker-cleaner.d.ts.map +1 -0
  70. package/dist/enforcer/docker-cleaner.js +163 -0
  71. package/dist/enforcer/docker-cleaner.js.map +1 -0
  72. package/dist/enforcer/file-remover.d.ts +34 -0
  73. package/dist/enforcer/file-remover.d.ts.map +1 -0
  74. package/dist/enforcer/file-remover.js +137 -0
  75. package/dist/enforcer/file-remover.js.map +1 -0
  76. package/dist/enforcer/index.d.ts +33 -0
  77. package/dist/enforcer/index.d.ts.map +1 -0
  78. package/dist/enforcer/index.js +142 -0
  79. package/dist/enforcer/index.js.map +1 -0
  80. package/dist/enforcer/process-killer.d.ts +18 -0
  81. package/dist/enforcer/process-killer.d.ts.map +1 -0
  82. package/dist/enforcer/process-killer.js +80 -0
  83. package/dist/enforcer/process-killer.js.map +1 -0
  84. package/dist/enforcer/service-stopper.d.ts +23 -0
  85. package/dist/enforcer/service-stopper.d.ts.map +1 -0
  86. package/dist/enforcer/service-stopper.js +95 -0
  87. package/dist/enforcer/service-stopper.js.map +1 -0
  88. package/dist/index.d.ts +6 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +10 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/isolator/firewall.d.ts +25 -0
  93. package/dist/isolator/firewall.d.ts.map +1 -0
  94. package/dist/isolator/firewall.js +114 -0
  95. package/dist/isolator/firewall.js.map +1 -0
  96. package/dist/isolator/index.d.ts +63 -0
  97. package/dist/isolator/index.d.ts.map +1 -0
  98. package/dist/isolator/index.js +201 -0
  99. package/dist/isolator/index.js.map +1 -0
  100. package/dist/isolator/lockdown.d.ts +22 -0
  101. package/dist/isolator/lockdown.d.ts.map +1 -0
  102. package/dist/isolator/lockdown.js +401 -0
  103. package/dist/isolator/lockdown.js.map +1 -0
  104. package/dist/isolator/quarantine.d.ts +39 -0
  105. package/dist/isolator/quarantine.d.ts.map +1 -0
  106. package/dist/isolator/quarantine.js +364 -0
  107. package/dist/isolator/quarantine.js.map +1 -0
  108. package/dist/mdm/index.d.ts +93 -0
  109. package/dist/mdm/index.d.ts.map +1 -0
  110. package/dist/mdm/index.js +414 -0
  111. package/dist/mdm/index.js.map +1 -0
  112. package/dist/mdm/intune.d.ts +69 -0
  113. package/dist/mdm/intune.d.ts.map +1 -0
  114. package/dist/mdm/intune.js +409 -0
  115. package/dist/mdm/intune.js.map +1 -0
  116. package/dist/mdm/jamf.d.ts +58 -0
  117. package/dist/mdm/jamf.d.ts.map +1 -0
  118. package/dist/mdm/jamf.js +441 -0
  119. package/dist/mdm/jamf.js.map +1 -0
  120. package/dist/mdm/jumpcloud.d.ts +73 -0
  121. package/dist/mdm/jumpcloud.d.ts.map +1 -0
  122. package/dist/mdm/jumpcloud.js +470 -0
  123. package/dist/mdm/jumpcloud.js.map +1 -0
  124. package/dist/mdm/templates/detect.ps1.d.ts +30 -0
  125. package/dist/mdm/templates/detect.ps1.d.ts.map +1 -0
  126. package/dist/mdm/templates/detect.ps1.js +463 -0
  127. package/dist/mdm/templates/detect.ps1.js.map +1 -0
  128. package/dist/mdm/templates/detect.sh.d.ts +30 -0
  129. package/dist/mdm/templates/detect.sh.d.ts.map +1 -0
  130. package/dist/mdm/templates/detect.sh.js +474 -0
  131. package/dist/mdm/templates/detect.sh.js.map +1 -0
  132. package/dist/mdm/templates/enforce.ps1.d.ts +33 -0
  133. package/dist/mdm/templates/enforce.ps1.d.ts.map +1 -0
  134. package/dist/mdm/templates/enforce.ps1.js +681 -0
  135. package/dist/mdm/templates/enforce.ps1.js.map +1 -0
  136. package/dist/mdm/templates/enforce.sh.d.ts +33 -0
  137. package/dist/mdm/templates/enforce.sh.d.ts.map +1 -0
  138. package/dist/mdm/templates/enforce.sh.js +591 -0
  139. package/dist/mdm/templates/enforce.sh.js.map +1 -0
  140. package/dist/platform/darwin.d.ts +6 -0
  141. package/dist/platform/darwin.d.ts.map +1 -0
  142. package/dist/platform/darwin.js +192 -0
  143. package/dist/platform/darwin.js.map +1 -0
  144. package/dist/platform/index.d.ts +43 -0
  145. package/dist/platform/index.d.ts.map +1 -0
  146. package/dist/platform/index.js +27 -0
  147. package/dist/platform/index.js.map +1 -0
  148. package/dist/platform/linux.d.ts +6 -0
  149. package/dist/platform/linux.d.ts.map +1 -0
  150. package/dist/platform/linux.js +134 -0
  151. package/dist/platform/linux.js.map +1 -0
  152. package/dist/platform/windows.d.ts +6 -0
  153. package/dist/platform/windows.d.ts.map +1 -0
  154. package/dist/platform/windows.js +134 -0
  155. package/dist/platform/windows.js.map +1 -0
  156. package/dist/reporter/console.d.ts +27 -0
  157. package/dist/reporter/console.d.ts.map +1 -0
  158. package/dist/reporter/console.js +431 -0
  159. package/dist/reporter/console.js.map +1 -0
  160. package/dist/reporter/index.d.ts +11 -0
  161. package/dist/reporter/index.d.ts.map +1 -0
  162. package/dist/reporter/index.js +13 -0
  163. package/dist/reporter/index.js.map +1 -0
  164. package/dist/reporter/json.d.ts +61 -0
  165. package/dist/reporter/json.d.ts.map +1 -0
  166. package/dist/reporter/json.js +75 -0
  167. package/dist/reporter/json.js.map +1 -0
  168. package/dist/reporter/webhook.d.ts +57 -0
  169. package/dist/reporter/webhook.d.ts.map +1 -0
  170. package/dist/reporter/webhook.js +230 -0
  171. package/dist/reporter/webhook.js.map +1 -0
  172. package/dist/types/config.d.ts +116 -0
  173. package/dist/types/config.d.ts.map +1 -0
  174. package/dist/types/config.js +6 -0
  175. package/dist/types/config.js.map +1 -0
  176. package/dist/types/detection.d.ts +85 -0
  177. package/dist/types/detection.d.ts.map +1 -0
  178. package/dist/types/detection.js +5 -0
  179. package/dist/types/detection.js.map +1 -0
  180. package/dist/types/enforcement.d.ts +33 -0
  181. package/dist/types/enforcement.d.ts.map +1 -0
  182. package/dist/types/enforcement.js +5 -0
  183. package/dist/types/enforcement.js.map +1 -0
  184. package/dist/types/index.d.ts +8 -0
  185. package/dist/types/index.d.ts.map +1 -0
  186. package/dist/types/index.js +8 -0
  187. package/dist/types/index.js.map +1 -0
  188. package/dist/types/isolation.d.ts +55 -0
  189. package/dist/types/isolation.d.ts.map +1 -0
  190. package/dist/types/isolation.js +5 -0
  191. package/dist/types/isolation.js.map +1 -0
  192. package/dist/utils/exec.d.ts +48 -0
  193. package/dist/utils/exec.d.ts.map +1 -0
  194. package/dist/utils/exec.js +103 -0
  195. package/dist/utils/exec.js.map +1 -0
  196. package/dist/utils/fs.d.ts +34 -0
  197. package/dist/utils/fs.d.ts.map +1 -0
  198. package/dist/utils/fs.js +111 -0
  199. package/dist/utils/fs.js.map +1 -0
  200. package/dist/utils/index.d.ts +7 -0
  201. package/dist/utils/index.d.ts.map +1 -0
  202. package/dist/utils/index.js +7 -0
  203. package/dist/utils/index.js.map +1 -0
  204. package/dist/utils/logger.d.ts +14 -0
  205. package/dist/utils/logger.d.ts.map +1 -0
  206. package/dist/utils/logger.js +48 -0
  207. package/dist/utils/logger.js.map +1 -0
  208. package/docs/intune.md +390 -0
  209. package/docs/jamf.md +400 -0
  210. package/docs/jumpcloud.md +510 -0
  211. package/package.json +65 -0
@@ -0,0 +1,474 @@
1
+ /**
2
+ * Shell detection script template for MDM deployment.
3
+ * Targets macOS and Linux systems.
4
+ */
5
+ import { VERSION, COMPANY } from '../../branding.js';
6
+ /**
7
+ * Escape a string for safe use in shell scripts.
8
+ * Escapes characters that could enable shell injection.
9
+ */
10
+ function escapeShellString(str) {
11
+ // Remove null bytes
12
+ let escaped = str.replace(/\0/g, '');
13
+ // Escape backslashes first, then single quotes
14
+ escaped = escaped.replace(/\\/g, '\\\\');
15
+ escaped = escaped.replace(/'/g, "'\\''");
16
+ // Escape special shell characters
17
+ escaped = escaped.replace(/\$/g, '\\$');
18
+ escaped = escaped.replace(/`/g, '\\`');
19
+ escaped = escaped.replace(/"/g, '\\"');
20
+ escaped = escaped.replace(/!/g, '\\!');
21
+ return escaped;
22
+ }
23
+ /**
24
+ * Validate URL format for MDM scripts.
25
+ */
26
+ function validateMdmUrl(url) {
27
+ try {
28
+ const parsed = new URL(url);
29
+ if (!['http:', 'https:'].includes(parsed.protocol)) {
30
+ throw new Error('Invalid protocol');
31
+ }
32
+ return escapeShellString(url);
33
+ }
34
+ catch {
35
+ throw new Error(`Invalid webhook URL: ${url}`);
36
+ }
37
+ }
38
+ /**
39
+ * Generate detection shell script.
40
+ */
41
+ export function generateDetectShellScript(options = {}) {
42
+ const { webhookUrl, webhookToken, gatewayPort = 18789, verbose = false } = options;
43
+ // Validate and sanitize inputs to prevent shell injection
44
+ const safeWebhookUrl = webhookUrl ? validateMdmUrl(webhookUrl) : undefined;
45
+ const safeWebhookToken = webhookToken ? escapeShellString(webhookToken) : undefined;
46
+ // Validate gateway port
47
+ if (gatewayPort < 1 || gatewayPort > 65535 || !Number.isInteger(gatewayPort)) {
48
+ throw new Error(`Invalid gateway port: ${gatewayPort}`);
49
+ }
50
+ const webhookSection = safeWebhookUrl
51
+ ? `
52
+ # Webhook configuration
53
+ WEBHOOK_URL="${safeWebhookUrl}"
54
+ ${safeWebhookToken ? `WEBHOOK_TOKEN="${safeWebhookToken}"` : 'WEBHOOK_TOKEN=""'}
55
+
56
+ send_webhook() {
57
+ local status="$1"
58
+ local severity="$2"
59
+ local details="$3"
60
+
61
+ local payload
62
+ payload=$(cat <<PAYLOAD
63
+ {
64
+ "event": "openclaw.detection",
65
+ "version": "1.0",
66
+ "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
67
+ "status": "$status",
68
+ "severity": "$severity",
69
+ "host": {
70
+ "hostname": "$(hostname)",
71
+ "os": "$(uname -s)",
72
+ "arch": "$(uname -m)",
73
+ "user": "$USER"
74
+ },
75
+ "details": "$details",
76
+ "source": {
77
+ "tool": "nox-openclaw-detector",
78
+ "version": "${VERSION}",
79
+ "vendor": "${COMPANY}"
80
+ }
81
+ }
82
+ PAYLOAD
83
+ )
84
+
85
+ local auth_header=""
86
+ if [[ -n "$WEBHOOK_TOKEN" ]]; then
87
+ auth_header="-H \\"Authorization: Bearer $WEBHOOK_TOKEN\\""
88
+ fi
89
+
90
+ curl -s -X POST "$WEBHOOK_URL" \\
91
+ -H "Content-Type: application/json" \\
92
+ $auth_header \\
93
+ -d "$payload" \\
94
+ --connect-timeout 10 \\
95
+ --max-time 30 > /dev/null 2>&1 || true
96
+ }
97
+ `
98
+ : '';
99
+ const verboseLog = verbose
100
+ ? `
101
+ log_verbose() {
102
+ echo "[DEBUG] $(date '+%Y-%m-%d %H:%M:%S') $1"
103
+ }
104
+ `
105
+ : `
106
+ log_verbose() { :; } # No-op when not verbose
107
+ `;
108
+ return `#!/bin/bash
109
+ # ==============================================================================
110
+ # Nox OpenClaw Detection Script
111
+ # ==============================================================================
112
+ # Generated by ${VERSION}
113
+ # ${COMPANY} - https://nox.security
114
+ #
115
+ # This script detects OpenClaw AI agent installations on macOS and Linux.
116
+ #
117
+ # Exit Codes:
118
+ # 0 - OpenClaw NOT detected (clean)
119
+ # 1 - OpenClaw DETECTED
120
+ # 2 - Script error
121
+ #
122
+ # Usage:
123
+ # ./detect-openclaw.sh
124
+ # ./detect-openclaw.sh --verbose
125
+ # ==============================================================================
126
+
127
+ set -euo pipefail
128
+
129
+ # Configuration
130
+ GATEWAY_PORT=${gatewayPort}
131
+ OPENCLAW_FOUND=0
132
+ DETECTION_DETAILS=()
133
+ ${verboseLog}
134
+ ${webhookSection}
135
+
136
+ # Add detection detail
137
+ add_detail() {
138
+ DETECTION_DETAILS+=("$1")
139
+ log_verbose "Detection: $1"
140
+ }
141
+
142
+ # Check if running as expected user
143
+ check_environment() {
144
+ log_verbose "Running as user: $USER"
145
+ log_verbose "Operating system: $(uname -s) $(uname -r)"
146
+ log_verbose "Architecture: $(uname -m)"
147
+ }
148
+
149
+ # Check if nox CLI is available and use it
150
+ check_nox_cli() {
151
+ if command -v nox &>/dev/null; then
152
+ log_verbose "Nox CLI found, using for detection"
153
+ local result
154
+ if result=$(nox scan --quiet --json 2>/dev/null); then
155
+ local summary
156
+ summary=$(echo "$result" | grep -o '"summary":"[^"]*"' | cut -d'"' -f4 || echo "")
157
+ if [[ "$summary" != "not-installed" && -n "$summary" ]]; then
158
+ OPENCLAW_FOUND=1
159
+ add_detail "Detected via nox CLI: $summary"
160
+ fi
161
+ return 0
162
+ fi
163
+ fi
164
+ return 1
165
+ }
166
+
167
+ # Check for CLI binary in common locations
168
+ check_cli_binary() {
169
+ log_verbose "Checking for CLI binary..."
170
+
171
+ local cli_paths=(
172
+ "/usr/local/bin/openclaw"
173
+ "/opt/homebrew/bin/openclaw"
174
+ "/usr/bin/openclaw"
175
+ "$HOME/.local/bin/openclaw"
176
+ "$HOME/bin/openclaw"
177
+ )
178
+
179
+ for cli_path in "\${cli_paths[@]}"; do
180
+ if [[ -f "$cli_path" ]]; then
181
+ OPENCLAW_FOUND=1
182
+ local version=""
183
+ if version=$("$cli_path" --version 2>/dev/null); then
184
+ add_detail "CLI binary found at $cli_path (version: $version)"
185
+ else
186
+ add_detail "CLI binary found at $cli_path"
187
+ fi
188
+ return
189
+ fi
190
+ done
191
+
192
+ # Check PATH
193
+ if command -v openclaw &>/dev/null; then
194
+ local cli_path
195
+ cli_path=$(command -v openclaw)
196
+ OPENCLAW_FOUND=1
197
+ add_detail "CLI binary found in PATH: $cli_path"
198
+ fi
199
+ }
200
+
201
+ # Check for macOS app bundle
202
+ check_app_bundle() {
203
+ log_verbose "Checking for macOS app bundle..."
204
+
205
+ local app_paths=(
206
+ "/Applications/OpenClaw.app"
207
+ "$HOME/Applications/OpenClaw.app"
208
+ )
209
+
210
+ for app_path in "\${app_paths[@]}"; do
211
+ if [[ -d "$app_path" ]]; then
212
+ OPENCLAW_FOUND=1
213
+ local version=""
214
+ local plist="$app_path/Contents/Info.plist"
215
+ if [[ -f "$plist" ]] && command -v defaults &>/dev/null; then
216
+ version=$(defaults read "$plist" CFBundleShortVersionString 2>/dev/null || echo "")
217
+ fi
218
+ if [[ -n "$version" ]]; then
219
+ add_detail "App bundle found at $app_path (version: $version)"
220
+ else
221
+ add_detail "App bundle found at $app_path"
222
+ fi
223
+ fi
224
+ done
225
+ }
226
+
227
+ # Check for configuration directory
228
+ check_config_directory() {
229
+ log_verbose "Checking for configuration directories..."
230
+
231
+ # Check current user
232
+ if [[ -d "$HOME/.openclaw" ]]; then
233
+ OPENCLAW_FOUND=1
234
+ local config_file="$HOME/.openclaw/openclaw.json"
235
+ if [[ -f "$config_file" ]]; then
236
+ add_detail "Config directory found at $HOME/.openclaw (with config file)"
237
+ else
238
+ add_detail "Config directory found at $HOME/.openclaw"
239
+ fi
240
+ fi
241
+
242
+ # Check other users (requires root)
243
+ if [[ $EUID -eq 0 ]]; then
244
+ for user_home in /Users/* /home/*; do
245
+ if [[ -d "$user_home/.openclaw" && "$user_home" != "$HOME" ]]; then
246
+ OPENCLAW_FOUND=1
247
+ add_detail "Config directory found at $user_home/.openclaw"
248
+ fi
249
+ done
250
+ fi
251
+ }
252
+
253
+ # Check for running processes
254
+ check_processes() {
255
+ log_verbose "Checking for running processes..."
256
+
257
+ local pids
258
+ if pids=$(pgrep -f "openclaw" 2>/dev/null); then
259
+ OPENCLAW_FOUND=1
260
+ local count
261
+ count=$(echo "$pids" | wc -l | tr -d ' ')
262
+ add_detail "OpenClaw processes running (count: $count, PIDs: $(echo $pids | tr '\\n' ' '))"
263
+ fi
264
+ }
265
+
266
+ # Check for gateway port
267
+ check_gateway_port() {
268
+ log_verbose "Checking for gateway port $GATEWAY_PORT..."
269
+
270
+ # Try netcat first
271
+ if command -v nc &>/dev/null; then
272
+ if nc -z localhost "$GATEWAY_PORT" 2>/dev/null; then
273
+ OPENCLAW_FOUND=1
274
+ add_detail "Gateway port $GATEWAY_PORT is listening"
275
+ return
276
+ fi
277
+ fi
278
+
279
+ # Try lsof
280
+ if command -v lsof &>/dev/null; then
281
+ if lsof -i ":$GATEWAY_PORT" -sTCP:LISTEN &>/dev/null; then
282
+ OPENCLAW_FOUND=1
283
+ add_detail "Gateway port $GATEWAY_PORT is listening (via lsof)"
284
+ return
285
+ fi
286
+ fi
287
+
288
+ # Try /dev/tcp (bash built-in)
289
+ if (echo >/dev/tcp/localhost/$GATEWAY_PORT) 2>/dev/null; then
290
+ OPENCLAW_FOUND=1
291
+ add_detail "Gateway port $GATEWAY_PORT is listening"
292
+ fi
293
+ }
294
+
295
+ # Check for launchd service (macOS)
296
+ check_launchd_service() {
297
+ if [[ "$(uname -s)" != "Darwin" ]]; then
298
+ return
299
+ fi
300
+
301
+ log_verbose "Checking for launchd services..."
302
+
303
+ local plist_patterns=(
304
+ "bot.molt"
305
+ "openclaw"
306
+ )
307
+
308
+ local search_dirs=(
309
+ "$HOME/Library/LaunchAgents"
310
+ "/Library/LaunchAgents"
311
+ "/Library/LaunchDaemons"
312
+ )
313
+
314
+ for dir in "\${search_dirs[@]}"; do
315
+ if [[ -d "$dir" ]]; then
316
+ for pattern in "\${plist_patterns[@]}"; do
317
+ for plist in "$dir"/*"$pattern"*.plist; do
318
+ if [[ -f "$plist" ]]; then
319
+ OPENCLAW_FOUND=1
320
+ local loaded=""
321
+ if launchctl list | grep -q "$pattern" 2>/dev/null; then
322
+ loaded=" (loaded)"
323
+ fi
324
+ add_detail "LaunchAgent/Daemon found: $plist$loaded"
325
+ fi
326
+ done
327
+ done
328
+ fi
329
+ done
330
+ }
331
+
332
+ # Check for systemd service (Linux)
333
+ check_systemd_service() {
334
+ if ! command -v systemctl &>/dev/null; then
335
+ return
336
+ fi
337
+
338
+ log_verbose "Checking for systemd services..."
339
+
340
+ local service_names=(
341
+ "openclaw"
342
+ "openclaw.service"
343
+ "bot.molt.gateway"
344
+ )
345
+
346
+ for service in "\${service_names[@]}"; do
347
+ if systemctl list-unit-files "$service" &>/dev/null; then
348
+ local status
349
+ status=$(systemctl is-active "$service" 2>/dev/null || echo "inactive")
350
+ if [[ "$status" != "inactive" ]] || systemctl is-enabled "$service" &>/dev/null; then
351
+ OPENCLAW_FOUND=1
352
+ add_detail "Systemd service found: $service (status: $status)"
353
+ fi
354
+ fi
355
+ done
356
+
357
+ # Check for service files directly
358
+ local service_paths=(
359
+ "/etc/systemd/system/openclaw.service"
360
+ "/usr/lib/systemd/system/openclaw.service"
361
+ "$HOME/.config/systemd/user/openclaw.service"
362
+ )
363
+
364
+ for service_path in "\${service_paths[@]}"; do
365
+ if [[ -f "$service_path" ]]; then
366
+ OPENCLAW_FOUND=1
367
+ add_detail "Systemd service file found: $service_path"
368
+ fi
369
+ done
370
+ }
371
+
372
+ # Check for Docker containers and images
373
+ check_docker() {
374
+ if ! command -v docker &>/dev/null; then
375
+ return
376
+ fi
377
+
378
+ log_verbose "Checking for Docker artifacts..."
379
+
380
+ # Check running containers
381
+ local containers
382
+ if containers=$(docker ps --filter "name=openclaw" --format "{{.Names}}" 2>/dev/null); then
383
+ if [[ -n "$containers" ]]; then
384
+ OPENCLAW_FOUND=1
385
+ add_detail "Docker containers running: $containers"
386
+ fi
387
+ fi
388
+
389
+ # Check stopped containers
390
+ if containers=$(docker ps -a --filter "name=openclaw" --filter "status=exited" --format "{{.Names}}" 2>/dev/null); then
391
+ if [[ -n "$containers" ]]; then
392
+ OPENCLAW_FOUND=1
393
+ add_detail "Docker containers (stopped): $containers"
394
+ fi
395
+ fi
396
+
397
+ # Check images
398
+ local images
399
+ if images=$(docker images --filter "reference=*openclaw*" --format "{{.Repository}}:{{.Tag}}" 2>/dev/null); then
400
+ if [[ -n "$images" ]]; then
401
+ OPENCLAW_FOUND=1
402
+ add_detail "Docker images found: $images"
403
+ fi
404
+ fi
405
+ }
406
+
407
+ # Main detection routine
408
+ main() {
409
+ check_environment
410
+
411
+ # Try nox CLI first (most comprehensive)
412
+ if check_nox_cli; then
413
+ # Nox CLI handled detection
414
+ :
415
+ else
416
+ # Fallback to individual checks
417
+ check_cli_binary
418
+ check_app_bundle
419
+ check_config_directory
420
+ check_processes
421
+ check_gateway_port
422
+ check_launchd_service
423
+ check_systemd_service
424
+ check_docker
425
+ fi
426
+
427
+ # Compile results
428
+ local details_string=""
429
+ if [[ \${#DETECTION_DETAILS[@]} -gt 0 ]]; then
430
+ details_string=$(IFS="; "; echo "\${DETECTION_DETAILS[*]}")
431
+ fi
432
+
433
+ # Send webhook notification
434
+ ${safeWebhookUrl ? `
435
+ if [[ $OPENCLAW_FOUND -eq 1 ]]; then
436
+ send_webhook "detected" "high" "$details_string"
437
+ else
438
+ send_webhook "clean" "info" "No OpenClaw installation detected"
439
+ fi
440
+ ` : ''}
441
+
442
+ # Output results
443
+ if [[ $OPENCLAW_FOUND -eq 1 ]]; then
444
+ echo "OPENCLAW DETECTED"
445
+ echo "Details: $details_string"
446
+ exit 1
447
+ else
448
+ echo "OpenClaw not detected"
449
+ exit 0
450
+ fi
451
+ }
452
+
453
+ # Run main function
454
+ main "$@"
455
+ `;
456
+ }
457
+ /**
458
+ * Get script metadata for documentation.
459
+ */
460
+ export function getDetectShellMetadata() {
461
+ return {
462
+ filename: 'detect-openclaw.sh',
463
+ extension: '.sh',
464
+ platform: 'unix',
465
+ description: 'Shell detection script for macOS and Linux',
466
+ requirements: ['bash 4.0+', 'Standard Unix utilities (grep, pgrep, nc)'],
467
+ exitCodes: {
468
+ 0: 'OpenClaw not detected (clean)',
469
+ 1: 'OpenClaw detected',
470
+ 2: 'Script error',
471
+ },
472
+ };
473
+ }
474
+ //# sourceMappingURL=detect.sh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.sh.js","sourceRoot":"","sources":["../../../src/mdm/templates/detect.sh.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * PowerShell enforcement script template for MDM deployment.
3
+ * Targets Windows systems.
4
+ */
5
+ export interface EnforcePowerShellOptions {
6
+ webhookUrl?: string;
7
+ webhookToken?: string;
8
+ gatewayPort?: number;
9
+ verbose?: boolean;
10
+ dryRun?: boolean;
11
+ quarantine?: boolean;
12
+ }
13
+ /**
14
+ * Generate enforcement PowerShell script.
15
+ */
16
+ export declare function generateEnforcePowerShellScript(options?: EnforcePowerShellOptions): string;
17
+ /**
18
+ * Get script metadata for documentation.
19
+ */
20
+ export declare function getEnforcePowerShellMetadata(): {
21
+ filename: string;
22
+ extension: string;
23
+ platform: string;
24
+ description: string;
25
+ requirements: string[];
26
+ exitCodes: {
27
+ 0: string;
28
+ 1: string;
29
+ 2: string;
30
+ 3: string;
31
+ };
32
+ };
33
+ //# sourceMappingURL=enforce.ps1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforce.ps1.d.ts","sourceRoot":"","sources":["../../../src/mdm/templates/enforce.ps1.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAiCD;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAooB9F;AAED;;GAEG;AACH,wBAAgB,4BAA4B;;;;;;;;;;;;EAc3C"}