clawhatch 0.1.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.
- package/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/checks/cloud-sync.d.ts +10 -0
- package/dist/checks/cloud-sync.d.ts.map +1 -0
- package/dist/checks/cloud-sync.js +62 -0
- package/dist/checks/cloud-sync.js.map +1 -0
- package/dist/checks/data-protection.d.ts +9 -0
- package/dist/checks/data-protection.d.ts.map +1 -0
- package/dist/checks/data-protection.js +197 -0
- package/dist/checks/data-protection.js.map +1 -0
- package/dist/checks/identity.d.ts +14 -0
- package/dist/checks/identity.d.ts.map +1 -0
- package/dist/checks/identity.js +327 -0
- package/dist/checks/identity.js.map +1 -0
- package/dist/checks/model.d.ts +10 -0
- package/dist/checks/model.d.ts.map +1 -0
- package/dist/checks/model.js +337 -0
- package/dist/checks/model.js.map +1 -0
- package/dist/checks/network.d.ts +9 -0
- package/dist/checks/network.d.ts.map +1 -0
- package/dist/checks/network.js +177 -0
- package/dist/checks/network.js.map +1 -0
- package/dist/checks/operational.d.ts +9 -0
- package/dist/checks/operational.d.ts.map +1 -0
- package/dist/checks/operational.js +158 -0
- package/dist/checks/operational.js.map +1 -0
- package/dist/checks/sandbox.d.ts +9 -0
- package/dist/checks/sandbox.d.ts.map +1 -0
- package/dist/checks/sandbox.js +135 -0
- package/dist/checks/sandbox.js.map +1 -0
- package/dist/checks/secrets.d.ts +9 -0
- package/dist/checks/secrets.d.ts.map +1 -0
- package/dist/checks/secrets.js +816 -0
- package/dist/checks/secrets.js.map +1 -0
- package/dist/checks/skills.d.ts +9 -0
- package/dist/checks/skills.d.ts.map +1 -0
- package/dist/checks/skills.js +303 -0
- package/dist/checks/skills.js.map +1 -0
- package/dist/checks/tools.d.ts +9 -0
- package/dist/checks/tools.d.ts.map +1 -0
- package/dist/checks/tools.js +397 -0
- package/dist/checks/tools.js.map +1 -0
- package/dist/discover.d.ts +22 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +281 -0
- package/dist/discover.js.map +1 -0
- package/dist/fixer.d.ts +16 -0
- package/dist/fixer.d.ts.map +1 -0
- package/dist/fixer.js +361 -0
- package/dist/fixer.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +230 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +14 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +108 -0
- package/dist/init.js.map +1 -0
- package/dist/notify.d.ts +28 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +217 -0
- package/dist/notify.js.map +1 -0
- package/dist/parsers/config.d.ts +16 -0
- package/dist/parsers/config.d.ts.map +1 -0
- package/dist/parsers/config.js +54 -0
- package/dist/parsers/config.js.map +1 -0
- package/dist/parsers/env.d.ts +6 -0
- package/dist/parsers/env.d.ts.map +1 -0
- package/dist/parsers/env.js +35 -0
- package/dist/parsers/env.js.map +1 -0
- package/dist/parsers/jsonl.d.ts +12 -0
- package/dist/parsers/jsonl.d.ts.map +1 -0
- package/dist/parsers/jsonl.js +61 -0
- package/dist/parsers/jsonl.js.map +1 -0
- package/dist/parsers/markdown.d.ts +17 -0
- package/dist/parsers/markdown.d.ts.map +1 -0
- package/dist/parsers/markdown.js +57 -0
- package/dist/parsers/markdown.js.map +1 -0
- package/dist/reporter-html.d.ts +9 -0
- package/dist/reporter-html.d.ts.map +1 -0
- package/dist/reporter-html.js +581 -0
- package/dist/reporter-html.js.map +1 -0
- package/dist/reporter.d.ts +10 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +133 -0
- package/dist/reporter.js.map +1 -0
- package/dist/sanitize.d.ts +17 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +83 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/scanner.d.ts +18 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +236 -0
- package/dist/scanner.js.map +1 -0
- package/dist/scoring.d.ts +17 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +47 -0
- package/dist/scoring.js.map +1 -0
- package/dist/telemetry.d.ts +16 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +52 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/threat-feed.d.ts +14 -0
- package/dist/threat-feed.d.ts.map +1 -0
- package/dist/threat-feed.js +133 -0
- package/dist/threat-feed.js.map +1 -0
- package/dist/types.d.ts +221 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +34 -0
- package/dist/utils.js.map +1 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Richard / Clawhatch
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# clawhatch
|
|
2
|
+
|
|
3
|
+
> Security scanner for OpenClaw AI agents — 100-point audit with auto-fix.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/clawhatch)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://nodejs.org/)
|
|
8
|
+
|
|
9
|
+
Clawhatch runs **100 automated security checks** against your [OpenClaw](https://openclaw.com) installation, scores it on a 100-point scale (A+ to F), and can auto-fix safe issues. Think of it as `npm audit` for your AI agent.
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx clawhatch scan
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
No installation required. Clawhatch auto-detects your OpenClaw installation at `~/.openclaw` (or `%APPDATA%\openclaw` on Windows).
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g clawhatch
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Basic scan — auto-detects your OpenClaw config
|
|
29
|
+
clawhatch scan
|
|
30
|
+
|
|
31
|
+
# Scan with workspace files (SOUL.md, skills, markdown)
|
|
32
|
+
clawhatch scan --workspace .
|
|
33
|
+
|
|
34
|
+
# Deep scan — analyze full session logs (slower)
|
|
35
|
+
clawhatch scan --deep
|
|
36
|
+
|
|
37
|
+
# JSON output for scripting and CI
|
|
38
|
+
clawhatch scan --json
|
|
39
|
+
|
|
40
|
+
# HTML report
|
|
41
|
+
clawhatch scan --format html
|
|
42
|
+
|
|
43
|
+
# Auto-fix safe issues (prompts for behavioral changes)
|
|
44
|
+
clawhatch scan --fix
|
|
45
|
+
|
|
46
|
+
# Custom OpenClaw installation path
|
|
47
|
+
clawhatch scan --path /custom/path
|
|
48
|
+
|
|
49
|
+
# Combine flags
|
|
50
|
+
clawhatch scan --workspace . --deep --fix
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Example Output
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Clawhatch Security Scanner v0.1.0
|
|
57
|
+
|
|
58
|
+
Clawhatch Security Scan
|
|
59
|
+
==================================================
|
|
60
|
+
|
|
61
|
+
Security Score: 72/100 (B — Acceptable)
|
|
62
|
+
|
|
63
|
+
Platform: win32
|
|
64
|
+
OpenClaw: 1.2.0
|
|
65
|
+
Checks: 100 run, 94 passed, 6 findings
|
|
66
|
+
Duration: 842ms
|
|
67
|
+
Scanned: 14 files
|
|
68
|
+
|
|
69
|
+
--------------------------------------------------
|
|
70
|
+
|
|
71
|
+
HIGH (2 findings)
|
|
72
|
+
|
|
73
|
+
! Gateway auth token is weak
|
|
74
|
+
Auth token is short or low-entropy (< 32 characters)
|
|
75
|
+
Risk: Weak tokens can be brute-forced
|
|
76
|
+
Fix: Generate a strong token: openssl rand -hex 32
|
|
77
|
+
|
|
78
|
+
! Session logs contain potential secrets
|
|
79
|
+
API keys or tokens detected in session log files
|
|
80
|
+
Risk: Secrets persisted in plaintext logs
|
|
81
|
+
Fix: Enable log sanitization and rotate exposed keys
|
|
82
|
+
|
|
83
|
+
MEDIUM (3 findings)
|
|
84
|
+
|
|
85
|
+
~ DM policy set to "open"
|
|
86
|
+
Channel accepts messages from any sender
|
|
87
|
+
Risk: Unauthorized users can interact with the agent
|
|
88
|
+
Fix: Set dmPolicy to "allowlist" and configure allowFrom
|
|
89
|
+
|
|
90
|
+
~ No tool rate limiting configured
|
|
91
|
+
Tool execution has no throttle (tools.rateLimit missing)
|
|
92
|
+
Risk: Rapid tool invocation can spam external APIs
|
|
93
|
+
Fix: Set tools.rateLimit in openclaw.json (e.g., 60)
|
|
94
|
+
|
|
95
|
+
~ Session log retention not configured
|
|
96
|
+
No sessionLogTTL set — logs kept indefinitely
|
|
97
|
+
Risk: Stale data accumulation and potential compliance issues
|
|
98
|
+
Fix: Set retention.sessionLogTTL (e.g., 30 days)
|
|
99
|
+
|
|
100
|
+
LOW (1 finding)
|
|
101
|
+
|
|
102
|
+
- No health check endpoint configured
|
|
103
|
+
Gateway has no monitoring.enabled setting
|
|
104
|
+
Risk: No automated way to verify agent is running correctly
|
|
105
|
+
Fix: Enable monitoring in openclaw.json
|
|
106
|
+
|
|
107
|
+
==================================================
|
|
108
|
+
|
|
109
|
+
3 issue(s) can be auto-fixed. Run with --fix
|
|
110
|
+
Run with --json for machine-readable output
|
|
111
|
+
Run with --deep for thorough session log scanning
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## What It Checks
|
|
115
|
+
|
|
116
|
+
Clawhatch runs 100 checks across **10 security categories**:
|
|
117
|
+
|
|
118
|
+
| Category | Checks | What It Covers |
|
|
119
|
+
|----------|--------|----------------|
|
|
120
|
+
| **Identity & Access** | 15 | DM policies, allowlists, pairing config, access groups, OAuth, API key rotation |
|
|
121
|
+
| **Network Exposure** | 10 | Gateway binding, auth mode, TLS, trusted proxies, insecure auth flags |
|
|
122
|
+
| **Sandbox Configuration** | 8 | Sandbox mode, workspace access, Docker isolation, browser host control |
|
|
123
|
+
| **Secret Scanning** | 10 | Hardcoded API keys, .env permissions, secrets in markdown, session log leakage |
|
|
124
|
+
| **Model Security** | 7 | Model config, legacy models, injection resistance, SOUL.md analysis, fallback order |
|
|
125
|
+
| **Cloud Sync** | 1 | iCloud, OneDrive, Dropbox, Google Drive detection |
|
|
126
|
+
| **Tool Security** | 20 | Elevated tools, command injection, Docker socket exposure, audit logging |
|
|
127
|
+
| **Skill Security** | 12 | Untrusted sources, dangerous dependencies, native modules, sandboxing |
|
|
128
|
+
| **Data Protection** | 10 | PII in logs, retention policies, encryption at rest, log rotation |
|
|
129
|
+
| **Operational** | 7 | Logging config, monitoring, git secrets, health checks, dependency staleness |
|
|
130
|
+
|
|
131
|
+
## Scoring
|
|
132
|
+
|
|
133
|
+
Clawhatch uses a **100-point scoring system** with severity-based penalties:
|
|
134
|
+
|
|
135
|
+
| Severity | Penalty per finding |
|
|
136
|
+
|----------|---------------------|
|
|
137
|
+
| Critical | −15 points |
|
|
138
|
+
| High | −8 points |
|
|
139
|
+
| Medium | −3 points |
|
|
140
|
+
| Low | −1 point |
|
|
141
|
+
|
|
142
|
+
**Critical cap:** Any critical finding hard-caps the score at **40**, regardless of calculated total. Fix critical issues first.
|
|
143
|
+
|
|
144
|
+
### Grade Scale
|
|
145
|
+
|
|
146
|
+
| Score | Grade | Label |
|
|
147
|
+
|-------|-------|-------|
|
|
148
|
+
| 90–100 | A+ | Excellent |
|
|
149
|
+
| 80–89 | A | Good |
|
|
150
|
+
| 70–79 | B | Acceptable |
|
|
151
|
+
| 50–69 | C | Needs Work |
|
|
152
|
+
| 30–49 | D | Poor |
|
|
153
|
+
| 0–29 | F | Critical |
|
|
154
|
+
|
|
155
|
+
## Auto-Fix (`--fix`)
|
|
156
|
+
|
|
157
|
+
When you run `clawhatch scan --fix`, the scanner applies fixes in two tiers:
|
|
158
|
+
|
|
159
|
+
**Safe fixes** — applied automatically:
|
|
160
|
+
- File permission corrections (e.g., tightening `.env` to 600)
|
|
161
|
+
- Adding secrets to `.gitignore`
|
|
162
|
+
- Generating strong replacement tokens
|
|
163
|
+
|
|
164
|
+
**Behavioral fixes** — prompts for confirmation:
|
|
165
|
+
- Changing DM policies from "open" to "allowlist"
|
|
166
|
+
- Enabling sandbox mode
|
|
167
|
+
- Modifying gateway bind addresses
|
|
168
|
+
|
|
169
|
+
All fixes create timestamped backups (`.bak.<timestamp>`) before modifying any file.
|
|
170
|
+
|
|
171
|
+
## JSON Export (`--json`)
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
clawhatch scan --json > report.json
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Outputs a structured `ScanResult` object:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"timestamp": "2026-02-06T12:00:00.000Z",
|
|
182
|
+
"openclawVersion": "1.2.0",
|
|
183
|
+
"score": 82,
|
|
184
|
+
"findings": [
|
|
185
|
+
{
|
|
186
|
+
"id": "NETWORK-001",
|
|
187
|
+
"severity": "CRITICAL",
|
|
188
|
+
"confidence": "high",
|
|
189
|
+
"category": "Network Exposure",
|
|
190
|
+
"title": "Gateway bound to 0.0.0.0",
|
|
191
|
+
"description": "...",
|
|
192
|
+
"risk": "...",
|
|
193
|
+
"remediation": "...",
|
|
194
|
+
"autoFixable": true,
|
|
195
|
+
"fixType": "behavioral"
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
"suggestions": [],
|
|
199
|
+
"summary": {
|
|
200
|
+
"score": 82,
|
|
201
|
+
"grade": "A",
|
|
202
|
+
"label": "Good",
|
|
203
|
+
"critical": 0,
|
|
204
|
+
"high": 1,
|
|
205
|
+
"medium": 2,
|
|
206
|
+
"low": 0,
|
|
207
|
+
"suggestions": 3,
|
|
208
|
+
"autoFixable": 1
|
|
209
|
+
},
|
|
210
|
+
"filesScanned": 14,
|
|
211
|
+
"checksRun": 100,
|
|
212
|
+
"checksPassed": 97,
|
|
213
|
+
"duration": 1234,
|
|
214
|
+
"platform": "win32"
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Exit Codes
|
|
219
|
+
|
|
220
|
+
| Code | Meaning |
|
|
221
|
+
|------|---------|
|
|
222
|
+
| `0` | Scan passed (no critical findings) |
|
|
223
|
+
| `1` | Critical findings detected |
|
|
224
|
+
|
|
225
|
+
## Findings vs. Suggestions
|
|
226
|
+
|
|
227
|
+
Clawhatch separates output into two groups:
|
|
228
|
+
|
|
229
|
+
- **Findings** (high/medium confidence) — count toward your score and represent actionable security issues.
|
|
230
|
+
- **Suggestions** (low confidence) — informational recommendations that do not affect your score.
|
|
231
|
+
|
|
232
|
+
## CI/CD Integration
|
|
233
|
+
|
|
234
|
+
### GitHub Actions
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
name: Security Audit
|
|
238
|
+
on: [push, pull_request]
|
|
239
|
+
|
|
240
|
+
jobs:
|
|
241
|
+
clawhatch:
|
|
242
|
+
runs-on: ubuntu-latest
|
|
243
|
+
steps:
|
|
244
|
+
- uses: actions/checkout@v4
|
|
245
|
+
- uses: actions/setup-node@v4
|
|
246
|
+
with:
|
|
247
|
+
node-version: '18'
|
|
248
|
+
|
|
249
|
+
- name: Run Clawhatch scan
|
|
250
|
+
run: npx clawhatch scan --workspace . --json > clawhatch-report.json
|
|
251
|
+
|
|
252
|
+
- name: Check score
|
|
253
|
+
run: |
|
|
254
|
+
score=$(jq '.score' clawhatch-report.json)
|
|
255
|
+
echo "Security score: $score"
|
|
256
|
+
[ "$score" -ge 50 ] || exit 1
|
|
257
|
+
|
|
258
|
+
- uses: actions/upload-artifact@v4
|
|
259
|
+
if: always()
|
|
260
|
+
with:
|
|
261
|
+
name: clawhatch-report
|
|
262
|
+
path: clawhatch-report.json
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Platform Support
|
|
266
|
+
|
|
267
|
+
| Platform | Status | Notes |
|
|
268
|
+
|----------|--------|-------|
|
|
269
|
+
| **Windows** | ✅ Supported | Full support including `%APPDATA%\openclaw` detection |
|
|
270
|
+
| **Linux** | 🔄 Coming soon | Core checks work, platform-specific checks in progress |
|
|
271
|
+
| **macOS** | 🔄 Coming soon | Core checks work, platform-specific checks in progress |
|
|
272
|
+
|
|
273
|
+
## Other Commands
|
|
274
|
+
|
|
275
|
+
### `clawhatch init`
|
|
276
|
+
|
|
277
|
+
Generate a secure baseline OpenClaw configuration:
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
clawhatch init
|
|
281
|
+
clawhatch init --path /custom/path
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Creates a hardened `openclaw.json` and `.env` template with secure defaults.
|
|
285
|
+
|
|
286
|
+
## Community Threat Intelligence
|
|
287
|
+
|
|
288
|
+
Clawhatch includes a community threat intelligence network. When you share your scan results, they're anonymized and aggregated to protect everyone:
|
|
289
|
+
|
|
290
|
+
### Share your results
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
clawhatch scan --share # Anonymize and share with community
|
|
294
|
+
clawhatch scan --upload # Same as --share
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Only check IDs, severity levels, and categories are shared. **No file paths, secrets, or descriptions ever leave your machine.**
|
|
298
|
+
|
|
299
|
+
### View community threats
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
clawhatch threats # View the community threat feed
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Shows the top threats across all users, trending attacks, new advisories, and the community average score.
|
|
306
|
+
|
|
307
|
+
### Subscribe to alerts
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
clawhatch subscribe --webhook https://discord.com/api/webhooks/... # Discord
|
|
311
|
+
clawhatch subscribe --webhook https://hooks.slack.com/services/... # Slack
|
|
312
|
+
clawhatch subscribe --threshold CRITICAL # Only critical alerts
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
When a new threat is detected across the community, subscribers are notified instantly via their configured webhook.
|
|
316
|
+
|
|
317
|
+
### How it works
|
|
318
|
+
|
|
319
|
+
1. You run `clawhatch scan --share`
|
|
320
|
+
2. Findings are stripped to just check IDs + severity (no file paths, no secrets)
|
|
321
|
+
3. Anonymized report is uploaded to the community feed
|
|
322
|
+
4. If 45% of users suddenly have NETWORK-001, that's flagged as trending
|
|
323
|
+
5. Subscribers with that vulnerability get an instant webhook alert
|
|
324
|
+
|
|
325
|
+
### Privacy
|
|
326
|
+
|
|
327
|
+
- Instance ID is a SHA-256 hash of your hostname -- we never see your actual machine name
|
|
328
|
+
- No file paths, descriptions, or secret values are ever transmitted
|
|
329
|
+
- You can inspect exactly what's sent with `clawhatch scan --json --share`
|
|
330
|
+
|
|
331
|
+
## Requirements
|
|
332
|
+
|
|
333
|
+
- **Node.js** >= 18.0.0
|
|
334
|
+
- **OpenClaw** installed (auto-detected or specify with `--path`)
|
|
335
|
+
|
|
336
|
+
## Contributing
|
|
337
|
+
|
|
338
|
+
Contributions welcome! Please see the [GitHub repository](https://github.com/wlshlad85/clawhatch) for details.
|
|
339
|
+
|
|
340
|
+
1. Fork the repo
|
|
341
|
+
2. Create a feature branch (`git checkout -b feat/my-check`)
|
|
342
|
+
3. Add your checks following the existing pattern in `src/checks/`
|
|
343
|
+
4. Run tests: `npm test`
|
|
344
|
+
5. Submit a PR
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
[MIT](LICENSE) © Clawhatch
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Sync Detection check (51).
|
|
3
|
+
*
|
|
4
|
+
* Detects if ~/.openclaw/ is inside a known cloud sync directory
|
|
5
|
+
* (iCloud, OneDrive, Dropbox, Google Drive). If so, credentials
|
|
6
|
+
* are being uploaded to the cloud in plaintext.
|
|
7
|
+
*/
|
|
8
|
+
import { type Finding } from "../types.js";
|
|
9
|
+
export declare function runCloudSyncCheck(openclawDir: string): Promise<Finding[]>;
|
|
10
|
+
//# sourceMappingURL=cloud-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-sync.d.ts","sourceRoot":"","sources":["../../src/checks/cloud-sync.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAY,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AA4CrD,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,EAAE,CAAC,CAgCpB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Sync Detection check (51).
|
|
3
|
+
*
|
|
4
|
+
* Detects if ~/.openclaw/ is inside a known cloud sync directory
|
|
5
|
+
* (iCloud, OneDrive, Dropbox, Google Drive). If so, credentials
|
|
6
|
+
* are being uploaded to the cloud in plaintext.
|
|
7
|
+
*/
|
|
8
|
+
import { Severity } from "../types.js";
|
|
9
|
+
import { platform, homedir } from "node:os";
|
|
10
|
+
import { resolve } from "node:path";
|
|
11
|
+
import { stat } from "node:fs/promises";
|
|
12
|
+
function getCloudServices() {
|
|
13
|
+
const home = homedir();
|
|
14
|
+
const os = platform();
|
|
15
|
+
const services = [];
|
|
16
|
+
if (os === "darwin") {
|
|
17
|
+
services.push({ name: "iCloud Drive", paths: [`${home}/Library/Mobile Documents`] }, { name: "Dropbox", paths: [`${home}/Dropbox`, `${home}/Library/CloudStorage/Dropbox`] }, { name: "OneDrive", paths: [`${home}/OneDrive`, `${home}/Library/CloudStorage/OneDrive-Personal`] }, { name: "Google Drive", paths: [`${home}/Google Drive`, `${home}/Library/CloudStorage/GoogleDrive`] });
|
|
18
|
+
}
|
|
19
|
+
else if (os === "win32") {
|
|
20
|
+
// FIX: Removed duplicate path — `home` already contains the full path like C:\Users\RICHARD
|
|
21
|
+
// so we don't need to construct C:\Users\<username> separately
|
|
22
|
+
services.push({ name: "OneDrive", paths: [`${home}\\OneDrive`] }, { name: "Dropbox", paths: [`${home}\\Dropbox`] }, { name: "Google Drive", paths: [`${home}\\Google Drive`] }, { name: "iCloud Drive", paths: [`${home}\\iCloudDrive`] });
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Linux
|
|
26
|
+
services.push({ name: "Dropbox", paths: [`${home}/Dropbox`] }, { name: "Google Drive", paths: [`${home}/Google Drive`] }, { name: "OneDrive", paths: [`${home}/OneDrive`] });
|
|
27
|
+
}
|
|
28
|
+
return services;
|
|
29
|
+
}
|
|
30
|
+
export async function runCloudSyncCheck(openclawDir) {
|
|
31
|
+
const findings = [];
|
|
32
|
+
const resolvedOcDir = resolve(openclawDir).toLowerCase();
|
|
33
|
+
const services = getCloudServices();
|
|
34
|
+
for (const service of services) {
|
|
35
|
+
for (const syncPath of service.paths) {
|
|
36
|
+
try {
|
|
37
|
+
await stat(syncPath);
|
|
38
|
+
// Sync directory exists — check if openclaw dir is inside it
|
|
39
|
+
const resolvedSync = resolve(syncPath).toLowerCase();
|
|
40
|
+
if (resolvedOcDir.startsWith(resolvedSync)) {
|
|
41
|
+
findings.push({
|
|
42
|
+
id: "CLOUD-001",
|
|
43
|
+
severity: Severity.High,
|
|
44
|
+
confidence: "high",
|
|
45
|
+
category: "Cloud Sync",
|
|
46
|
+
title: `OpenClaw directory is inside ${service.name}`,
|
|
47
|
+
description: `${openclawDir} is inside ${syncPath} — credentials are being synced to the cloud`,
|
|
48
|
+
risk: "API keys, OAuth tokens, and session logs are uploaded to cloud storage in plaintext",
|
|
49
|
+
remediation: `Move ~/.openclaw/ outside of ${service.name} or exclude it from sync`,
|
|
50
|
+
autoFixable: false,
|
|
51
|
+
});
|
|
52
|
+
break; // One finding per service
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Sync dir doesn't exist — skip
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return findings;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=cloud-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-sync.js","sourceRoot":"","sources":["../../src/checks/cloud-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Protection checks (DATA-001 to DATA-010).
|
|
3
|
+
*
|
|
4
|
+
* Checks for PII in logs, data retention policies, encryption,
|
|
5
|
+
* log rotation, and data access audit trails.
|
|
6
|
+
*/
|
|
7
|
+
import { type Finding, type OpenClawConfig, type DiscoveredFiles } from "../types.js";
|
|
8
|
+
export declare function runDataProtectionChecks(config: OpenClawConfig, files: DiscoveredFiles): Promise<Finding[]>;
|
|
9
|
+
//# sourceMappingURL=data-protection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-protection.d.ts","sourceRoot":"","sources":["../../src/checks/data-protection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAY,KAAK,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAahG,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,OAAO,EAAE,CAAC,CA8LpB"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Protection checks (DATA-001 to DATA-010).
|
|
3
|
+
*
|
|
4
|
+
* Checks for PII in logs, data retention policies, encryption,
|
|
5
|
+
* log rotation, and data access audit trails.
|
|
6
|
+
*/
|
|
7
|
+
import { Severity } from "../types.js";
|
|
8
|
+
import { readFile, stat } from "node:fs/promises";
|
|
9
|
+
import { basename } from "node:path";
|
|
10
|
+
// FIX: Tightened PII patterns to reduce false positives.
|
|
11
|
+
// Phone/SSN patterns removed — they match timestamps, version numbers, ports, etc.
|
|
12
|
+
// with extremely high false-positive rates. Kept email and credit-card (Luhn check
|
|
13
|
+
// would be ideal but is out of scope; the 4-group pattern is reasonably specific).
|
|
14
|
+
const PII_PATTERNS = [
|
|
15
|
+
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/, // email (FIX: [A-Za-z] not [A-Z|a-z])
|
|
16
|
+
/\b\d{4}[\s-]\d{4}[\s-]\d{4}[\s-]\d{4}\b/, // credit card-like (require separators to avoid matching hex/ids)
|
|
17
|
+
];
|
|
18
|
+
export async function runDataProtectionChecks(config, files) {
|
|
19
|
+
const findings = [];
|
|
20
|
+
// DATA-001: Session logs contain PII
|
|
21
|
+
for (const logFile of files.sessionLogFiles.slice(0, 5)) {
|
|
22
|
+
try {
|
|
23
|
+
const content = await readFile(logFile, "utf-8").then((c) => c.slice(0, 512 * 1024));
|
|
24
|
+
const hasPII = PII_PATTERNS.some((p) => p.test(content));
|
|
25
|
+
if (hasPII) {
|
|
26
|
+
findings.push({
|
|
27
|
+
id: "DATA-001",
|
|
28
|
+
severity: Severity.High,
|
|
29
|
+
confidence: "medium",
|
|
30
|
+
category: "Data Protection",
|
|
31
|
+
title: "Session log may contain PII",
|
|
32
|
+
description: `${basename(logFile)} contains patterns resembling personal data (email, phone, etc.)`,
|
|
33
|
+
risk: "PII in logs may violate privacy regulations (GDPR, CCPA) and expose user data",
|
|
34
|
+
remediation: "Enable PII scrubbing in session logs or reduce log verbosity",
|
|
35
|
+
autoFixable: false,
|
|
36
|
+
file: logFile,
|
|
37
|
+
});
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Can't read
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// DATA-002: No data retention policy
|
|
46
|
+
if (!config.retention?.sessionLogTTL) {
|
|
47
|
+
findings.push({
|
|
48
|
+
id: "DATA-002",
|
|
49
|
+
severity: Severity.Medium,
|
|
50
|
+
confidence: "medium",
|
|
51
|
+
category: "Data Protection",
|
|
52
|
+
title: "No data retention policy",
|
|
53
|
+
description: "No session log TTL configured — logs accumulate indefinitely",
|
|
54
|
+
risk: "Unbounded log retention increases data breach exposure window",
|
|
55
|
+
remediation: "Set retention.sessionLogTTL to a reasonable period (e.g., 30 days)",
|
|
56
|
+
autoFixable: false,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// DATA-003: Logs not encrypted at rest
|
|
60
|
+
if (!config.retention?.encryptAtRest) {
|
|
61
|
+
findings.push({
|
|
62
|
+
id: "DATA-003",
|
|
63
|
+
severity: Severity.Low,
|
|
64
|
+
confidence: "low",
|
|
65
|
+
category: "Data Protection",
|
|
66
|
+
title: "Session logs not encrypted at rest",
|
|
67
|
+
description: "retention.encryptAtRest is not enabled for session logs",
|
|
68
|
+
risk: "Logs stored in plaintext can be read if the disk is accessed by unauthorized parties",
|
|
69
|
+
remediation: "Set retention.encryptAtRest: true or use full-disk encryption",
|
|
70
|
+
autoFixable: false,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// DATA-004: No log rotation
|
|
74
|
+
if (!config.retention?.logRotation) {
|
|
75
|
+
// Also flag if session logs are large
|
|
76
|
+
let hasLargeLog = false;
|
|
77
|
+
for (const logFile of files.sessionLogFiles.slice(0, 5)) {
|
|
78
|
+
try {
|
|
79
|
+
const s = await stat(logFile);
|
|
80
|
+
if (s.size > 50 * 1024 * 1024) {
|
|
81
|
+
hasLargeLog = true;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Can't stat
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
findings.push({
|
|
90
|
+
id: "DATA-004",
|
|
91
|
+
severity: hasLargeLog ? Severity.Medium : Severity.Low,
|
|
92
|
+
confidence: hasLargeLog ? "high" : "medium",
|
|
93
|
+
category: "Data Protection",
|
|
94
|
+
title: "No log rotation configured",
|
|
95
|
+
description: hasLargeLog
|
|
96
|
+
? "Log rotation disabled and session logs exceed 50MB"
|
|
97
|
+
: "retention.logRotation is not enabled",
|
|
98
|
+
risk: "Unrotated logs consume disk space and increase exposure in case of breach",
|
|
99
|
+
remediation: "Set retention.logRotation: true to enable automatic log rotation",
|
|
100
|
+
autoFixable: false,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// DATA-005: Backups not encrypted
|
|
104
|
+
if (config.retention && !config.retention.encryptAtRest) {
|
|
105
|
+
findings.push({
|
|
106
|
+
id: "DATA-005",
|
|
107
|
+
severity: Severity.Low,
|
|
108
|
+
confidence: "low",
|
|
109
|
+
category: "Data Protection",
|
|
110
|
+
title: "Backups not encrypted",
|
|
111
|
+
description: "Data retention is configured but encryption at rest is not enabled",
|
|
112
|
+
risk: "Backup files containing session data are stored in plaintext",
|
|
113
|
+
remediation: "Enable retention.encryptAtRest: true to encrypt stored data",
|
|
114
|
+
autoFixable: false,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// DATA-006: No data anonymization
|
|
118
|
+
if (files.sessionLogFiles.length > 0 && !config.retention?.sessionLogTTL) {
|
|
119
|
+
findings.push({
|
|
120
|
+
id: "DATA-006",
|
|
121
|
+
severity: Severity.Low,
|
|
122
|
+
confidence: "low",
|
|
123
|
+
category: "Data Protection",
|
|
124
|
+
title: "No data anonymization",
|
|
125
|
+
description: "Session logs exist with no retention policy or anonymization configured",
|
|
126
|
+
risk: "Historical logs contain identifiable conversation data",
|
|
127
|
+
remediation: "Configure data anonymization or set a retention TTL to limit data lifespan",
|
|
128
|
+
autoFixable: false,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// DATA-007: Third-party data sharing
|
|
132
|
+
if (config.monitoring?.enabled && config.monitoring?.provider) {
|
|
133
|
+
findings.push({
|
|
134
|
+
id: "DATA-007",
|
|
135
|
+
severity: Severity.Medium,
|
|
136
|
+
confidence: "medium",
|
|
137
|
+
category: "Data Protection",
|
|
138
|
+
title: "Third-party monitoring enabled",
|
|
139
|
+
description: `Monitoring data is sent to third-party provider: ${config.monitoring.provider}`,
|
|
140
|
+
risk: "Session data, tool invocations, or PII may be shared with external services",
|
|
141
|
+
remediation: "Review monitoring configuration to ensure only necessary data is shared",
|
|
142
|
+
autoFixable: false,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
// DATA-008: No right-to-deletion
|
|
146
|
+
if (files.sessionLogFiles.length > 0 && !config.retention?.sessionLogTTL) {
|
|
147
|
+
findings.push({
|
|
148
|
+
id: "DATA-008",
|
|
149
|
+
severity: Severity.Low,
|
|
150
|
+
confidence: "low",
|
|
151
|
+
category: "Data Protection",
|
|
152
|
+
title: "No data deletion mechanism",
|
|
153
|
+
description: "No retention TTL or deletion mechanism for user session data",
|
|
154
|
+
risk: "Cannot fulfil data deletion requests (GDPR Article 17) without manual cleanup",
|
|
155
|
+
remediation: "Configure retention.sessionLogTTL or provide a data deletion workflow",
|
|
156
|
+
autoFixable: false,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// DATA-009: Logs in public directory
|
|
160
|
+
if (files.workspaceDir) {
|
|
161
|
+
const publicDirs = ["public", "static", "dist", "build", "www"];
|
|
162
|
+
for (const logFile of files.sessionLogFiles) {
|
|
163
|
+
const inPublic = publicDirs.some((d) => logFile.toLowerCase().includes(`${d}/`) || logFile.toLowerCase().includes(`${d}\\`));
|
|
164
|
+
if (inPublic) {
|
|
165
|
+
findings.push({
|
|
166
|
+
id: "DATA-009",
|
|
167
|
+
severity: Severity.High,
|
|
168
|
+
confidence: "high",
|
|
169
|
+
category: "Data Protection",
|
|
170
|
+
title: "Session logs in public directory",
|
|
171
|
+
description: `${basename(logFile)} is inside a public/static directory`,
|
|
172
|
+
risk: "Logs in public directories may be served by web servers and accessible via URL",
|
|
173
|
+
remediation: "Move session logs out of public-facing directories",
|
|
174
|
+
autoFixable: false,
|
|
175
|
+
file: logFile,
|
|
176
|
+
});
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// DATA-010: No audit trail for data access
|
|
182
|
+
if (!config.tools?.auditLog && files.sessionLogFiles.length > 0) {
|
|
183
|
+
findings.push({
|
|
184
|
+
id: "DATA-010",
|
|
185
|
+
severity: Severity.Low,
|
|
186
|
+
confidence: "low",
|
|
187
|
+
category: "Data Protection",
|
|
188
|
+
title: "No audit trail for data access",
|
|
189
|
+
description: "No audit logging configured to track who accesses session data",
|
|
190
|
+
risk: "Cannot determine who accessed, modified, or exported conversation data",
|
|
191
|
+
remediation: "Enable tools.auditLog: true to track data access operations",
|
|
192
|
+
autoFixable: false,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
return findings;
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=data-protection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-protection.js","sourceRoot":"","sources":["../../src/checks/data-protection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAA2D,MAAM,aAAa,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAQ,MAAM,WAAW,CAAC;AAE3C,yDAAyD;AACzD,mFAAmF;AACnF,mFAAmF;AACnF,mFAAmF;AACnF,MAAM,YAAY,GAAG;IACnB,oDAAoD,EAAI,sCAAsC;IAC9F,yCAAyC,EAAgB,kEAAkE;CAC5H,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAsB,EACtB,KAAsB;IAEtB,MAAM,QAAQ,GAAc,EAAE,CAAC;IAE/B,qCAAqC;IACrC,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;YACrF,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YACzD,IAAI,MAAM,EAAE,CAAC;gBACX,QAAQ,CAAC,IAAI,CAAC;oBACZ,EAAE,EAAE,UAAU;oBACd,QAAQ,EAAE,QAAQ,CAAC,IAAI;oBACvB,UAAU,EAAE,QAAQ;oBACpB,QAAQ,EAAE,iBAAiB;oBAC3B,KAAK,EAAE,6BAA6B;oBACpC,WAAW,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,kEAAkE;oBACnG,IAAI,EAAE,+EAA+E;oBACrF,WAAW,EAAE,8DAA8D;oBAC3E,WAAW,EAAE,KAAK;oBAClB,IAAI,EAAE,OAAO;iBACd,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,aAAa;QACf,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,MAAM;YACzB,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,0BAA0B;YACjC,WAAW,EAAE,8DAA8D;YAC3E,IAAI,EAAE,+DAA+D;YACrE,WAAW,EAAE,oEAAoE;YACjF,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,oCAAoC;YAC3C,WAAW,EAAE,yDAAyD;YACtE,IAAI,EAAE,sFAAsF;YAC5F,WAAW,EAAE,+DAA+D;YAC5E,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC;QACnC,sCAAsC;QACtC,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC;gBACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC9B,IAAI,CAAC,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;oBAC9B,WAAW,GAAG,IAAI,CAAC;oBACnB,MAAM;gBACR,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,aAAa;YACf,CAAC;QACH,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG;YACtD,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;YAC3C,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,4BAA4B;YACnC,WAAW,EAAE,WAAW;gBACtB,CAAC,CAAC,oDAAoD;gBACtD,CAAC,CAAC,sCAAsC;YAC1C,IAAI,EAAE,2EAA2E;YACjF,WAAW,EAAE,kEAAkE;YAC/E,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,kCAAkC;IAClC,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC;QACxD,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,uBAAuB;YAC9B,WAAW,EAAE,oEAAoE;YACjF,IAAI,EAAE,8DAA8D;YACpE,WAAW,EAAE,6DAA6D;YAC1E,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,kCAAkC;IAClC,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;QACzE,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,uBAAuB;YAC9B,WAAW,EAAE,yEAAyE;YACtF,IAAI,EAAE,wDAAwD;YAC9D,WAAW,EAAE,4EAA4E;YACzF,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,qCAAqC;IACrC,IAAI,MAAM,CAAC,UAAU,EAAE,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;QAC9D,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,MAAM;YACzB,UAAU,EAAE,QAAQ;YACpB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,gCAAgC;YACvC,WAAW,EAAE,oDAAoD,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE;YAC7F,IAAI,EAAE,6EAA6E;YACnF,WAAW,EAAE,yEAAyE;YACtF,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,iCAAiC;IACjC,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;QACzE,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,4BAA4B;YACnC,WAAW,EAAE,8DAA8D;YAC3E,IAAI,EAAE,+EAA+E;YACrF,WAAW,EAAE,uEAAuE;YACpF,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,qCAAqC;IACrC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAChE,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CACrC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CACpF,CAAC;YACF,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,IAAI,CAAC;oBACZ,EAAE,EAAE,UAAU;oBACd,QAAQ,EAAE,QAAQ,CAAC,IAAI;oBACvB,UAAU,EAAE,MAAM;oBAClB,QAAQ,EAAE,iBAAiB;oBAC3B,KAAK,EAAE,kCAAkC;oBACzC,WAAW,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,sCAAsC;oBACvE,IAAI,EAAE,gFAAgF;oBACtF,WAAW,EAAE,oDAAoD;oBACjE,WAAW,EAAE,KAAK;oBAClB,IAAI,EAAE,OAAO;iBACd,CAAC,CAAC;gBACH,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChE,QAAQ,CAAC,IAAI,CAAC;YACZ,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,iBAAiB;YAC3B,KAAK,EAAE,gCAAgC;YACvC,WAAW,EAAE,gEAAgE;YAC7E,IAAI,EAAE,wEAAwE;YAC9E,WAAW,EAAE,6DAA6D;YAC1E,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|