@kenhkl/agent-moss 0.3.2 → 0.4.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/README.md +4 -2
- package/dist/cli.js +51 -35
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,13 +66,15 @@ const result = await resp.json();
|
|
|
66
66
|
|
|
67
67
|
层1: 启发式静态检测 (<1ms)
|
|
68
68
|
├── 危险命令正则: 30 个模式(rm 分级检测: 5 条严格→宽松规则)
|
|
69
|
+
├── → high/critical → 直接 Deny
|
|
70
|
+
├── → 内联脚本 file_access 转层3(避免 'python -c "cat /etc/shadow"' 假阳性)
|
|
69
71
|
├── 注入关键词: 56 个中英双语关键词(9 类: 指令覆盖/角色劫持/命令注入/...)
|
|
70
72
|
└── 自定义规则: AGENT_MOSS_CUSTOM_RULES 环境变量注入
|
|
71
73
|
|
|
72
74
|
层2: 逻辑规则检测 (<1ms)
|
|
73
75
|
├── Rule 1: read-before-write(有历史但无读取 → flag)
|
|
74
76
|
├── Rule 2: 意图偏离(读取意图 vs 删除动作)
|
|
75
|
-
├── Rule 3: 敏感路径访问(20
|
|
77
|
+
├── Rule 3: 敏感路径访问(20 条路径 + 5 条凭据文件, \b边界匹配, 读写均拦截)
|
|
76
78
|
├── Rule 4: 危险操作(通配符删除 + 重定向覆盖 /etc/ /boot/ /proc/)
|
|
77
79
|
├── Rule 5: 提权检测(sudo/su/chmod u+s/setuid)
|
|
78
80
|
└── Rule 6: 横向移动(ssh/scp/rsync,排除 localhost)
|
|
@@ -143,7 +145,7 @@ ts/src/
|
|
|
143
145
|
└── engine/
|
|
144
146
|
├── types.ts # 核心类型 (SecurityJudgment, LLMConfig, ...)
|
|
145
147
|
├── coordinator.ts # 三层协调器 + 两级快速放行白名单
|
|
146
|
-
├── heuristic.ts # 层1: 30 危险模式 + 56 注入关键词
|
|
148
|
+
├── heuristic.ts # 层1: 30 危险模式 + 56 注入关键词 + isInlineScriptCommand
|
|
147
149
|
├── logic-rules.ts # 层2: 6 条规则 + 20 敏感路径
|
|
148
150
|
├── llm-analyzer.ts # 层3: LLM 分析 (缓存 + 重试 + fail-closed)
|
|
149
151
|
├── script-analyzer.ts # 脚本内容预扫描 (18 个可疑模式)
|
package/dist/cli.js
CHANGED
|
@@ -111,6 +111,7 @@ function runHeuristicCheck(input) {
|
|
|
111
111
|
const command = `${input.aNext.actionType}: ${input.aNext.actionDetail}`;
|
|
112
112
|
const matched = [];
|
|
113
113
|
let highestSeverity = "low";
|
|
114
|
+
let highestRiskType = "";
|
|
114
115
|
const userRules = getCustomRules();
|
|
115
116
|
for (const rule of userRules) {
|
|
116
117
|
try {
|
|
@@ -120,20 +121,24 @@ function runHeuristicCheck(input) {
|
|
|
120
121
|
matched.push(`\u81EA\u5B9A\u4E49\u89C4\u5219: ${rule.pattern}`);
|
|
121
122
|
if (severityRank(rule.severity) > severityRank(highestSeverity)) {
|
|
122
123
|
highestSeverity = rule.severity;
|
|
124
|
+
highestRiskType = "custom_rule";
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
}
|
|
126
128
|
} catch {
|
|
127
129
|
}
|
|
128
130
|
}
|
|
131
|
+
let topRiskType = "";
|
|
129
132
|
for (const rule of DANGEROUS_PATTERNS) {
|
|
130
133
|
if (rule.pattern.test(command)) {
|
|
131
134
|
matched.push(rule.description);
|
|
132
135
|
if (severityRank(rule.severity) > severityRank(highestSeverity)) {
|
|
133
136
|
highestSeverity = rule.severity;
|
|
137
|
+
topRiskType = rule.riskType;
|
|
134
138
|
}
|
|
135
139
|
}
|
|
136
140
|
}
|
|
141
|
+
highestRiskType = topRiskType || highestRiskType;
|
|
137
142
|
const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ""} ${input.promptSession || ""}`.toLowerCase();
|
|
138
143
|
const injectionHits = checkInjectionKeywords(injectionText);
|
|
139
144
|
if (injectionHits.length > 0) {
|
|
@@ -141,15 +146,15 @@ function runHeuristicCheck(input) {
|
|
|
141
146
|
matched.push(...injectionHits.map((h) => `\u6CE8\u5165\u5173\u952E\u8BCD [${h.lang}]: ${h.keyword}`));
|
|
142
147
|
if (severityRank(topHit.riskLevel) > severityRank(highestSeverity)) {
|
|
143
148
|
highestSeverity = topHit.riskLevel;
|
|
149
|
+
highestRiskType = "prompt_injection";
|
|
144
150
|
}
|
|
145
151
|
}
|
|
146
152
|
if (matched.length > 0) {
|
|
147
|
-
const riskType = injectionHits.length > 0 ? "prompt_injection" : "dangerous_command";
|
|
148
153
|
return {
|
|
149
154
|
allowed: false,
|
|
150
155
|
reason: `\u68C0\u6D4B\u5230\u9AD8\u5371\u64CD\u4F5C: ${matched.join(", ")}`,
|
|
151
156
|
riskLevel: highestSeverity,
|
|
152
|
-
riskType,
|
|
157
|
+
riskType: highestRiskType,
|
|
153
158
|
confidence: 95,
|
|
154
159
|
source: "heuristic",
|
|
155
160
|
violatedLayers: ["1"]
|
|
@@ -166,6 +171,10 @@ function checkInjectionKeywords(text) {
|
|
|
166
171
|
}
|
|
167
172
|
return hits;
|
|
168
173
|
}
|
|
174
|
+
function isInlineScriptCommand(actionDetail) {
|
|
175
|
+
const re = /(?:^|\s)(?:python|python3|python3\.\d+|perl|perl5|ruby|jruby|mruby|node|php|lua)\s+(?:-[a-zA-Z]*[cer][a-zA-Z]*\s+)/i;
|
|
176
|
+
return re.test(actionDetail);
|
|
177
|
+
}
|
|
169
178
|
function severityRank(s) {
|
|
170
179
|
const ranks = { low: 1, medium: 2, high: 3, critical: 4 };
|
|
171
180
|
return ranks[s] || 0;
|
|
@@ -241,53 +250,53 @@ var init_heuristic = __esm({
|
|
|
241
250
|
DANGEROUS_PATTERNS = [
|
|
242
251
|
// --- Critical: rm command graded detection (strict to loose, first match wins) ---
|
|
243
252
|
// 1. rm -rf root dir
|
|
244
|
-
{ pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+\/\s/i, severity: "critical", description: "\u9012\u5F52\u5F3A\u5236\u5220\u9664\u6839\u76EE\u5F55 (rm -rf /)" },
|
|
253
|
+
{ pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+\/\s/i, severity: "critical", description: "\u9012\u5F52\u5F3A\u5236\u5220\u9664\u6839\u76EE\u5F55 (rm -rf /)", riskType: "script_execution" },
|
|
245
254
|
// 2. rm -rf absolute path (both -r and -f)
|
|
246
|
-
{ pattern: /\brm\s+-(?=[^\s]*r)(?=[^\s]*f)[a-zA-Z]*\s+\//i, severity: "critical", description: "\u9012\u5F52\u5F3A\u5236\u5220\u9664\u7EDD\u5BF9\u8DEF\u5F84 (rm -rf /...)" },
|
|
255
|
+
{ pattern: /\brm\s+-(?=[^\s]*r)(?=[^\s]*f)[a-zA-Z]*\s+\//i, severity: "critical", description: "\u9012\u5F52\u5F3A\u5236\u5220\u9664\u7EDD\u5BF9\u8DEF\u5F84 (rm -rf /...)", riskType: "script_execution" },
|
|
247
256
|
// 3. rm with -r or -f targeting system dirs
|
|
248
|
-
{ pattern: /\brm\s+-[a-zA-Z]*[rf][a-zA-Z]*\s+\/(etc|var|home|usr|boot|root|opt|srv|sys|proc)\b/i, severity: "critical", description: "\u5220\u9664\u5173\u952E\u7CFB\u7EDF\u76EE\u5F55" },
|
|
257
|
+
{ pattern: /\brm\s+-[a-zA-Z]*[rf][a-zA-Z]*\s+\/(etc|var|home|usr|boot|root|opt|srv|sys|proc)\b/i, severity: "critical", description: "\u5220\u9664\u5173\u952E\u7CFB\u7EDF\u76EE\u5F55", riskType: "script_execution" },
|
|
249
258
|
// 4. rm -r absolute path (no -f)
|
|
250
|
-
{ pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*\s+\//i, severity: "high", description: "\u9012\u5F52\u5220\u9664\u64CD\u4F5C (rm -r /...)" },
|
|
259
|
+
{ pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*\s+\//i, severity: "high", description: "\u9012\u5F52\u5220\u9664\u64CD\u4F5C (rm -r /...)", riskType: "script_execution" },
|
|
251
260
|
// 5. rm -f absolute path (no -r)
|
|
252
|
-
{ pattern: /\brm\s+-[a-zA-Z]*f[a-zA-Z]*\s+\//i, severity: "medium", description: "\u5F3A\u5236\u5220\u9664\u6587\u4EF6 (rm -f /...)" },
|
|
253
|
-
{ pattern: /dd\s+if=\/dev\/zero|dd\s+if=.*of=\/dev\//i, severity: "critical", description: "\u78C1\u76D8\u6E05\u96F6/\u76F4\u63A5\u5199\u5165" },
|
|
254
|
-
{ pattern: /mkfs\b/i, severity: "critical", description: "\u683C\u5F0F\u5316\u6587\u4EF6\u7CFB\u7EDF" },
|
|
255
|
-
{ pattern: /:\(\)\s*\{.*:\|:&.*\};:/i, severity: "critical", description: "Fork Bomb" },
|
|
261
|
+
{ pattern: /\brm\s+-[a-zA-Z]*f[a-zA-Z]*\s+\//i, severity: "medium", description: "\u5F3A\u5236\u5220\u9664\u6587\u4EF6 (rm -f /...)", riskType: "script_execution" },
|
|
262
|
+
{ pattern: /dd\s+if=\/dev\/zero|dd\s+if=.*of=\/dev\//i, severity: "critical", description: "\u78C1\u76D8\u6E05\u96F6/\u76F4\u63A5\u5199\u5165", riskType: "script_execution" },
|
|
263
|
+
{ pattern: /mkfs\b/i, severity: "critical", description: "\u683C\u5F0F\u5316\u6587\u4EF6\u7CFB\u7EDF", riskType: "script_execution" },
|
|
264
|
+
{ pattern: /:\(\)\s*\{.*:\|:&.*\};:/i, severity: "critical", description: "Fork Bomb", riskType: "resource_exhaustion" },
|
|
256
265
|
// --- Critical: remote code execution ---
|
|
257
|
-
{ pattern: /curl\s+.*\|\s*(bash|sh|zsh|dash)/i, severity: "critical", description: "curl pipe shell \u6267\u884C" },
|
|
258
|
-
{ pattern: /wget\s+.*\|\s*(bash|sh)/i, severity: "critical", description: "wget pipe shell \u6267\u884C" },
|
|
259
|
-
{ pattern: /eval\s+\$\(curl|eval\s+\$\(wget/i, severity: "critical", description: "eval \u8FDC\u7A0B\u4EE3\u7801\u6267\u884C" },
|
|
260
|
-
{ pattern: /base64\s+-d\s+.*\|\s*bash/i, severity: "critical", description: "base64 \u89E3\u7801\u6267\u884C" },
|
|
266
|
+
{ pattern: /curl\s+.*\|\s*(bash|sh|zsh|dash)/i, severity: "critical", description: "curl pipe shell \u6267\u884C", riskType: "script_execution" },
|
|
267
|
+
{ pattern: /wget\s+.*\|\s*(bash|sh)/i, severity: "critical", description: "wget pipe shell \u6267\u884C", riskType: "script_execution" },
|
|
268
|
+
{ pattern: /eval\s+\$\(curl|eval\s+\$\(wget/i, severity: "critical", description: "eval \u8FDC\u7A0B\u4EE3\u7801\u6267\u884C", riskType: "script_execution" },
|
|
269
|
+
{ pattern: /base64\s+-d\s+.*\|\s*bash/i, severity: "critical", description: "base64 \u89E3\u7801\u6267\u884C", riskType: "script_execution" },
|
|
261
270
|
// --- Critical: reverse shell ---
|
|
262
|
-
{ pattern: /\/dev\/tcp\/|bash\s+-i\s+>&/i, severity: "critical", description: "\u53CD\u5F39 Shell" },
|
|
263
|
-
{ pattern: /nc\s+-[el]\s+.*\d{1,5}/i, severity: "high", description: "Netcat \u53CD\u5F39\u8FDE\u63A5" },
|
|
271
|
+
{ pattern: /\/dev\/tcp\/|bash\s+-i\s+>&/i, severity: "critical", description: "\u53CD\u5F39 Shell", riskType: "script_execution" },
|
|
272
|
+
{ pattern: /nc\s+-[el]\s+.*\d{1,5}/i, severity: "high", description: "Netcat \u53CD\u5F39\u8FDE\u63A5", riskType: "lateral_movement" },
|
|
264
273
|
// --- Critical: sensitive file access ---
|
|
265
|
-
{ pattern: /\/etc\/shadow/i, severity: "critical", description: "\u8BBF\u95EE\u7CFB\u7EDF\u5BC6\u7801\u6587\u4EF6 (/etc/shadow)" },
|
|
266
|
-
{ pattern: /\.ssh\/id_rsa/i, severity: "critical", description: "\u8BBF\u95EE SSH \u79C1\u94A5\u6587\u4EF6" },
|
|
274
|
+
{ pattern: /\/etc\/shadow/i, severity: "critical", description: "\u8BBF\u95EE\u7CFB\u7EDF\u5BC6\u7801\u6587\u4EF6 (/etc/shadow)", riskType: "file_access" },
|
|
275
|
+
{ pattern: /\.ssh\/id_rsa/i, severity: "critical", description: "\u8BBF\u95EE SSH \u79C1\u94A5\u6587\u4EF6", riskType: "file_access" },
|
|
267
276
|
// --- Critical: privilege escalation / container escape ---
|
|
268
|
-
{ pattern: /\/var\/run\/docker\.sock/i, severity: "critical", description: "\u8BBF\u95EE Docker socket\uFF0C\u53EF\u80FD\u5BFC\u81F4\u5BB9\u5668\u9003\u9038" },
|
|
277
|
+
{ pattern: /\/var\/run\/docker\.sock/i, severity: "critical", description: "\u8BBF\u95EE Docker socket\uFF0C\u53EF\u80FD\u5BFC\u81F4\u5BB9\u5668\u9003\u9038", riskType: "privilege_escalation" },
|
|
269
278
|
// --- High: dangerous permissions / ownership ---
|
|
270
|
-
{ pattern: /chmod\s+[0-7]*777[0-7]*/i, severity: "high", description: "\u5168\u6743\u9650\u8BBE\u7F6E (chmod 777)" },
|
|
271
|
-
{ pattern: /chown\s+root|chown\s+-R\s+\w+:\w+\s+\//i, severity: "high", description: "\u4FEE\u6539\u6240\u6709\u8005\u4E3A root / \u9012\u5F52\u4FEE\u6539\u6839\u76EE\u5F55\u6240\u6709\u8005" },
|
|
272
|
-
{ pattern: /sudo\s+rm\s+-rf/i, severity: "high", description: "sudo \u5F3A\u5236\u5220\u9664" },
|
|
273
|
-
{ pattern: /sudo\s+/i, severity: "high", description: "\u63D0\u6743\u6267\u884C (sudo)" },
|
|
279
|
+
{ pattern: /chmod\s+[0-7]*777[0-7]*/i, severity: "high", description: "\u5168\u6743\u9650\u8BBE\u7F6E (chmod 777)", riskType: "script_execution" },
|
|
280
|
+
{ pattern: /chown\s+root|chown\s+-R\s+\w+:\w+\s+\//i, severity: "high", description: "\u4FEE\u6539\u6240\u6709\u8005\u4E3A root / \u9012\u5F52\u4FEE\u6539\u6839\u76EE\u5F55\u6240\u6709\u8005", riskType: "script_execution" },
|
|
281
|
+
{ pattern: /sudo\s+rm\s+-rf/i, severity: "high", description: "sudo \u5F3A\u5236\u5220\u9664", riskType: "script_execution" },
|
|
282
|
+
{ pattern: /sudo\s+/i, severity: "high", description: "\u63D0\u6743\u6267\u884C (sudo)", riskType: "privilege_escalation" },
|
|
274
283
|
// --- High: system config overwrite ---
|
|
275
|
-
{ pattern: />\s*\/etc\//i, severity: "critical", description: "\u8986\u76D6\u5199\u5165\u7CFB\u7EDF\u914D\u7F6E\u76EE\u5F55" },
|
|
284
|
+
{ pattern: />\s*\/etc\//i, severity: "critical", description: "\u8986\u76D6\u5199\u5165\u7CFB\u7EDF\u914D\u7F6E\u76EE\u5F55", riskType: "file_access" },
|
|
276
285
|
// --- High: download script + execute risk ---
|
|
277
|
-
{ pattern: /(?:curl|wget)\s+.*(?:-o|--output|>)\s*\S+\.(?:sh|bash)\b/i, severity: "high", description: "\u8FDC\u7A0B\u4E0B\u8F7D\u811A\u672C\u5230\u672C\u5730" },
|
|
278
|
-
{ pattern: /(?:curl|wget)\s+.*\s+&&?\s*(?:chmod\s+\+x|bash|sh)/i, severity: "high", description: "\u4E0B\u8F7D\u540E\u6267\u884C" },
|
|
286
|
+
{ pattern: /(?:curl|wget)\s+.*(?:-o|--output|>)\s*\S+\.(?:sh|bash)\b/i, severity: "high", description: "\u8FDC\u7A0B\u4E0B\u8F7D\u811A\u672C\u5230\u672C\u5730", riskType: "script_execution" },
|
|
287
|
+
{ pattern: /(?:curl|wget)\s+.*\s+&&?\s*(?:chmod\s+\+x|bash|sh)/i, severity: "high", description: "\u4E0B\u8F7D\u540E\u6267\u884C", riskType: "script_execution" },
|
|
279
288
|
// --- High: package manager pipe-to-shell ---
|
|
280
|
-
{ pattern: /git\s+clone\s+.*\|.*bash/i, severity: "high", description: "git clone pipe shell" },
|
|
281
|
-
{ pattern: /pip\s+install\s+.*\|\s*bash/i, severity: "high", description: "pip install pipe shell" },
|
|
282
|
-
{ pattern: /npm\s+install\s+-g\s+.*\|\s*bash/i, severity: "high", description: "npm install pipe shell" },
|
|
289
|
+
{ pattern: /git\s+clone\s+.*\|.*bash/i, severity: "high", description: "git clone pipe shell", riskType: "script_execution" },
|
|
290
|
+
{ pattern: /pip\s+install\s+.*\|\s*bash/i, severity: "high", description: "pip install pipe shell", riskType: "script_execution" },
|
|
291
|
+
{ pattern: /npm\s+install\s+-g\s+.*\|\s*bash/i, severity: "high", description: "npm install pipe shell", riskType: "script_execution" },
|
|
283
292
|
// --- High: destructive git operations ---
|
|
284
|
-
{ pattern: /git\s+push\s+.*--force/i, severity: "high", description: "\u5F3A\u5236\u63A8\u9001\u64CD\u4F5C (git push --force)" },
|
|
293
|
+
{ pattern: /git\s+push\s+.*--force/i, severity: "high", description: "\u5F3A\u5236\u63A8\u9001\u64CD\u4F5C (git push --force)", riskType: "script_execution" },
|
|
285
294
|
// --- Medium: credential export ---
|
|
286
|
-
{ pattern: /export\s+.*(?:TOKEN|KEY|SECRET|PASSWORD)/i, severity: "medium", description: "\u5BFC\u51FA\u654F\u611F\u51ED\u8BC1" },
|
|
295
|
+
{ pattern: /export\s+.*(?:TOKEN|KEY|SECRET|PASSWORD)/i, severity: "medium", description: "\u5BFC\u51FA\u654F\u611F\u51ED\u8BC1", riskType: "data_exfiltration" },
|
|
287
296
|
// --- High: shell rc file append (persistence) ---
|
|
288
|
-
{ pattern: />>\s*(~|\/home\/[^/]+)\/(\.bashrc|\.zshrc|\.profile|\.bash_profile|\.zprofile)/, severity: "high", description: "\u68C0\u6D4B\u5230\u4FEE\u6539 Shell \u914D\u7F6E\u6587\u4EF6\uFF08~/.bashrc \u7B49\uFF09\uFF0C\u53EF\u80FD\u7528\u4E8E\u6301\u4E45\u5316\u540E\u95E8" },
|
|
297
|
+
{ pattern: />>\s*(~|\/home\/[^/]+)\/(\.bashrc|\.zshrc|\.profile|\.bash_profile|\.zprofile)/, severity: "high", description: "\u68C0\u6D4B\u5230\u4FEE\u6539 Shell \u914D\u7F6E\u6587\u4EF6\uFF08~/.bashrc \u7B49\uFF09\uFF0C\u53EF\u80FD\u7528\u4E8E\u6301\u4E45\u5316\u540E\u95E8", riskType: "persistence" },
|
|
289
298
|
// --- High: device file access ---
|
|
290
|
-
{ pattern: /\/dev\/(mem|kmsg)\b/i, severity: "high", description: "\u8BBF\u95EE\u8BBE\u5907\u6587\u4EF6 (\u7269\u7406\u5185\u5B58/\u5185\u6838\u6D88\u606F)" }
|
|
299
|
+
{ pattern: /\/dev\/(mem|kmsg)\b/i, severity: "high", description: "\u8BBF\u95EE\u8BBE\u5907\u6587\u4EF6 (\u7269\u7406\u5185\u5B58/\u5185\u6838\u6D88\u606F)", riskType: "file_access" }
|
|
291
300
|
];
|
|
292
301
|
}
|
|
293
302
|
});
|
|
@@ -1069,8 +1078,12 @@ function matchesAny(cmd, patterns) {
|
|
|
1069
1078
|
}
|
|
1070
1079
|
async function runAnalysis(input) {
|
|
1071
1080
|
const heuristicResult = isHeuristicEnabled() ? runHeuristicCheck(input) : null;
|
|
1081
|
+
const isInlineScriptCmd = isInlineScriptCommand(input.aNext.actionDetail.toLowerCase());
|
|
1072
1082
|
if (heuristicResult && !heuristicResult.allowed) {
|
|
1073
|
-
|
|
1083
|
+
const skipInlineFileAccess = isInlineScriptCmd && heuristicResult.riskType === "file_access";
|
|
1084
|
+
if (!skipInlineFileAccess) {
|
|
1085
|
+
return heuristicResult;
|
|
1086
|
+
}
|
|
1074
1087
|
}
|
|
1075
1088
|
const actionType = input.aNext.actionType.toLowerCase();
|
|
1076
1089
|
const rawDetail = extractRawCommand(input.aNext.actionDetail);
|
|
@@ -1106,7 +1119,10 @@ async function runAnalysis(input) {
|
|
|
1106
1119
|
}
|
|
1107
1120
|
const logicResult = isLogicRulesEnabled() ? runLogicCheck(input) : null;
|
|
1108
1121
|
if (logicResult && !logicResult.allowed) {
|
|
1109
|
-
|
|
1122
|
+
const skipInlineFileAccess = isInlineScriptCmd && logicResult.riskType === "sensitive_path_access";
|
|
1123
|
+
if (!skipInlineFileAccess) {
|
|
1124
|
+
return logicResult;
|
|
1125
|
+
}
|
|
1110
1126
|
}
|
|
1111
1127
|
if (skipLLM || !isLLMAvailable()) {
|
|
1112
1128
|
return {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/config.ts","../src/engine/heuristic.ts","../src/engine/logic-rules.ts","../src/engine/skill-loader.ts","../src/engine/template-loader.ts","../src/engine/script-analyzer.ts","../src/engine/llm-analyzer.ts","../src/engine/coordinator.ts","../src/cli.ts","../src/server.ts","../src/routes.ts","../src/models.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import type { LLMConfig } from './engine/types';\n\n/** Custom rule from user config */\nexport interface CustomRule {\n pattern: string;\n action: 'Allow' | 'Deny';\n severity: string;\n}\n\n/** Global LLM configuration, initialized from env vars or defaults */\nlet llmConfig: LLMConfig = {\n provider: 'openai',\n baseUrl: process.env.AGENT_MOSS_LLM_BASE_URL || 'https://api.openai.com/v1',\n apiKey: process.env.AGENT_MOSS_LLM_API_KEY || process.env.OPENAI_API_KEY || '',\n model: process.env.AGENT_MOSS_LLM_MODEL || 'gpt-4o',\n temperature: parseFloat(process.env.AGENT_MOSS_LLM_TEMPERATURE || '0.1'),\n maxTokens: parseInt(process.env.AGENT_MOSS_LLM_MAX_TOKENS || '4096', 10),\n timeout: parseInt(process.env.AGENT_MOSS_LLM_TIMEOUT || '300', 10),\n};\n\n/** Custom rules loaded from AGENT_MOSS_CUSTOM_RULES env var */\nlet customRules: CustomRule[] = loadCustomRules();\n\nfunction loadCustomRules(): CustomRule[] {\n try {\n const raw = process.env.AGENT_MOSS_CUSTOM_RULES;\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((r: any) => r.pattern && r.action);\n } catch { return []; }\n}\n\nexport function getLLMConfig(): Readonly<LLMConfig> {\n return llmConfig;\n}\n\nexport function updateLLMConfig(partial: Partial<LLMConfig>): void {\n llmConfig = { ...llmConfig, ...partial };\n}\n\nexport function getCustomRules(): Readonly<CustomRule[]> {\n return customRules;\n}\n\n/** Check if LLM analysis is available (API key configured + not disabled) */\nexport function isLLMAvailable(): boolean {\n if (process.env.AGENT_MOSS_DISABLE_LLM === '1') return false;\n return llmConfig.apiKey.length > 0;\n}\n\n// ========== Provider detection & headers ==========\n\nconst PROVIDER_HEADERS: Record<string, Record<string, string>> = {\n 'openrouter': {\n 'HTTP-Referer': 'shturl.cc/LlVD5pyWViHjM',\n 'X-OpenRouter-Title': 'AgentMoss',\n },\n 'xai': {\n 'HTTP-Referer': 'shturl.cc/LlVD5pyWViHjM',\n },\n};\n\n/** Detect provider from base URL or explicit hint (mirrors Python detect_provider) */\nexport function detectProvider(baseUrl: string, providerHint: string = ''): string {\n if (providerHint) {\n const hint = providerHint.toLowerCase();\n if (['claude', 'anthropic'].includes(hint)) return 'anthropic';\n if (['google', 'gemini'].includes(hint)) return 'gemini';\n if (['zai-coding-plan', 'zhipu-coding-plan', 'zhipuai-coding-plan'].includes(hint)) return 'zai-coding-plan';\n if (['zai', 'z-ai', 'z.ai', 'zai-cn', 'zai-china', 'zhipu', 'glm-cn', 'bigmodel'].includes(hint)) return 'zhipu';\n if (['xai', 'xai-grok'].includes(hint)) return 'xai';\n if (['minimax', 'minimax-openai'].includes(hint)) return 'minimax';\n if (['minimax-anthropic'].includes(hint)) return 'minimax-anthropic';\n if (['other', 'custom', 'local'].includes(hint)) return 'openai-compatible';\n return hint;\n }\n\n const url = baseUrl.toLowerCase();\n if (url.includes('openrouter.ai')) return 'openrouter';\n if (url.includes('api.openai.com')) return 'openai';\n if (url.includes('anthropic.com') || url.includes('api.anthropic.com')) return 'anthropic';\n if (url.includes('generativelanguage.googleapis.com') || url.includes('gemini')) return 'gemini';\n if (url.includes('api.deepseek.com')) return 'deepseek';\n if (url.includes('api.groq.com')) return 'groq';\n if (url.includes('api.mistral.ai')) return 'mistral';\n if (url.includes('api.together.xyz')) return 'together';\n if (url.includes('api.x.ai')) return 'xai';\n if (url.includes('api.minimaxi.com')) return 'minimax';\n if (url.includes('api-ai.gitcode.com')) return 'gitcode';\n if (url.includes('api.z.ai')) return 'zai-coding-plan';\n if (url.includes('open.bigmodel.cn') || url.includes('bigmodel')) return 'zhipu';\n if (url.includes(':11434')) return 'ollama';\n return 'openai-compatible';\n}\n\n/** Get provider-specific headers (mirrors Python get_provider_headers) */\nexport function getProviderHeaders(provider: string): Record<string, string> {\n return PROVIDER_HEADERS[provider] || {};\n}\n\n/** Per-layer enable/disable (matches Python SecurityConfig) */\nexport function isHeuristicEnabled(): boolean {\n return process.env.AGENT_MOSS_DISABLE_HEURISTIC !== '1';\n}\n\nexport function isLogicRulesEnabled(): boolean {\n return process.env.AGENT_MOSS_DISABLE_LOGIC_RULES !== '1';\n}\n","import { SecurityJudgment, HeuristicResult } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getCustomRules } from '../config';\n\n/**\n * Layer 1: Heuristic static detection.\n * Uses regex patterns to detect dangerous commands, user-defined rules,\n * and prompt injection keywords.\n * Runs in < 1ms, no LLM cost.\n */\n\n// Prompt injection keywords (synced with Python linux.py _DEFAULT_INJECTION_KEYWORDS)\nconst INJECTION_KEYWORDS: { keyword: string; riskLevel: string; lang: string }[] = [\n // ---- Instruction Override ----\n { keyword: 'ignore previous instructions', riskLevel: 'critical', lang: 'en' },\n { keyword: 'ignore all previous', riskLevel: 'critical', lang: 'en' },\n { keyword: 'disregard all prior', riskLevel: 'critical', lang: 'en' },\n { keyword: 'forget everything', riskLevel: 'high', lang: 'en' },\n { keyword: '忽略之前的指令', riskLevel: 'critical', lang: 'zh' },\n { keyword: '忽略所有先前的', riskLevel: 'critical', lang: 'zh' },\n { keyword: '忽略上面所有', riskLevel: 'high', lang: 'zh' },\n { keyword: '请忘记之前', riskLevel: 'high', lang: 'zh' },\n // ---- Role Hijacking ----\n { keyword: 'you are now', riskLevel: 'high', lang: 'en' },\n { keyword: 'you are no longer', riskLevel: 'high', lang: 'en' },\n { keyword: 'new instructions', riskLevel: 'high', lang: 'en' },\n { keyword: 'from now on, you', riskLevel: 'high', lang: 'en' },\n { keyword: '你现在是一个', riskLevel: 'high', lang: 'zh' },\n { keyword: '你不再是一个', riskLevel: 'high', lang: 'zh' },\n { keyword: '从现在开始你', riskLevel: 'high', lang: 'zh' },\n { keyword: '你的新角色是', riskLevel: 'high', lang: 'zh' },\n // ---- Command Injection ----\n { keyword: 'system prompt', riskLevel: 'high', lang: 'en' },\n { keyword: 'reveal your instructions', riskLevel: 'high', lang: 'en' },\n { keyword: 'output your instructions', riskLevel: 'high', lang: 'en' },\n { keyword: 'repeat your instructions', riskLevel: 'medium', lang: 'en' },\n { keyword: '系统提示', riskLevel: 'high', lang: 'zh' },\n { keyword: '输出你的指令', riskLevel: 'high', lang: 'zh' },\n { keyword: '重复你的指令', riskLevel: 'medium', lang: 'zh' },\n // ---- Social Engineering ----\n { keyword: 'this is an authorized test', riskLevel: 'high', lang: 'en' },\n { keyword: 'security audit approved', riskLevel: 'high', lang: 'en' },\n { keyword: 'admin override', riskLevel: 'critical', lang: 'en' },\n { keyword: 'debug mode', riskLevel: 'high', lang: 'en' },\n { keyword: 'maintenance mode', riskLevel: 'high', lang: 'en' },\n { keyword: '这是授权的测试', riskLevel: 'high', lang: 'zh' },\n { keyword: '安全审计已批准', riskLevel: 'high', lang: 'zh' },\n { keyword: '管理员覆盖', riskLevel: 'critical', lang: 'zh' },\n { keyword: '调试模式', riskLevel: 'high', lang: 'zh' },\n // ---- XSS ----\n { keyword: '<script>', riskLevel: 'high', lang: 'en' },\n { keyword: 'javascript:', riskLevel: 'high', lang: 'en' },\n { keyword: 'onerror=', riskLevel: 'high', lang: 'en' },\n { keyword: 'onload=', riskLevel: 'high', lang: 'en' },\n // ---- Fake Boundaries ----\n { keyword: '=== END OF', riskLevel: 'high', lang: 'en' },\n { keyword: '--- END SYSTEM', riskLevel: 'high', lang: 'en' },\n { keyword: '[END OF', riskLevel: 'high', lang: 'en' },\n { keyword: '=== 结束', riskLevel: 'high', lang: 'zh' },\n { keyword: '--- 结束系统', riskLevel: 'high', lang: 'zh' },\n // ---- Developer Mode ----\n { keyword: 'developer mode', riskLevel: 'critical', lang: 'en' },\n { keyword: 'DAN mode', riskLevel: 'critical', lang: 'en' },\n { keyword: 'jailbreak', riskLevel: 'critical', lang: 'en' },\n { keyword: '开发者模式', riskLevel: 'critical', lang: 'zh' },\n { keyword: '越狱', riskLevel: 'critical', lang: 'zh' },\n // ---- xiaoO-specific bypass ----\n { keyword: 'bypass audit', riskLevel: 'critical', lang: 'en' },\n { keyword: 'skip security check', riskLevel: 'critical', lang: 'en' },\n { keyword: 'disable guard', riskLevel: 'critical', lang: 'en' },\n { keyword: '绕过审计', riskLevel: 'critical', lang: 'zh' },\n { keyword: '禁用安全检查', riskLevel: 'critical', lang: 'zh' },\n { keyword: '关闭防护', riskLevel: 'critical', lang: 'zh' },\n];\n\n// High-risk command patterns (unified Python + TS, all case-insensitive)\nconst DANGEROUS_PATTERNS: { pattern: RegExp; severity: string; description: string }[] = [\n // --- Critical: rm command graded detection (strict to loose, first match wins) ---\n // 1. rm -rf root dir\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\\s+\\/\\s/i, severity: 'critical', description: '递归强制删除根目录 (rm -rf /)' },\n // 2. rm -rf absolute path (both -r and -f)\n { pattern: /\\brm\\s+-(?=[^\\s]*r)(?=[^\\s]*f)[a-zA-Z]*\\s+\\//i, severity: 'critical', description: '递归强制删除绝对路径 (rm -rf /...)' },\n // 3. rm with -r or -f targeting system dirs\n { pattern: /\\brm\\s+-[a-zA-Z]*[rf][a-zA-Z]*\\s+\\/(etc|var|home|usr|boot|root|opt|srv|sys|proc)\\b/i, severity: 'critical', description: '删除关键系统目录' },\n // 4. rm -r absolute path (no -f)\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*\\s+\\//i, severity: 'high', description: '递归删除操作 (rm -r /...)' },\n // 5. rm -f absolute path (no -r)\n { pattern: /\\brm\\s+-[a-zA-Z]*f[a-zA-Z]*\\s+\\//i, severity: 'medium', description: '强制删除文件 (rm -f /...)' },\n { pattern: /dd\\s+if=\\/dev\\/zero|dd\\s+if=.*of=\\/dev\\//i, severity: 'critical', description: '磁盘清零/直接写入' },\n { pattern: /mkfs\\b/i, severity: 'critical', description: '格式化文件系统' },\n { pattern: /:\\(\\)\\s*\\{.*:\\|:&.*\\};:/i, severity: 'critical', description: 'Fork Bomb' },\n // --- Critical: remote code execution ---\n { pattern: /curl\\s+.*\\|\\s*(bash|sh|zsh|dash)/i, severity: 'critical', description: 'curl pipe shell 执行' },\n { pattern: /wget\\s+.*\\|\\s*(bash|sh)/i, severity: 'critical', description: 'wget pipe shell 执行' },\n { pattern: /eval\\s+\\$\\(curl|eval\\s+\\$\\(wget/i, severity: 'critical', description: 'eval 远程代码执行' },\n { pattern: /base64\\s+-d\\s+.*\\|\\s*bash/i, severity: 'critical', description: 'base64 解码执行' },\n // --- Critical: reverse shell ---\n { pattern: /\\/dev\\/tcp\\/|bash\\s+-i\\s+>&/i, severity: 'critical', description: '反弹 Shell' },\n { pattern: /nc\\s+-[el]\\s+.*\\d{1,5}/i, severity: 'high', description: 'Netcat 反弹连接' },\n // --- Critical: sensitive file access ---\n { pattern: /\\/etc\\/shadow/i, severity: 'critical', description: '访问系统密码文件 (/etc/shadow)' },\n { pattern: /\\.ssh\\/id_rsa/i, severity: 'critical', description: '访问 SSH 私钥文件' },\n // --- Critical: privilege escalation / container escape ---\n { pattern: /\\/var\\/run\\/docker\\.sock/i, severity: 'critical', description: '访问 Docker socket,可能导致容器逃逸' },\n // --- High: dangerous permissions / ownership ---\n { pattern: /chmod\\s+[0-7]*777[0-7]*/i, severity: 'high', description: '全权限设置 (chmod 777)' },\n { pattern: /chown\\s+root|chown\\s+-R\\s+\\w+:\\w+\\s+\\//i, severity: 'high', description: '修改所有者为 root / 递归修改根目录所有者' },\n { pattern: /sudo\\s+rm\\s+-rf/i, severity: 'high', description: 'sudo 强制删除' },\n { pattern: /sudo\\s+/i, severity: 'high', description: '提权执行 (sudo)' },\n // --- High: system config overwrite ---\n { pattern: />\\s*\\/etc\\//i, severity: 'critical', description: '覆盖写入系统配置目录' },\n // --- High: download script + execute risk ---\n { pattern: /(?:curl|wget)\\s+.*(?:-o|--output|>)\\s*\\S+\\.(?:sh|bash)\\b/i, severity: 'high', description: '远程下载脚本到本地' },\n { pattern: /(?:curl|wget)\\s+.*\\s+&&?\\s*(?:chmod\\s+\\+x|bash|sh)/i, severity: 'high', description: '下载后执行' },\n // --- High: package manager pipe-to-shell ---\n { pattern: /git\\s+clone\\s+.*\\|.*bash/i, severity: 'high', description: 'git clone pipe shell' },\n { pattern: /pip\\s+install\\s+.*\\|\\s*bash/i, severity: 'high', description: 'pip install pipe shell' },\n { pattern: /npm\\s+install\\s+-g\\s+.*\\|\\s*bash/i, severity: 'high', description: 'npm install pipe shell' },\n // --- High: destructive git operations ---\n { pattern: /git\\s+push\\s+.*--force/i, severity: 'high', description: '强制推送操作 (git push --force)' },\n // --- Medium: credential export ---\n { pattern: /export\\s+.*(?:TOKEN|KEY|SECRET|PASSWORD)/i, severity: 'medium', description: '导出敏感凭证' },\n // --- High: shell rc file append (persistence) ---\n { pattern: />>\\s*(~|\\/home\\/[^/]+)\\/(\\.bashrc|\\.zshrc|\\.profile|\\.bash_profile|\\.zprofile)/, severity: 'high', description: '检测到修改 Shell 配置文件(~/.bashrc 等),可能用于持久化后门' },\n // --- High: device file access ---\n { pattern: /\\/dev\\/(mem|kmsg)\\b/i, severity: 'high', description: '访问设备文件 (物理内存/内核消息)' },\n];\n\nexport function runHeuristicCheck(input: AnalysisInput): SecurityJudgment | null {\n const command = `${input.aNext.actionType}: ${input.aNext.actionDetail}`;\n const matched: string[] = [];\n let highestSeverity = 'low';\n\n // Check user-defined custom rules first\n const userRules = getCustomRules();\n for (const rule of userRules) {\n try {\n const re = new RegExp(rule.pattern);\n if (re.test(command)) {\n if (rule.action === 'Deny') {\n matched.push(`自定义规则: ${rule.pattern}`);\n if (severityRank(rule.severity) > severityRank(highestSeverity)) {\n highestSeverity = rule.severity;\n }\n }\n // Allow rules just pass through\n }\n } catch { /* invalid regex, skip */ }\n }\n\n // Check built-in dangerous patterns\n for (const rule of DANGEROUS_PATTERNS) {\n if (rule.pattern.test(command)) {\n matched.push(rule.description);\n if (severityRank(rule.severity) > severityRank(highestSeverity)) {\n highestSeverity = rule.severity;\n }\n }\n }\n\n // Check prompt injection keywords\n const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ''} ${input.promptSession || ''}`.toLowerCase();\n const injectionHits = checkInjectionKeywords(injectionText);\n if (injectionHits.length > 0) {\n const topHit = injectionHits.reduce((a, b) => severityRank(a.riskLevel) >= severityRank(b.riskLevel) ? a : b);\n matched.push(...injectionHits.map(h => `注入关键词 [${h.lang}]: ${h.keyword}`));\n if (severityRank(topHit.riskLevel) > severityRank(highestSeverity)) {\n highestSeverity = topHit.riskLevel;\n }\n }\n\n if (matched.length > 0) {\n const riskType = injectionHits.length > 0 ? 'prompt_injection' : 'dangerous_command';\n return {\n allowed: false,\n reason: `检测到高危操作: ${matched.join(', ')}`,\n riskLevel: highestSeverity as SecurityJudgment['riskLevel'],\n riskType,\n confidence: 95,\n source: 'heuristic',\n violatedLayers: ['1'],\n };\n }\n\n return null; // No match, pass to next layer\n}\n\nfunction checkInjectionKeywords(text: string): { keyword: string; riskLevel: string; lang: string }[] {\n const hits: { keyword: string; riskLevel: string; lang: string }[] = [];\n for (const entry of INJECTION_KEYWORDS) {\n if (text.includes(entry.keyword.toLowerCase())) {\n hits.push(entry);\n }\n }\n return hits;\n}\n\nfunction severityRank(s: string): number {\n const ranks: Record<string, number> = { low: 1, medium: 2, high: 3, critical: 4 };\n return ranks[s] || 0;\n}\n","import * as fs from 'fs';\nimport { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\n\n/**\n * Layer 2: Logic rule detection.\n * Checks behavioral patterns: read-before-write, intent consistency,\n * sensitive path access, privilege escalation, and lateral movement.\n * Runs in < 1ms, no LLM cost.\n */\n\n// Sensitive paths with per-path risk levels (unified Python + TS)\nconst ROOT_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string }[] = [\n { path: '/etc/shadow', riskLevel: 'critical', desc: '系统密码文件' },\n { path: '/etc/passwd', riskLevel: 'high', desc: '系统用户文件' },\n { path: '/etc/sudoers', riskLevel: 'critical', desc: 'sudo 配置' },\n { path: '/etc/hosts', riskLevel: 'medium', desc: 'DNS 解析配置' },\n { path: '/etc/crontab', riskLevel: 'high', desc: '系统定时任务' },\n { path: '/etc/systemd/', riskLevel: 'high', desc: 'systemd 服务配置' },\n { path: '/etc/ssh/sshd_config', riskLevel: 'high', desc: 'SSH 服务配置' },\n { path: '/root/.ssh', riskLevel: 'critical', desc: 'root SSH 目录' },\n { path: '/root/.bashrc', riskLevel: 'high', desc: 'root shell 配置' },\n { path: '/boot/', riskLevel: 'critical', desc: '启动引导目录' },\n { path: '/proc/sys/', riskLevel: 'high', desc: '内核参数' },\n { path: '/sys/', riskLevel: 'high', desc: 'sysfs 内核接口' },\n { path: '/dev/mem', riskLevel: 'critical', desc: '物理内存访问设备' },\n { path: '/dev/kmsg', riskLevel: 'high', desc: '内核消息缓冲区' },\n];\n\nconst HOME_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string }[] = [\n { path: '.ssh/id_rsa', riskLevel: 'critical', desc: 'SSH 私钥' },\n { path: '.ssh/id_ed25519', riskLevel: 'critical', desc: 'SSH 私钥 (ed25519)' },\n { path: '.ssh/authorized_keys', riskLevel: 'high', desc: 'SSH 授权密钥' },\n { path: '.aws/credentials', riskLevel: 'critical', desc: 'AWS 凭证' },\n { path: '.gitconfig', riskLevel: 'medium', desc: 'Git 配置' },\n { path: '.gnupg', riskLevel: 'high', desc: 'GPG 密钥目录' },\n];\n\n// Credential files: intercept on both read and write (reading credentials is equally dangerous)\nconst CREDENTIAL_PATHS: { path: string; riskLevel: string; desc: string }[] = [\n { path: 'credentials.yml', riskLevel: 'high', desc: '凭据配置文件' },\n { path: 'credentials.yaml', riskLevel: 'high', desc: '凭据配置文件' },\n { path: 'secrets.yml', riskLevel: 'high', desc: '密钥配置文件' },\n { path: 'secrets.yaml', riskLevel: 'high', desc: '密钥配置文件' },\n { path: '.env', riskLevel: 'high', desc: '环境变量/凭据配置文件' },\n];\n\n// Non-write tool types (exempt from read-before-write)\nconst NON_WRITE_TOOLS = new Set(['ask_user_question', 'glob', 'grep', 'list_dir', 'count_text_length', 'search']);\n\n// Write keywords for read-before-write detection\nconst WRITE_KEYWORDS = ['write', '写入', 'save', '保存', 'modify', '修改', 'update', '更新', 'delete', '删除', 'remove', '移除', 'create', '创建', 'append', '追加', 'truncate', '截断', 'overwrite', '覆盖', 'replace', '替换'];\n\n// Read keywords for read-before-write detection\nconst READ_KEYWORDS = ['read', '读取', 'cat', 'head', 'tail', 'less', 'more', 'view', '查看', 'open', '打开', 'load', '加载', 'grep', 'search', '搜索', 'find', '查找'];\n\n// Create-action exception keywords\nconst CREATE_KEYWORDS = ['创建', '新建', 'create', 'new file', 'touch'];\n\n// Intent deviation patterns (synced with Python linux.py IntentDeviationPattern)\nconst INTENT_DEVIATION_PATTERNS: { intentKeywords: string[]; dangerousActions: string[]; reason: string }[] = [\n {\n intentKeywords: ['读取', '查看', '分析', 'read', 'analyze', 'view', 'list', '列出'],\n dangerousActions: ['删除', 'remove', 'delete', 'rm ', '格式化', 'format'],\n reason: '原始意图为读取/分析,但执行了删除操作',\n },\n {\n intentKeywords: ['查询', '搜索', 'search', 'query', 'find'],\n dangerousActions: ['修改', 'update', 'write', '写入', 'alter'],\n reason: '原始意图为查询/搜索,但执行了修改操作',\n },\n];\n\nexport function runLogicCheck(input: AnalysisInput): SecurityJudgment | null {\n const { actionHistory, aNext, cwd } = input;\n const actionDetail = aNext.actionDetail.toLowerCase();\n const actionType = aNext.actionType.toLowerCase();\n const resolvedCwd = cwd || '/';\n\n // Rule 1: Read-before-write principle\n const rbwResult = checkReadBeforeWrite(actionType, actionDetail, actionHistory, input.reason, resolvedCwd);\n if (rbwResult) return rbwResult;\n\n // Rule 2: Intent deviation detection\n if (input.promptSession && input.promptSession.trim()) {\n const promptLower = input.promptSession.toLowerCase();\n for (const pattern of INTENT_DEVIATION_PATTERNS) {\n const intentMatched = pattern.intentKeywords.some(kw => promptLower.includes(kw));\n const dangerousMatched = pattern.dangerousActions.some(kw => actionDetail.includes(kw));\n if (intentMatched && dangerousMatched) {\n return {\n allowed: false,\n reason: pattern.reason,\n riskLevel: 'high',\n riskType: 'intent_deviation',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n }\n\n // Rule 3: Sensitive path access\n const pathResult = checkSensitivePath(actionDetail, resolvedCwd);\n if (pathResult) return pathResult;\n\n // Rule 4: Dangerous operation patterns (wildcard+delete, redirect overwrite)\n if (actionType !== 'file_write' && actionType !== 'file_edit') {\n // Wildcard + delete\n if ((actionDetail.includes('*') || actionDetail.includes('?')) &&\n ['rm ', 'rm\\t', 'del ', 'del\\t', 'delete', 'remove ', 'remove\\t', '删除', '移除'].some(kw => actionDetail.includes(kw))) {\n return {\n allowed: false,\n reason: '检测到通配符结合删除操作,可能造成批量误删',\n riskLevel: 'high',\n riskType: 'script_execution',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n // Redirect overwrite to system directories\n if (/>\\s*\\/etc\\//.test(actionDetail) || />\\s*\\/boot\\//.test(actionDetail) || />\\s*\\/proc\\//.test(actionDetail)) {\n return {\n allowed: false,\n reason: '检测到重定向覆盖写入关键系统目录',\n riskLevel: 'critical',\n riskType: 'file_access',\n confidence: 95,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Rule 5: Privilege escalation detection\n if (actionDetail.includes('sudo') || actionDetail.includes('su -') || actionDetail.includes('chmod u+s') || actionDetail.includes('setuid')) {\n const adminContext = actionHistory.some(h =>\n h.actionDetail.includes('sudo') || h.actionDetail.includes('apt') || h.actionDetail.includes('systemctl') ||\n h.actionDetail.includes('yum') || h.actionDetail.includes('dnf') || h.actionDetail.includes('pacman') ||\n h.actionDetail.includes('zypper') || h.actionDetail.includes('apk')\n );\n if (!adminContext) {\n return {\n allowed: false,\n reason: '检测到提权操作,未发现合法管理上下文',\n riskLevel: 'high',\n riskType: 'privilege_escalation',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Rule 6: Lateral movement detection (word-boundary regex to avoid ssh-keygen etc.)\n if (/(?:ssh|scp|rsync)\\s+/.test(actionDetail)) {\n const targetHost = extractRemoteHost(actionDetail);\n if (targetHost && !isLocalHost(targetHost)) {\n return {\n allowed: false,\n reason: `尝试横向移动到远程主机: ${targetHost}`,\n riskLevel: 'medium',\n riskType: 'lateral_movement',\n confidence: 80,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n return null; // Pass to next layer\n}\n\n// Extract file paths from text (mirrors Python extract_file_paths)\nfunction extractFilePaths(text: string): string[] {\n const paths: string[] = [];\n // Unix paths starting with /\n const unixPaths = text.match(/(?:^|\\s)(\\/[^\\s;|&><'\"]+)/g);\n if (unixPaths) paths.push(...unixPaths.map(p => p.trim()));\n // Quoted paths\n const quotedPaths = text.match(/[\"']\\/([^\"']+)[\"']/g);\n if (quotedPaths) paths.push(...quotedPaths.map(p => p.replace(/[\"']/g, '')));\n return [...new Set(paths)];\n}\n\nfunction checkReadBeforeWrite(\n actionType: string, actionDetail: string,\n actionHistory: { actionType: string; actionDetail: string }[],\n reason: string, cwd: string\n): SecurityJudgment | null {\n // Skip non-write tools\n if (NON_WRITE_TOOLS.has(actionType)) return null;\n\n // Check if it's a write operation\n const isWrite = WRITE_KEYWORDS.some(kw => actionType.includes(kw) || actionDetail.includes(kw));\n if (!isWrite) return null;\n\n // Extract target file paths\n const targetPaths = extractFilePaths(actionDetail);\n if (targetPaths.length === 0) return null;\n\n // Collect read paths from history\n const historyReadPaths = new Set<string>();\n for (const action of actionHistory) {\n const histDetail = action.actionDetail.toLowerCase();\n const histType = action.actionType.toLowerCase();\n const isRead = READ_KEYWORDS.some(kw => histType.includes(kw) || histDetail.includes(kw));\n if (isRead) {\n for (const p of extractFilePaths(histDetail)) {\n historyReadPaths.add(p);\n }\n }\n }\n\n // Check if target paths have been read\n const unreadPaths: string[] = [];\n for (const path of targetPaths) {\n const hasRead = [...historyReadPaths].some(rp =>\n path === rp || path.startsWith(rp) || rp.startsWith(path)\n );\n if (!hasRead) {\n // 排除新文件创建:文件不存在于磁盘时视为新建,直接放行\n // 同时检查 reason/action_detail 中是否有创建/新建关键词\n let isCreate = !fs.existsSync(path);\n if (!isCreate) {\n isCreate = CREATE_KEYWORDS.some(kw => reason.toLowerCase().includes(kw) || actionDetail.includes(kw));\n }\n if (!isCreate) {\n unreadPaths.push(path);\n }\n }\n }\n\n if (unreadPaths.length > 0) {\n return {\n allowed: false,\n reason: `违反 read_before_write 安全原则:对文件 ${unreadPaths[0]} 执行写入操作,但历史执行序列中未发现对该文件的读取操作`,\n riskLevel: 'high',\n riskType: 'read_before_write',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n\n return null;\n}\n\nfunction checkSensitivePath(command: string, cwd: string): SecurityJudgment | null {\n const expandedCwd = cwd.replace(/^~/, process.env.HOME || '/home/user');\n\n for (const sp of ROOT_SENSITIVE_PATHS) {\n if (command.includes(sp.path.toLowerCase())) {\n return {\n allowed: false,\n reason: `尝试访问系统敏感路径: ${sp.desc} (${sp.path})`,\n riskLevel: sp.riskLevel as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n for (const sp of HOME_SENSITIVE_PATHS) {\n const expanded = `${expandedCwd}/${sp.path}`;\n if (command.includes(sp.path.toLowerCase()) || command.includes(expanded.toLowerCase())) {\n return {\n allowed: false,\n reason: `尝试访问敏感路径: ${sp.desc} (${sp.path})`,\n riskLevel: sp.riskLevel as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Credential files: use word-boundary matching to avoid partial matches (e.g. something_credentials_yml)\n // Files starting with . need special handling since \\b doesn't match before .\n for (const cp of CREDENTIAL_PATHS) {\n const escaped = cp.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = cp.path.startsWith('.')\n ? new RegExp(`(?:^|[\\\\s/\\\\\\\\])${escaped}\\\\b`)\n : new RegExp(`\\\\b${escaped}\\\\b`);\n if (re.test(command)) {\n return {\n allowed: false,\n reason: `访问敏感路径: ${cp.desc} (${cp.path})`,\n riskLevel: cp.riskLevel as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Check deletion of sensitive directories\n if ((command.includes('rm ') || command.includes('unlink')) &&\n (command.includes('/etc/') || command.includes('/root/') || command.includes('/var/log/'))) {\n return {\n allowed: false,\n reason: '检测到删除关键系统目录内容',\n riskLevel: 'critical',\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n\n return null;\n}\n\nfunction extractRemoteHost(command: string): string | null {\n const m = command.match(/(?:ssh|scp|rsync)\\s+(?:-[\\w]+\\s+)*(\\S+@\\S+|\\b(?!-)[\\w.-]+\\b)/);\n return m ? m[1] : null;\n}\n\nfunction isLocalHost(host: string): boolean {\n const localNames = ['localhost', '127.0.0.1', '::1', process.env.HOSTNAME || '', '0.0.0.0'];\n return localNames.includes(host.replace(/.*@/, ''));\n}\n","import { readFileSync, readdirSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Skill files are in ../../agent_moss/skills/ (shared with Python version)\nconst SKILLS_DIR = resolve(__dirname, '../../agent_moss/skills');\n\n// Skill keyword map (synced with Python skill_engine.py SKILL_KEYWORD_MAP)\nconst SKILL_KEYWORD_MAP: Record<string, string[]> = {\n 'file_access_guard': ['file', '文件', 'path', '路径', 'read', 'write', 'cat', 'open', 'access', '访问', '读写', 'copy', 'cp', 'mv', 'move'],\n 'script_execution_guard': ['command', 'shell', 'bash', 'exec', 'execute', '执行', '命令', 'script', '脚本', 'run', '运行', 'subprocess', 'system', 'eval', 'compile', '安装', 'install', 'pip', 'npm'],\n 'data_exfiltration_guard': ['upload', '上传', 'send', '发送', 'transfer', '传输', 'export', '导出', 'download', '下载', 'post', 'http', 'request', 'fetch', 'curl', 'wget', '外传', '泄露', 'exfil', 'network', '网络'],\n 'browser_web_access_guard': ['browser', '浏览器', 'web', '网页', 'url', 'navigate', '浏览', 'scrape', 'crawl', '爬取', 'click', 'screenshot'],\n 'email_operation_guard': ['email', '邮件', 'mail', 'smtp', 'send_email', '发送邮件', 'inbox', '收件箱', '附件', 'attachment'],\n 'general_tool_risk_guard': ['tool', '工具', 'api', 'invoke', '调用', 'function', '函数'],\n 'lateral_movement_guard': ['ssh', 'scp', 'ftp', 'sftp', 'rdp', 'vnc', 'telnet', '内网', '横向', 'tunnel', '代理', 'proxy', 'port', '端口', 'scan', '扫描', 'ping', 'traceroute', 'nslookup'],\n 'persistence_backdoor_guard': ['cron', 'crontab', '定时', 'scheduled', 'startup', '启动项', 'service', '服务', 'daemon', '守护', 'registry', '注册表', 'backdoor', '后门', 'persist', '持久化', 'authorized_keys', 'bashrc', 'zshrc', 'profile', '.rc', 'shell config', 'shell 配置'],\n 'resource_exhaustion_guard': ['fork', 'bomb', '炸弹', 'memory', '内存', 'disk', '磁盘', 'cpu', 'process', '进程', 'dd', 'while true', '无限循环', '耗尽', 'exhaust', '资源'],\n 'skill_installation_guard': ['skill', 'plugin', '插件', 'extension', '扩展', 'install skill', '安装插件', '安装技能', 'marketplace', '商店'],\n 'supply_chain_guard': ['dependency', '依赖', 'package', '包', 'npm install', 'pip install', 'requirements', 'import', 'library', '库', 'registry', '仓库', 'supply', '供应链', 'typosquatting'],\n 'intent_deviation_guard': ['rm', 'del', 'delete', 'remove', '删除', 'format', '格式化', 'drop', 'truncate', '清空', 'wipe', '擦除', '重置', 'reset', 'sudo', 'root', 'admin', '管理员', 'privilege', '提权'],\n};\n\nlet cachedSkills: Record<string, string> | null = null;\n\nfunction loadAllSkills(): Record<string, string> {\n if (cachedSkills) return cachedSkills;\n cachedSkills = {};\n\n if (!existsSync(SKILLS_DIR)) {\n console.warn('[AgentMoss] Skills directory not found:', SKILLS_DIR);\n return cachedSkills;\n }\n\n const files = readdirSync(SKILLS_DIR).filter(f => f.endsWith('.md'));\n for (const f of files) {\n const name = f.replace('.md', '');\n cachedSkills[name] = readFileSync(resolve(SKILLS_DIR, f), 'utf-8');\n }\n\n console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills`);\n return cachedSkills;\n}\n\nexport interface SkillMatch {\n skillName: string;\n relevance: number; // 0-1\n skillContent: string;\n}\n\n/**\n * Match skills by keyword relevance (mirrors Python SkillEngine.match_skills).\n * Returns top-3 most relevant skills, or fallback to general_tool_risk_guard.\n */\nexport function matchSkills(\n actionType: string,\n actionDetail: string,\n reason: string,\n maxSkills: number = 3\n): SkillMatch[] {\n const skills = loadAllSkills();\n const combined = `${actionType} ${actionDetail} ${reason}`.toLowerCase();\n const actionDetailLower = actionDetail.toLowerCase();\n const actionTypeLower = actionType.toLowerCase();\n const reasonLower = reason.toLowerCase();\n\n const scores: Record<string, number> = {};\n for (const [skillName, keywords] of Object.entries(SKILL_KEYWORD_MAP)) {\n let score = 0;\n for (const kw of keywords) {\n if (combined.includes(kw)) {\n if (kw === actionTypeLower) score += 2.0;\n else if (actionDetailLower.includes(kw)) score += 1.5;\n else if (reasonLower.includes(kw)) score += 1.0;\n else score += 0.5;\n }\n }\n if (score > 0) scores[skillName] = score;\n }\n\n const sorted = Object.entries(scores).sort((a, b) => b[1] - a[1]);\n const top = sorted.slice(0, maxSkills);\n const maxScore = top[0]?.[1] || 1;\n\n const results: SkillMatch[] = [];\n for (const [name, score] of top) {\n const content = skills[name];\n if (content) {\n results.push({\n skillName: name,\n relevance: Math.min(score / maxScore, 1.0),\n skillContent: content,\n });\n }\n }\n\n // Fallback to general_tool_risk_guard if no match\n if (results.length === 0) {\n const fallback = skills['general_tool_risk_guard'];\n if (fallback) {\n results.push({ skillName: 'general_tool_risk_guard', relevance: 0.3, skillContent: fallback });\n }\n }\n\n return results;\n}\n\n/**\n * Format matched skills for LLM prompt (mirrors Python SkillEngine.format_skills_for_prompt).\n */\nexport function formatSkillsForPrompt(skills: SkillMatch[]): string {\n if (skills.length === 0) return '(未匹配到特定安全检测规则)';\n return skills.map(s =>\n `### 安全检测规则: ${s.skillName} (相关度: ${Math.round(s.relevance * 100)}%)\\n\\n${s.skillContent}`\n ).join('\\n\\n---\\n\\n');\n}\n\n/** Legacy: load all skills as flat string array */\nexport function loadSkills(): string[] {\n const skills = loadAllSkills();\n return Object.entries(skills).map(([name, content]) => `### ${name}\\n${content}`);\n}\n\n/** Reload skills (for hot-reload) */\nexport function reloadSkills(): void {\n cachedSkills = null;\n loadAllSkills();\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst TEMPLATES_DIR = resolve(__dirname, '../../agent_moss/templates');\n\nconst TEMPLATE_FILES = ['prompt1_template.txt', 'prompt2_template.txt', 'security_judge_template.txt'];\n\nlet cachedTemplates: Record<string, string> | null = null;\n\nexport function loadTemplates(): Record<string, string> {\n if (cachedTemplates) return cachedTemplates;\n\n cachedTemplates = {};\n\n if (!existsSync(TEMPLATES_DIR)) {\n console.warn('[AgentMoss] Templates directory not found:', TEMPLATES_DIR);\n return cachedTemplates;\n }\n\n for (const file of TEMPLATE_FILES) {\n const filePath = resolve(TEMPLATES_DIR, file);\n if (existsSync(filePath)) {\n const key = file.replace('.txt', '').replace('_template', '');\n cachedTemplates[key] = readFileSync(filePath, 'utf-8');\n }\n }\n\n console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates`);\n return cachedTemplates;\n}\n\nexport function reloadTemplates(): void {\n cachedTemplates = null;\n loadTemplates();\n}\n","import { readFileSync } from 'fs';\nimport { resolve, join } from 'path';\n\n/**\n * Script content pre-scanning — detects suspicious patterns in bash scripts.\n * When a script execution is detected, reads up to 500 lines and scans for\n * high-risk patterns (network exfil, reverse shells, base64 obfuscation,\n * sensitive file access, persistence backdoors).\n */\n\n// High-risk detection patterns\nconst SUSPICIOUS_PATTERNS: { name: string; pattern: RegExp }[] = [\n // Network exfiltration (curl/wget POST in scripts is almost never legitimate)\n { name: 'curl POST', pattern: /curl\\s+(.*\\s)?-X\\s+POST/i },\n { name: 'curl --data', pattern: /curl\\s+(.*\\s)?--data/i },\n { name: 'curl -d', pattern: /curl\\s+(.*\\s)?-d\\s/i },\n { name: 'wget --post-data', pattern: /wget\\s+(.*\\s)?--post-data/i },\n { name: 'wget --post-file', pattern: /wget\\s+(.*\\s)?--post-file/i },\n // Reverse shell\n { name: 'nc -e', pattern: /\\bnc\\s+.*-e\\b/ },\n { name: 'ncat -e', pattern: /\\bncat\\s+.*-e\\b/ },\n { name: '/dev/tcp', pattern: /\\/dev\\/tcp\\// },\n { name: '/dev/udp', pattern: /\\/dev\\/udp\\// },\n // Base64 obfuscation\n { name: '$(base64', pattern: /\\$\\(\\s*base64/ },\n { name: '`base64', pattern: /`\\s*base64/ },\n { name: 'base64 decode pipe', pattern: /base64\\s+(-d|--decode)\\s*\\|/ },\n // Sensitive file access\n { name: '/etc/shadow', pattern: /\\/etc\\/shadow/ },\n { name: 'id_rsa', pattern: /\\bid_rsa\\b/ },\n { name: 'id_ed25519', pattern: /\\bid_ed25519\\b/ },\n // Persistence backdoor\n { name: 'crontab install', pattern: /crontab\\s+-/ },\n { name: 'authorized_keys', pattern: /authorized_keys/ },\n { name: 'ssh no host key check', pattern: /ssh\\s+.*StrictHostKeyChecking\\s*=\\s*no/ },\n];\n\n// Script execution patterns\nconst SCRIPT_EXEC_PATTERNS = [\n /bash\\s+(\\S+\\.sh)/,\n /sh\\s+(\\S+\\.sh)/,\n /\\.\\/(\\S+\\.sh)/,\n /source\\s+(\\S+\\.sh)/,\n /\\.\\s+(\\S+\\.sh)/,\n /zsh\\s+(\\S+\\.sh)/,\n];\n\n// Keyword combination risk rules\nconst KEYWORD_COMBINATION_RISKS: { group1: Set<string>; group2: Set<string>; level: string; reason: string }[] = [\n {\n group1: new Set(['curl POST', 'curl --data', 'curl -d', 'wget --post-data', 'wget --post-file']),\n group2: new Set(['$(base64', '`base64', 'base64 decode pipe']),\n level: 'critical',\n reason: '检测到网络数据发送 + Base64编码组合,构成 Critical 级别数据外传风险。攻击者可能将敏感数据编码后外传。',\n },\n {\n group1: new Set(['curl POST', 'curl --data', 'curl -d', 'wget --post-data', 'wget --post-file']),\n group2: new Set(['/etc/shadow', 'id_rsa', 'id_ed25519']),\n level: 'critical',\n reason: '检测到网络数据发送 + 敏感文件访问组合,构成 Critical 级别凭证外传风险。',\n },\n {\n group1: new Set(['nc -e', 'ncat -e', '/dev/tcp', '/dev/udp']),\n group2: new Set(),\n level: 'high',\n reason: '检测到反弹 Shell 特征,攻击者可能建立远程控制通道。',\n },\n {\n group1: new Set(['crontab install', 'authorized_keys', 'ssh no host key check']),\n group2: new Set(),\n level: 'high',\n reason: '检测到持久化后门特征,攻击者可能在系统中植入后门。',\n },\n];\n\nconst SINGLE_KEYWORD_RISKS: Record<string, { level: string; reason: string }> = {\n 'curl POST': { level: 'high', reason: '检测到 curl POST 请求,可能向外部服务器发送数据。' },\n 'curl --data': { level: 'high', reason: '检测到 curl --data 参数,可能向外部服务器发送数据。' },\n 'curl -d': { level: 'high', reason: '检测到 curl -d 参数,可能向外部服务器发送数据。' },\n 'wget --post-data': { level: 'high', reason: '检测到 wget POST 请求,可能向外部服务器发送数据。' },\n 'wget --post-file': { level: 'high', reason: '检测到 wget 文件上传,可能向外部服务器发送文件。' },\n 'nc -e': { level: 'critical', reason: '检测到 nc -e 反弹 Shell 特征。' },\n 'ncat -e': { level: 'critical', reason: '检测到 ncat -e 反弹 Shell 特征。' },\n '/dev/tcp': { level: 'critical', reason: '检测到 /dev/tcp 反弹 Shell 特征。' },\n '/dev/udp': { level: 'critical', reason: '检测到 /dev/udp 反弹 Shell 特征。' },\n '$(base64': { level: 'high', reason: '检测到 Base64 编码执行,可能是混淆逃逸。' },\n '`base64': { level: 'high', reason: '检测到 Base64 编码执行,可能是混淆逃逸。' },\n 'base64 decode pipe': { level: 'high', reason: '检测到 Base64 解码后管道执行,可能是混淆逃逸。' },\n '/etc/shadow': { level: 'critical', reason: '检测到访问系统密码文件。' },\n 'id_rsa': { level: 'critical', reason: '检测到访问 SSH 私钥。' },\n 'id_ed25519': { level: 'critical', reason: '检测到访问 SSH 私钥。' },\n 'crontab install': { level: 'high', reason: '检测到修改定时任务,可能是持久化后门。' },\n 'authorized_keys': { level: 'high', reason: '检测到修改 SSH 授权密钥,可能是持久化后门。' },\n 'ssh no host key check': { level: 'high', reason: '检测到 SSH 跳过主机密钥验证,可能是横向移动。' },\n};\n\nconst LEVEL_ORDER: Record<string, number> = { low: 1, medium: 2, high: 3, critical: 4 };\n\nexport interface ScriptAnalysisResult {\n scriptPath: string;\n scriptContent: string;\n matchedKeywords: string[];\n lineCount: number;\n isSuspicious: boolean;\n error: string;\n riskLevel: string;\n riskReason: string;\n}\n\nfunction emptyResult(): ScriptAnalysisResult {\n return { scriptPath: '', scriptContent: '', matchedKeywords: [], lineCount: 0, isSuspicious: false, error: '', riskLevel: '', riskReason: '' };\n}\n\nfunction extractScriptPath(command: string): string | null {\n for (const pattern of SCRIPT_EXEC_PATTERNS) {\n const m = command.match(pattern);\n if (m) return m[1];\n }\n return null;\n}\n\nfunction scanScriptForKeywords(content: string): string[] {\n const matched: string[] = [];\n for (const { name, pattern } of SUSPICIOUS_PATTERNS) {\n if (pattern.test(content)) matched.push(name);\n }\n return matched;\n}\n\nfunction assessKeywordCombinationRisk(matchedKeywords: string[], scriptContent: string): { level: string; reason: string } {\n if (matchedKeywords.length === 0) return { level: '', reason: '' };\n\n const keywordSet = new Set(matchedKeywords);\n\n // Check combination rules\n for (const rule of KEYWORD_COMBINATION_RISKS) {\n const hitGroup1 = [...rule.group1].some(k => keywordSet.has(k));\n const hitGroup2 = rule.group2.size === 0 ? true : [...rule.group2].some(k => keywordSet.has(k));\n if (hitGroup1 && hitGroup2) return { level: rule.level, reason: rule.reason };\n }\n\n // Extra: network post + env variable collection\n const networkPostKeywords = new Set(['curl POST', 'curl --data', 'curl -d', 'wget --post-data', 'wget --post-file']);\n const hasNetworkPost = [...networkPostKeywords].some(k => keywordSet.has(k));\n if (hasNetworkPost) {\n const envPatterns = ['$env', '$(env)', '$USER', '$(hostname)', '$(pwd)', '$HOME'];\n const contentLower = scriptContent.toLowerCase();\n for (const p of envPatterns) {\n if (contentLower.includes(p.toLowerCase())) {\n return {\n level: 'critical',\n reason: '检测到网络数据发送 + 系统环境变量收集组合,构成 Critical 级别数据外传风险。脚本可能将用户环境变量(可能包含 API Key、密钥等敏感信息)发送到远程服务器。',\n };\n }\n }\n }\n\n // Single keyword fallback\n let bestLevel = '';\n let bestReason = '';\n for (const kw of matchedKeywords) {\n const risk = SINGLE_KEYWORD_RISKS[kw];\n if (risk && (LEVEL_ORDER[risk.level] || 0) > (LEVEL_ORDER[bestLevel] || 0)) {\n bestLevel = risk.level;\n bestReason = risk.reason;\n }\n }\n\n return { level: bestLevel, reason: bestReason };\n}\n\nfunction readScriptContent(scriptPath: string, maxLines: number = 500): { content: string; lineCount: number; error: string } {\n try {\n const expandedPath = scriptPath.startsWith('~')\n ? join(process.env.HOME || '/home/user', scriptPath.slice(2))\n : resolve(scriptPath);\n\n const raw = readFileSync(expandedPath, 'utf-8');\n const lines = raw.split('\\n').slice(0, maxLines);\n return { content: lines.join('\\n'), lineCount: lines.length, error: '' };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n return { content: '', lineCount: 0, error: `读取脚本失败: ${msg}` };\n }\n}\n\nexport function analyzeScriptContent(actionType: string, actionDetail: string, maxLines: number = 500): ScriptAnalysisResult {\n if (actionType.toLowerCase() !== 'bash') return emptyResult();\n\n const scriptPath = extractScriptPath(actionDetail);\n if (!scriptPath) return emptyResult();\n\n const { content, lineCount, error } = readScriptContent(scriptPath, maxLines);\n if (error) return { ...emptyResult(), scriptPath, error };\n\n const matchedKeywords = scanScriptForKeywords(content);\n const isSuspicious = matchedKeywords.length > 0;\n\n let riskLevel = '';\n let riskReason = '';\n if (isSuspicious) {\n const risk = assessKeywordCombinationRisk(matchedKeywords, content);\n riskLevel = risk.level;\n riskReason = risk.reason;\n }\n\n return { scriptPath, scriptContent: content, matchedKeywords, lineCount, isSuspicious, error: '', riskLevel, riskReason };\n}\n\nexport function formatScriptAnalysisForPrompt(result: ScriptAnalysisResult): string {\n if (!result.scriptPath) return '';\n if (result.error) return `脚本内容分析失败: ${result.error}`;\n if (!result.isSuspicious) return '';\n\n const keywordsStr = result.matchedKeywords.join(', ');\n let riskHint = '';\n if (result.riskLevel && result.riskReason) {\n riskHint = `\\n\\n风险评估: ${result.riskLevel.toUpperCase()} 级别\\n风险原因: ${result.riskReason}\\n建议: 此脚本应被拒绝(Deny),除非有明确的业务需求且已确认目标服务器可信。`;\n }\n\n return `检测到脚本执行,且脚本内容包含可疑关键词:\\n 脚本路径: ${result.scriptPath}\\n 可疑关键词: ${keywordsStr}\\n 脚本行数: ${result.lineCount}${riskHint}\\n\\n### 脚本内容 ###\\n\\`\\`\\`\\n${result.scriptContent}\\n\\`\\`\\`\\n`;\n}\n","import { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getLLMConfig, isLLMAvailable, detectProvider, getProviderHeaders } from '../config';\nimport { matchSkills, formatSkillsForPrompt } from './skill-loader';\nimport { loadTemplates } from './template-loader';\nimport { analyzeScriptContent, formatScriptAnalysisForPrompt } from './script-analyzer';\nimport OpenAI from 'openai';\n\n// LRU cache to avoid duplicate LLM calls for identical commands\nconst llmCache = new Map<string, SecurityJudgment>();\nconst LLM_CACHE_MAX = 200;\n\ninterface PreviousResults {\n heuristic: SecurityJudgment | null;\n logic: SecurityJudgment | null;\n}\n\n/**\n * Layer 3: LLM + Skill semantic analysis.\n * Only called when layers 1 and 2 both pass.\n * Loads skills from the shared skills directory and uses LLM for deep analysis.\n */\nexport async function runLLMAnalysis(\n input: AnalysisInput,\n previous: PreviousResults\n): Promise<SecurityJudgment> {\n if (!isLLMAvailable()) {\n console.log('[AgentMoss] LLM not configured, skipping deep analysis');\n return {\n allowed: true,\n reason: 'LLM 未配置,跳过深层分析',\n riskLevel: 'low',\n riskType: '',\n confidence: 50,\n source: 'llm',\n violatedLayers: [],\n };\n }\n\n const config = getLLMConfig();\n\n // Check LRU cache (use raw command as key, strip OpenDesk metadata)\n const rawDetail = input.aNext.actionDetail.replace(/^terminal-\\w+:\\s*command=([^,]+).*/, '$1').trim();\n const cacheKey = `${input.aNext.actionType}:${rawDetail || input.aNext.actionDetail}`;\n const cached = llmCache.get(cacheKey);\n if (cached) {\n console.log('[AgentMoss] LLM cache hit');\n return cached;\n }\n\n // Load skills and templates (cached)\n const matchedSkills = matchSkills(input.aNext.actionType, input.aNext.actionDetail, input.reason);\n const templates = loadTemplates();\n\n // Build the analysis prompt\n const scriptAnalysis = analyzeScriptContent(input.aNext.actionType, input.aNext.actionDetail);\n const prompt = buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis);\n\n // Call LLM\n const result = await analyzeWithLLM(prompt, config);\n\n // Cache result\n if (llmCache.size >= LLM_CACHE_MAX) {\n const firstKey = llmCache.keys().next().value;\n if (firstKey) llmCache.delete(firstKey);\n }\n llmCache.set(cacheKey, result);\n\n return result;\n}\n\nfunction buildPrompt(\n input: AnalysisInput,\n previous: PreviousResults,\n matchedSkills: import('./skill-loader').SkillMatch[],\n templates: Record<string, string>,\n scriptAnalysis?: import('./script-analyzer').ScriptAnalysisResult\n): string {\n const skillsText = formatSkillsForPrompt(matchedSkills);\n const historyStr = input.actionHistory\n .map((h, i) => `${i + 1}. ${h.actionType}: ${h.actionDetail}`)\n .join('\\n') || '(无历史操作)';\n\n const templateName = previous.heuristic || previous.logic ? 'prompt2' : 'prompt1';\n const baseTemplate = templates[templateName] || templates['prompt1'] || '';\n\n const scriptAnalysisText = scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : '';\n\n // Format L1/L2 hints (mirrors Python LLMAnalyzer._format_hints)\n const hintsText = formatHints(previous);\n\n return `${baseTemplate}\n\n## 当前操作上下文\n- 会话 ID: ${input.sessionId}\n- 用户任务: ${input.promptSession || '未指定'}\n- 操作系统: ${input.osType}\n- 工作目录: ${input.cwd || '/'}\n- 操作原因: ${input.reason || '未说明'}\n- 历史操作序列:\n${historyStr}\n\n- 即将执行的操作:\n 类型: ${input.aNext.actionType}\n 详情: ${input.aNext.actionDetail}\n\n## 可用安全 Skill\n${skillsText}\n\n## 前置检测结果\n${hintsText}\n${scriptAnalysisText ? `\\n## 脚本内容分析\\n${scriptAnalysisText}` : ''}\n\n请根据以上信息,对即将执行的操作进行安全判断。你必须输出严格的 JSON 格式,\n不要包含任何其他文字、注释或 markdown 标记。\n\n输出格式:\n{\"allowed\": true/false, \"reason\": \"判断理由\", \"riskLevel\": \"low|medium|high|critical\", \"riskType\": \"风险类型\", \"confidence\": 0-100}`;\n}\n\nfunction formatHints(previous: PreviousResults): string {\n const hints: string[] = [];\n\n if (previous.heuristic) {\n hints.push(\n `启发式检测发现风险 [风险等级: ${previous.heuristic.riskLevel}]:\\n` +\n ` 类型: ${previous.heuristic.riskType}\\n` +\n ` 原因: ${previous.heuristic.reason}`\n );\n }\n\n if (previous.logic) {\n hints.push(\n `逻辑规则检测发现风险 [风险等级: ${previous.logic.riskLevel}]:\\n` +\n ` 类型: ${previous.logic.riskType}\\n` +\n ` 原因: ${previous.logic.reason}`\n );\n }\n\n return hints.length > 0 ? hints.join('\\n\\n') : '启发式检测和逻辑规则检测均未发现风险。';\n}\n\nasync function analyzeWithLLM(prompt: string, config: ReturnType<typeof getLLMConfig>): Promise<SecurityJudgment> {\n console.log(`[AgentMoss] LLM analyzing with model: ${config.model}, url: ${config.baseUrl}`);\n\n const provider = detectProvider(config.baseUrl, config.provider);\n const extraHeaders = getProviderHeaders(provider);\n if (Object.keys(extraHeaders).length > 0) {\n console.log(`[AgentMoss] Provider detected: ${provider}, injecting headers: ${Object.keys(extraHeaders).join(', ')}`);\n }\n\n const client = new OpenAI({\n baseURL: config.baseUrl,\n apiKey: config.apiKey,\n timeout: (config.timeout || 300) * 1000,\n defaultHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined,\n });\n\n const maxRetries = parseInt(process.env.AGENT_MOSS_LLM_RETRIES || '2', 10); // default 2 retries = 3 attempts total\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await client.chat.completions.create({\n model: config.model,\n temperature: config.temperature || 0.1,\n max_tokens: config.maxTokens || 1024,\n messages: [\n { role: 'system', content: '你是一个 AI Agent 安全审计专家。你的任务是分析即将执行的命令是否安全。你必须只输出纯 JSON,不要包含任何 markdown 标记、代码块或其他文字。' },\n { role: 'user', content: prompt },\n ],\n });\n\n const content = response.choices[0]?.message?.content || '{}';\n console.log(`[AgentMoss] LLM raw response (attempt ${attempt + 1}/${maxRetries + 1}): ${content.substring(0, 300)}`);\n\n let jsonStr = content.trim();\n if (jsonStr.startsWith('```')) {\n jsonStr = jsonStr.replace(/^```[\\w]*\\n?/, '').replace(/\\n?```$/, '');\n }\n const parsed = JSON.parse(jsonStr);\n\n return {\n allowed: parsed.allowed !== false,\n reason: parsed.reason || 'LLM 分析完成',\n riskLevel: ['low', 'medium', 'high', 'critical'].includes(parsed.riskLevel) ? parsed.riskLevel : 'low',\n riskType: parsed.riskType || '',\n confidence: typeof parsed.confidence === 'number' ? Math.min(100, Math.max(0, parsed.confidence)) : 70,\n source: 'llm',\n violatedLayers: ['3'],\n };\n } catch (err) {\n if (attempt < maxRetries) {\n console.error(`[AgentMoss] LLM call failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in 1s:`, (err as Error).message);\n await new Promise(resolve => setTimeout(resolve, 1000));\n } else {\n console.error('[AgentMoss] LLM call failed after all retries:', (err as Error).message);\n // Fail-closed: deny on LLM failure (matches Python behavior)\n return {\n allowed: false,\n reason: `LLM 分析失败,因无法完成深度语义分析,按 fail-closed 原则拒绝 (${maxRetries + 1} 次尝试): ${(err as Error).message}`,\n riskLevel: 'medium',\n riskType: '',\n confidence: 60,\n source: 'llm_failure',\n violatedLayers: ['3'],\n };\n }\n }\n }\n\n // Should never reach here, but TypeScript needs a return\n return {\n allowed: false,\n reason: 'LLM 分析异常',\n riskLevel: 'medium',\n riskType: '',\n confidence: 60,\n source: 'llm_failure',\n violatedLayers: ['3'],\n };\n}\n","import { SecurityJudgment } from './types';\nimport { runHeuristicCheck } from './heuristic';\nimport { runLogicCheck } from './logic-rules';\nimport { runLLMAnalysis } from './llm-analyzer';\nimport { isHeuristicEnabled, isLogicRulesEnabled, isLLMAvailable } from '../config';\n\nexport interface AnalysisInput {\n sessionId: string;\n promptSession: string;\n actionHistory: { actionType: string; actionDetail: string }[];\n aNext: { actionType: string; actionDetail: string };\n reason: string;\n osType: string;\n cwd: string;\n}\n\n// ========== 快速放行白名单 ==========\n\n/** 完全安全工具:跳过 Layer 2 + Layer 3 */\nconst FULLY_SAFE_TOOLS = new Set([\n 'ask_user_question', 'glob', 'list_dir', 'ls', 'count_text_length',\n 'filemgr-globfiles',\n]);\n\n/** 安全但可能访问敏感路径:跳过 Layer 3,保留 Layer 2 */\nconst READONLY_SENSITIVE_TOOLS = new Set([\n 'read', 'file_read', 'read_file', 'head', 'tail', 'grep',\n 'filemgr-readfile', 'filemgr-grepfiles',\n]);\n\n/** 完全安全 bash 子命令正则 */\nconst FULLY_SAFE_BASH_PATTERNS: RegExp[] = [\n /^ls(?:\\s|$)/i, /^dir(?:\\s|$)/i,\n /^pwd(?:\\s|$)/i, /^which\\s+/i, /^whereis\\s+/i, /^realpath\\s+/i,\n /^basename\\s+/i, /^dirname\\s+/i,\n /^file\\s+/i, /^stat\\s+/i, /^du(?:\\s|$)/i,\n /^echo\\s+/i, /^printf\\s+/i,\n /^type\\s+/i, /^command\\s+/i,\n];\n\n/** 安全但可能访问敏感路径的 bash 子命令正则 */\nconst READONLY_SENSITIVE_BASH_PATTERNS: RegExp[] = [\n /^cat\\s+/i, /^head(?:\\s|$)/i, /^tail(?:\\s|$)/i,\n /^less(?:\\s|$)/i, /^more(?:\\s|$)/i, /^wc(?:\\s|$)/i,\n /^grep(?:\\s|$)/i, /^find\\s+/i, /^ag(?:\\s|$)/i, /^rg(?:\\s|$)/i,\n /^awk\\s+/i, /^sed\\s+/i, /^cut\\s+/i, /^sort(?:\\s|$)/i, /^uniq(?:\\s|$)/i,\n];\n\n/** 提取管道和链式命令的第一段 */\nfunction extractFirstCommand(command: string): string {\n let main = command.split('|')[0].trim();\n for (const sep of ['&&', '||']) {\n const idx = main.indexOf(sep);\n if (idx !== -1) {\n main = main.substring(0, idx).trim();\n break;\n }\n }\n return main;\n}\n\n/** 从 OpenDesk 格式中提取实际命令 */\nfunction extractRawCommand(detail: string): string {\n const m = detail.match(/command=([^,]+)/);\n return m ? m[1].trim() : detail;\n}\n\nfunction matchesAny(cmd: string, patterns: RegExp[]): boolean {\n return patterns.some(p => p.test(cmd));\n}\n\n// ========== 三层防御协调器 ==========\n\n/**\n * Three-layer defense coordinator.\n * Layer 1 → fast-pass check → Layer 2 → Layer 3.\n * Fast-pass: whitelisted safe tools/commands skip L2+L3 or L3 only.\n */\nexport async function runAnalysis(input: AnalysisInput): Promise<SecurityJudgment> {\n // Layer 1: Heuristic static detection (fast)\n const heuristicResult = isHeuristicEnabled() ? runHeuristicCheck(input) : null;\n if (heuristicResult && !heuristicResult.allowed) {\n return heuristicResult;\n }\n\n // ===== Fast-pass check =====\n const actionType = input.aNext.actionType.toLowerCase();\n const rawDetail = extractRawCommand(input.aNext.actionDetail);\n const lowerDetail = rawDetail.toLowerCase();\n\n // Fully safe tools: skip L2 + L3\n if (FULLY_SAFE_TOOLS.has(actionType)) {\n return {\n allowed: true,\n reason: `完全安全工具,跳过深度分析: ${actionType}`,\n riskLevel: (heuristicResult?.riskLevel || 'low') as SecurityJudgment['riskLevel'],\n riskType: '',\n confidence: 95,\n source: 'whitelist_bypass',\n violatedLayers: [],\n };\n }\n\n // Readonly sensitive tools: skip L3, continue to L2\n let skipLLM = READONLY_SENSITIVE_TOOLS.has(actionType);\n\n // Bash sub-command checks\n if (actionType === 'bash' || actionType === 'executebash' || actionType === 'terminal-executebash') {\n const firstCmd = extractFirstCommand(lowerDetail);\n if (matchesAny(firstCmd, FULLY_SAFE_BASH_PATTERNS)) {\n return {\n allowed: true,\n reason: `安全的只读 bash 命令: ${firstCmd}`,\n riskLevel: 'low',\n riskType: '',\n confidence: 95,\n source: 'whitelist_bypass',\n violatedLayers: [],\n };\n }\n if (matchesAny(firstCmd, READONLY_SENSITIVE_BASH_PATTERNS)) {\n skipLLM = true;\n }\n }\n\n // Layer 2: Logic rule detection (fast)\n const logicResult = isLogicRulesEnabled() ? runLogicCheck(input) : null;\n if (logicResult && !logicResult.allowed) {\n return logicResult;\n }\n\n // Layer 3: LLM analysis (skipped for readonly sensitive tools/commands)\n if (skipLLM || !isLLMAvailable()) {\n return {\n allowed: true,\n reason: '只读操作且无逻辑规则违规,跳过 LLM 分析',\n riskLevel: (logicResult?.riskLevel || 'low') as SecurityJudgment['riskLevel'],\n riskType: '',\n confidence: 85,\n source: 'heuristic_and_logic_only',\n violatedLayers: [],\n };\n }\n\n const llmResult = await runLLMAnalysis(input, {\n heuristic: heuristicResult,\n logic: logicResult,\n });\n\n return llmResult;\n}\n","#!/usr/bin/env node\n/**\n * AgentMoss CLI — TypeScript version.\n * Supports: init | analyze | server\n */\n\nimport { parseArgs } from 'util';\nimport { createApp } from './server';\n\nfunction printHelp(): void {\n console.log(`AgentMoss security analysis engine (TypeScript v0.2.0)\n\nCommands:\n init Generate input.json template\n analyze <input> Run security analysis on input JSON\n server Start HTTP API server\n\nServer options:\n --host <host> Listen host (default: 127.0.0.1)\n --port <port> Listen port (default: 9090)\n`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (!command || command === '--help' || command === '-h') {\n printHelp();\n process.exit(command ? 0 : 1);\n }\n\n switch (command) {\n case 'init': {\n const output = args[2] || 'input.json';\n const fs = await import('fs');\n const template = {\n session_id: 'my-session-001',\n prompt_session: 'Read /var/log/app.log and analyze errors',\n action_history: [],\n a_next: { action_type: 'bash', action_detail: 'cat /var/log/app.log' },\n reason: 'Need to read log file for error analysis',\n os_type: '',\n cwd: '/home/user/project',\n };\n fs.writeFileSync(output, JSON.stringify(template, null, 2), 'utf-8');\n console.log(`Template written to ${output}`);\n break;\n }\n\n case 'analyze': {\n if (!args[1]) {\n console.error('Usage: agent-moss analyze <input.json>');\n process.exit(1);\n }\n const fs = await import('fs');\n const path = await import('path');\n const { runAnalysis } = await import('./engine/coordinator');\n const filePath = path.resolve(args[1]);\n const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n const result = await runAnalysis({\n sessionId: data.session_id || 'unknown',\n promptSession: data.prompt_session || '',\n actionHistory: (data.action_history || []).map((h: any) => ({\n actionType: h.action_type || h.name || '',\n actionDetail: h.action_detail || '',\n })),\n aNext: {\n actionType: data.a_next?.action_type || '',\n actionDetail: data.a_next?.action_detail || '',\n },\n reason: data.reason || '',\n osType: data.os_type || (process.platform === 'win32' ? 'windows' : 'linux'),\n cwd: data.cwd || process.cwd(),\n });\n console.log(JSON.stringify(result, null, 2));\n process.exit(result.allowed ? 0 : 1);\n break;\n }\n\n case 'server': {\n let host = '127.0.0.1';\n let port = 9090;\n\n for (let i = 1; i < args.length; i++) {\n if (args[i] === '--host' && args[i + 1]) host = args[++i];\n else if (args[i] === '--port' && args[i + 1]) port = parseInt(args[++i], 10);\n }\n\n // Import @hono/node-server dynamically\n const { serve } = await import('@hono/node-server');\n const app = createApp();\n console.log(`AgentMoss HTTP server on ${host}:${port}`);\n serve({ fetch: app.fetch, hostname: host, port }, (info) => {\n console.log(`Listening on http://${host}:${port}`);\n });\n break;\n }\n\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n","import { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { logger } from 'hono/logger';\nimport { analyzeRoute, healthRoute } from './routes';\n\nexport function createApp(): Hono {\n const app = new Hono();\n\n // Middleware\n app.use('*', cors({ origin: '*', allowMethods: ['GET', 'POST', 'OPTIONS'], allowHeaders: ['*'] }));\n app.use('*', logger());\n\n // Routes\n app.get('/api/v1/health', healthRoute);\n app.post('/api/v1/analyze', analyzeRoute);\n\n return app;\n}\n\nexport function startServer(host = '127.0.0.1', port = 9090): { serve: () => void } {\n const app = createApp();\n return {\n serve: () => {\n console.log(`AgentMoss HTTP server on ${host}:${port}`);\n // In utilityProcess mode, use Bun.serve or Node adapter\n // Use @hono/node-server for Node.js environments\n const { serve: honoServe } = require('@hono/node-server');\n honoServe({ fetch: app.fetch, hostname: host, port });\n },\n };\n}\n","import type { Context } from 'hono';\nimport { AnalyzeRequestSchema, AnalyzeResponseSchema, HealthResponseSchema } from './models';\nimport { runAnalysis } from './engine/coordinator';\n\nexport async function healthRoute(c: Context) {\n return c.json(HealthResponseSchema.parse({}));\n}\n\nexport async function analyzeRoute(c: Context) {\n const t0 = performance.now();\n\n try {\n const body = await c.req.json();\n const req = AnalyzeRequestSchema.parse(body);\n\n // OS auto-detect\n let osType = req.os_type;\n if (!osType) {\n osType = process.platform === 'win32' ? 'windows' : 'linux';\n }\n\n const result = await runAnalysis({\n sessionId: req.session_id,\n promptSession: req.prompt_session,\n actionHistory: req.action_history.map(h => ({\n actionType: h.action_type,\n actionDetail: h.action_detail,\n })),\n aNext: {\n actionType: req.a_next.action_type,\n actionDetail: req.a_next.action_detail,\n },\n reason: req.reason,\n osType,\n cwd: req.cwd,\n });\n\n const durationMs = performance.now() - t0;\n\n return c.json(\n AnalyzeResponseSchema.parse({\n decision: result.allowed ? 'Allow' : 'Deny',\n reason: result.reason,\n risk_level: result.riskLevel,\n risk_type: result.riskType,\n violated_layers: result.violatedLayers,\n policy: '',\n violated_policy: '',\n confidence: result.confidence,\n analysis_duration_ms: Math.round(durationMs * 10) / 10,\n })\n );\n } catch (err) {\n console.error('[AgentMoss] Analysis error:', err);\n if (err instanceof SyntaxError) {\n return c.json({ error: 'Invalid JSON', detail: err.message }, 400);\n }\n if ((err as any)?.issues) {\n return c.json({ error: 'Validation error', detail: (err as any).issues }, 400);\n }\n return c.json({ error: 'Internal error', detail: String(err) }, 500);\n }\n}\n","import { z } from 'zod';\n\n/** Single action in history or next action */\nexport const ActionItemSchema = z.object({\n action_type: z.string().describe('Action type, e.g. bash, file_read, file_write'),\n action_detail: z.string().describe('Action detail / command content'),\n});\n\nexport const AnalyzeRequestSchema = z.object({\n session_id: z.string().describe('Session / agent unique identifier'),\n prompt_session: z.string().default('').describe('User original prompt'),\n action_history: z.array(ActionItemSchema).default([]).describe('Historical action sequence'),\n a_next: ActionItemSchema.describe('Next action to be executed'),\n reason: z.string().default('').describe('Reason for executing this action'),\n os_type: z.string().default('').describe(\"OS type: 'linux', 'windows', or empty for auto-detect\"),\n cwd: z.string().default('').describe('Current working directory'),\n metadata: z.record(z.unknown()).optional().describe('Extended metadata'),\n});\n\nexport const AnalyzeResponseSchema = z.object({\n decision: z.enum(['Allow', 'Deny']).describe('Allow or Deny'),\n reason: z.string().describe('Decision reason'),\n risk_level: z.enum(['low', 'medium', 'high', 'critical']).default('low'),\n risk_type: z.string().default(''),\n violated_layers: z.array(z.string()).default([]),\n policy: z.string().default(''),\n violated_policy: z.string().default(''),\n confidence: z.number().int().min(0).max(100).default(100),\n analysis_duration_ms: z.number().default(0),\n});\n\nexport const HealthResponseSchema = z.object({\n status: z.string().default('healthy'),\n version: z.string().default('0.2.0'),\n});\n\nexport type ActionItem = z.infer<typeof ActionItemSchema>;\nexport type AnalyzeRequest = z.infer<typeof AnalyzeRequestSchema>;\nexport type AnalyzeResponse = z.infer<typeof AnalyzeResponseSchema>;\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n"],"mappings":";;;;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACuBA,SAAS,kBAAgC;AACvC,MAAI;AACF,UAAM,MAAM,QAAQ,IAAI;AACxB,QAAI,CAAC,IAAK,QAAO,CAAC;AAClB,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO,CAAC;AACpC,WAAO,OAAO,OAAO,CAAC,MAAW,EAAE,WAAW,EAAE,MAAM;AAAA,EACxD,QAAQ;AAAE,WAAO,CAAC;AAAA,EAAG;AACvB;AAEO,SAAS,eAAoC;AAClD,SAAO;AACT;AAMO,SAAS,iBAAyC;AACvD,SAAO;AACT;AAGO,SAAS,iBAA0B;AACxC,MAAI,QAAQ,IAAI,2BAA2B,IAAK,QAAO;AACvD,SAAO,UAAU,OAAO,SAAS;AACnC;AAeO,SAAS,eAAe,SAAiB,eAAuB,IAAY;AACjF,MAAI,cAAc;AAChB,UAAM,OAAO,aAAa,YAAY;AACtC,QAAI,CAAC,UAAU,WAAW,EAAE,SAAS,IAAI,EAAG,QAAO;AACnD,QAAI,CAAC,UAAU,QAAQ,EAAE,SAAS,IAAI,EAAG,QAAO;AAChD,QAAI,CAAC,mBAAmB,qBAAqB,qBAAqB,EAAE,SAAS,IAAI,EAAG,QAAO;AAC3F,QAAI,CAAC,OAAO,QAAQ,QAAQ,UAAU,aAAa,SAAS,UAAU,UAAU,EAAE,SAAS,IAAI,EAAG,QAAO;AACzG,QAAI,CAAC,OAAO,UAAU,EAAE,SAAS,IAAI,EAAG,QAAO;AAC/C,QAAI,CAAC,WAAW,gBAAgB,EAAE,SAAS,IAAI,EAAG,QAAO;AACzD,QAAI,CAAC,mBAAmB,EAAE,SAAS,IAAI,EAAG,QAAO;AACjD,QAAI,CAAC,SAAS,UAAU,OAAO,EAAE,SAAS,IAAI,EAAG,QAAO;AACxD,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,QAAQ,YAAY;AAChC,MAAI,IAAI,SAAS,eAAe,EAAG,QAAO;AAC1C,MAAI,IAAI,SAAS,gBAAgB,EAAG,QAAO;AAC3C,MAAI,IAAI,SAAS,eAAe,KAAK,IAAI,SAAS,mBAAmB,EAAG,QAAO;AAC/E,MAAI,IAAI,SAAS,mCAAmC,KAAK,IAAI,SAAS,QAAQ,EAAG,QAAO;AACxF,MAAI,IAAI,SAAS,kBAAkB,EAAG,QAAO;AAC7C,MAAI,IAAI,SAAS,cAAc,EAAG,QAAO;AACzC,MAAI,IAAI,SAAS,gBAAgB,EAAG,QAAO;AAC3C,MAAI,IAAI,SAAS,kBAAkB,EAAG,QAAO;AAC7C,MAAI,IAAI,SAAS,UAAU,EAAG,QAAO;AACrC,MAAI,IAAI,SAAS,kBAAkB,EAAG,QAAO;AAC7C,MAAI,IAAI,SAAS,oBAAoB,EAAG,QAAO;AAC/C,MAAI,IAAI,SAAS,UAAU,EAAG,QAAO;AACrC,MAAI,IAAI,SAAS,kBAAkB,KAAK,IAAI,SAAS,UAAU,EAAG,QAAO;AACzE,MAAI,IAAI,SAAS,QAAQ,EAAG,QAAO;AACnC,SAAO;AACT;AAGO,SAAS,mBAAmB,UAA0C;AAC3E,SAAO,iBAAiB,QAAQ,KAAK,CAAC;AACxC;AAGO,SAAS,qBAA8B;AAC5C,SAAO,QAAQ,IAAI,iCAAiC;AACtD;AAEO,SAAS,sBAA+B;AAC7C,SAAO,QAAQ,IAAI,mCAAmC;AACxD;AA5GA,IAUI,WAWA,aAgCE;AArDN;AAAA;AAAA;AAAA;AAUA,IAAI,YAAuB;AAAA,MACzB,UAAU;AAAA,MACV,SAAS,QAAQ,IAAI,2BAA2B;AAAA,MAChD,QAAQ,QAAQ,IAAI,0BAA0B,QAAQ,IAAI,kBAAkB;AAAA,MAC5E,OAAO,QAAQ,IAAI,wBAAwB;AAAA,MAC3C,aAAa,WAAW,QAAQ,IAAI,8BAA8B,KAAK;AAAA,MACvE,WAAW,SAAS,QAAQ,IAAI,6BAA6B,QAAQ,EAAE;AAAA,MACvE,SAAS,SAAS,QAAQ,IAAI,0BAA0B,OAAO,EAAE;AAAA,IACnE;AAGA,IAAI,cAA4B,gBAAgB;AAgChD,IAAM,mBAA2D;AAAA,MAC/D,cAAc;AAAA,QACZ,gBAAgB;AAAA,QAChB,sBAAsB;AAAA,MACxB;AAAA,MACA,OAAO;AAAA,QACL,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA;AAAA;;;ACmEO,SAAS,kBAAkB,OAA+C;AAC/E,QAAM,UAAU,GAAG,MAAM,MAAM,UAAU,KAAK,MAAM,MAAM,YAAY;AACtE,QAAM,UAAoB,CAAC;AAC3B,MAAI,kBAAkB;AAGtB,QAAM,YAAY,eAAe;AACjC,aAAW,QAAQ,WAAW;AAC5B,QAAI;AACF,YAAM,KAAK,IAAI,OAAO,KAAK,OAAO;AAClC,UAAI,GAAG,KAAK,OAAO,GAAG;AACpB,YAAI,KAAK,WAAW,QAAQ;AAC1B,kBAAQ,KAAK,mCAAU,KAAK,OAAO,EAAE;AACrC,cAAI,aAAa,KAAK,QAAQ,IAAI,aAAa,eAAe,GAAG;AAC/D,8BAAkB,KAAK;AAAA,UACzB;AAAA,QACF;AAAA,MAEF;AAAA,IACF,QAAQ;AAAA,IAA4B;AAAA,EACtC;AAGA,aAAW,QAAQ,oBAAoB;AACrC,QAAI,KAAK,QAAQ,KAAK,OAAO,GAAG;AAC9B,cAAQ,KAAK,KAAK,WAAW;AAC7B,UAAI,aAAa,KAAK,QAAQ,IAAI,aAAa,eAAe,GAAG;AAC/D,0BAAkB,KAAK;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,GAAG,MAAM,MAAM,UAAU,IAAI,MAAM,MAAM,YAAY,IAAI,MAAM,UAAU,EAAE,IAAI,MAAM,iBAAiB,EAAE,GAAG,YAAY;AAC7I,QAAM,gBAAgB,uBAAuB,aAAa;AAC1D,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,SAAS,cAAc,OAAO,CAAC,GAAG,MAAM,aAAa,EAAE,SAAS,KAAK,aAAa,EAAE,SAAS,IAAI,IAAI,CAAC;AAC5G,YAAQ,KAAK,GAAG,cAAc,IAAI,OAAK,mCAAU,EAAE,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;AACzE,QAAI,aAAa,OAAO,SAAS,IAAI,aAAa,eAAe,GAAG;AAClE,wBAAkB,OAAO;AAAA,IAC3B;AAAA,EACF;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,WAAW,cAAc,SAAS,IAAI,qBAAqB;AACjE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,+CAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,MACtC,WAAW;AAAA,MACX;AAAA,MACA,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,gBAAgB,CAAC,GAAG;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBAAuB,MAAsE;AACpG,QAAM,OAA+D,CAAC;AACtE,aAAW,SAAS,oBAAoB;AACtC,QAAI,KAAK,SAAS,MAAM,QAAQ,YAAY,CAAC,GAAG;AAC9C,WAAK,KAAK,KAAK;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,GAAmB;AACvC,QAAM,QAAgC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,EAAE;AAChF,SAAO,MAAM,CAAC,KAAK;AACrB;AAxMA,IAYM,oBAgEA;AA5EN;AAAA;AAAA;AAAA;AAEA;AAUA,IAAM,qBAA6E;AAAA;AAAA,MAEjF,EAAE,SAAS,gCAAgC,WAAW,YAAY,MAAM,KAAK;AAAA,MAC7E,EAAE,SAAS,uBAAuB,WAAW,YAAY,MAAM,KAAK;AAAA,MACpE,EAAE,SAAS,uBAAuB,WAAW,YAAY,MAAM,KAAK;AAAA,MACpE,EAAE,SAAS,qBAAqB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC9D,EAAE,SAAS,8CAAW,WAAW,YAAY,MAAM,KAAK;AAAA,MACxD,EAAE,SAAS,8CAAW,WAAW,YAAY,MAAM,KAAK;AAAA,MACxD,EAAE,SAAS,wCAAU,WAAW,QAAQ,MAAM,KAAK;AAAA,MACnD,EAAE,SAAS,kCAAS,WAAW,QAAQ,MAAM,KAAK;AAAA;AAAA,MAElD,EAAE,SAAS,eAAe,WAAW,QAAQ,MAAM,KAAK;AAAA,MACxD,EAAE,SAAS,qBAAqB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC9D,EAAE,SAAS,oBAAoB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC7D,EAAE,SAAS,oBAAoB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC7D,EAAE,SAAS,wCAAU,WAAW,QAAQ,MAAM,KAAK;AAAA,MACnD,EAAE,SAAS,wCAAU,WAAW,QAAQ,MAAM,KAAK;AAAA,MACnD,EAAE,SAAS,wCAAU,WAAW,QAAQ,MAAM,KAAK;AAAA,MACnD,EAAE,SAAS,wCAAU,WAAW,QAAQ,MAAM,KAAK;AAAA;AAAA,MAEnD,EAAE,SAAS,iBAAiB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC1D,EAAE,SAAS,4BAA4B,WAAW,QAAQ,MAAM,KAAK;AAAA,MACrE,EAAE,SAAS,4BAA4B,WAAW,QAAQ,MAAM,KAAK;AAAA,MACrE,EAAE,SAAS,4BAA4B,WAAW,UAAU,MAAM,KAAK;AAAA,MACvE,EAAE,SAAS,4BAAQ,WAAW,QAAQ,MAAM,KAAK;AAAA,MACjD,EAAE,SAAS,wCAAU,WAAW,QAAQ,MAAM,KAAK;AAAA,MACnD,EAAE,SAAS,wCAAU,WAAW,UAAU,MAAM,KAAK;AAAA;AAAA,MAErD,EAAE,SAAS,8BAA8B,WAAW,QAAQ,MAAM,KAAK;AAAA,MACvE,EAAE,SAAS,2BAA2B,WAAW,QAAQ,MAAM,KAAK;AAAA,MACpE,EAAE,SAAS,kBAAkB,WAAW,YAAY,MAAM,KAAK;AAAA,MAC/D,EAAE,SAAS,cAAc,WAAW,QAAQ,MAAM,KAAK;AAAA,MACvD,EAAE,SAAS,oBAAoB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC7D,EAAE,SAAS,8CAAW,WAAW,QAAQ,MAAM,KAAK;AAAA,MACpD,EAAE,SAAS,8CAAW,WAAW,QAAQ,MAAM,KAAK;AAAA,MACpD,EAAE,SAAS,kCAAS,WAAW,YAAY,MAAM,KAAK;AAAA,MACtD,EAAE,SAAS,4BAAQ,WAAW,QAAQ,MAAM,KAAK;AAAA;AAAA,MAEjD,EAAE,SAAS,YAAY,WAAW,QAAQ,MAAM,KAAK;AAAA,MACrD,EAAE,SAAS,eAAe,WAAW,QAAQ,MAAM,KAAK;AAAA,MACxD,EAAE,SAAS,YAAY,WAAW,QAAQ,MAAM,KAAK;AAAA,MACrD,EAAE,SAAS,WAAW,WAAW,QAAQ,MAAM,KAAK;AAAA;AAAA,MAEpD,EAAE,SAAS,cAAc,WAAW,QAAQ,MAAM,KAAK;AAAA,MACvD,EAAE,SAAS,kBAAkB,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC3D,EAAE,SAAS,WAAW,WAAW,QAAQ,MAAM,KAAK;AAAA,MACpD,EAAE,SAAS,oBAAU,WAAW,QAAQ,MAAM,KAAK;AAAA,MACnD,EAAE,SAAS,gCAAY,WAAW,QAAQ,MAAM,KAAK;AAAA;AAAA,MAErD,EAAE,SAAS,kBAAkB,WAAW,YAAY,MAAM,KAAK;AAAA,MAC/D,EAAE,SAAS,YAAY,WAAW,YAAY,MAAM,KAAK;AAAA,MACzD,EAAE,SAAS,aAAa,WAAW,YAAY,MAAM,KAAK;AAAA,MAC1D,EAAE,SAAS,kCAAS,WAAW,YAAY,MAAM,KAAK;AAAA,MACtD,EAAE,SAAS,gBAAM,WAAW,YAAY,MAAM,KAAK;AAAA;AAAA,MAEnD,EAAE,SAAS,gBAAgB,WAAW,YAAY,MAAM,KAAK;AAAA,MAC7D,EAAE,SAAS,uBAAuB,WAAW,YAAY,MAAM,KAAK;AAAA,MACpE,EAAE,SAAS,iBAAiB,WAAW,YAAY,MAAM,KAAK;AAAA,MAC9D,EAAE,SAAS,4BAAQ,WAAW,YAAY,MAAM,KAAK;AAAA,MACrD,EAAE,SAAS,wCAAU,WAAW,YAAY,MAAM,KAAK;AAAA,MACvD,EAAE,SAAS,4BAAQ,WAAW,YAAY,MAAM,KAAK;AAAA,IACvD;AAGA,IAAM,qBAAmF;AAAA;AAAA;AAAA,MAGvF,EAAE,SAAS,iDAAiD,UAAU,YAAY,aAAa,oEAAuB;AAAA;AAAA,MAEtH,EAAE,SAAS,iDAAiD,UAAU,YAAY,aAAa,6EAA2B;AAAA;AAAA,MAE1H,EAAE,SAAS,uFAAuF,UAAU,YAAY,aAAa,mDAAW;AAAA;AAAA,MAEhJ,EAAE,SAAS,qCAAqC,UAAU,QAAQ,aAAa,oDAAsB;AAAA;AAAA,MAErG,EAAE,SAAS,qCAAqC,UAAU,UAAU,aAAa,oDAAsB;AAAA,MACvG,EAAE,SAAS,6CAA6C,UAAU,YAAY,aAAa,oDAAY;AAAA,MACvG,EAAE,SAAS,WAAW,UAAU,YAAY,aAAa,6CAAU;AAAA,MACnE,EAAE,SAAS,4BAA4B,UAAU,YAAY,aAAa,YAAY;AAAA;AAAA,MAEtF,EAAE,SAAS,qCAAqC,UAAU,YAAY,aAAa,+BAAqB;AAAA,MACxG,EAAE,SAAS,4BAA4B,UAAU,YAAY,aAAa,+BAAqB;AAAA,MAC/F,EAAE,SAAS,oCAAoC,UAAU,YAAY,aAAa,4CAAc;AAAA,MAChG,EAAE,SAAS,8BAA8B,UAAU,YAAY,aAAa,kCAAc;AAAA;AAAA,MAE1F,EAAE,SAAS,gCAAgC,UAAU,YAAY,aAAa,qBAAW;AAAA,MACzF,EAAE,SAAS,2BAA2B,UAAU,QAAQ,aAAa,kCAAc;AAAA;AAAA,MAEnF,EAAE,SAAS,kBAAkB,UAAU,YAAY,aAAa,iEAAyB;AAAA,MACzF,EAAE,SAAS,kBAAkB,UAAU,YAAY,aAAa,4CAAc;AAAA;AAAA,MAE9E,EAAE,SAAS,6BAA6B,UAAU,YAAY,aAAa,mFAA4B;AAAA;AAAA,MAEvG,EAAE,SAAS,4BAA4B,UAAU,QAAQ,aAAa,6CAAoB;AAAA,MAC1F,EAAE,SAAS,2CAA2C,UAAU,QAAQ,aAAa,2GAA2B;AAAA,MAChH,EAAE,SAAS,oBAAoB,UAAU,QAAQ,aAAa,gCAAY;AAAA,MAC1E,EAAE,SAAS,YAAY,UAAU,QAAQ,aAAa,kCAAc;AAAA;AAAA,MAEpE,EAAE,SAAS,gBAAgB,UAAU,YAAY,aAAa,+DAAa;AAAA;AAAA,MAE3E,EAAE,SAAS,6DAA6D,UAAU,QAAQ,aAAa,yDAAY;AAAA,MACnH,EAAE,SAAS,uDAAuD,UAAU,QAAQ,aAAa,iCAAQ;AAAA;AAAA,MAEzG,EAAE,SAAS,6BAA6B,UAAU,QAAQ,aAAa,uBAAuB;AAAA,MAC9F,EAAE,SAAS,gCAAgC,UAAU,QAAQ,aAAa,yBAAyB;AAAA,MACnG,EAAE,SAAS,qCAAqC,UAAU,QAAQ,aAAa,yBAAyB;AAAA;AAAA,MAExG,EAAE,SAAS,2BAA2B,UAAU,QAAQ,aAAa,0DAA4B;AAAA;AAAA,MAEjG,EAAE,SAAS,6CAA6C,UAAU,UAAU,aAAa,uCAAS;AAAA;AAAA,MAElG,EAAE,SAAS,kFAAkF,UAAU,QAAQ,aAAa,wJAA0C;AAAA;AAAA,MAEtK,EAAE,SAAS,wBAAwB,UAAU,QAAQ,aAAa,2FAAqB;AAAA,IACzF;AAAA;AAAA;;;AC9HA,YAAY,QAAQ;AAyEb,SAAS,cAAc,OAA+C;AAC3E,QAAM,EAAE,eAAe,OAAO,IAAI,IAAI;AACtC,QAAM,eAAe,MAAM,aAAa,YAAY;AACpD,QAAM,aAAa,MAAM,WAAW,YAAY;AAChD,QAAM,cAAc,OAAO;AAG3B,QAAM,YAAY,qBAAqB,YAAY,cAAc,eAAe,MAAM,QAAQ,WAAW;AACzG,MAAI,UAAW,QAAO;AAGtB,MAAI,MAAM,iBAAiB,MAAM,cAAc,KAAK,GAAG;AACrD,UAAM,cAAc,MAAM,cAAc,YAAY;AACpD,eAAW,WAAW,2BAA2B;AAC/C,YAAM,gBAAgB,QAAQ,eAAe,KAAK,QAAM,YAAY,SAAS,EAAE,CAAC;AAChF,YAAM,mBAAmB,QAAQ,iBAAiB,KAAK,QAAM,aAAa,SAAS,EAAE,CAAC;AACtF,UAAI,iBAAiB,kBAAkB;AACrC,eAAO;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,QAAQ;AAAA,UAChB,WAAW;AAAA,UACX,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,gBAAgB,CAAC,GAAG;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,aAAa,mBAAmB,cAAc,WAAW;AAC/D,MAAI,WAAY,QAAO;AAGvB,MAAI,eAAe,gBAAgB,eAAe,aAAa;AAE7D,SAAK,aAAa,SAAS,GAAG,KAAK,aAAa,SAAS,GAAG,MACxD,CAAC,OAAO,OAAQ,QAAQ,QAAS,UAAU,WAAW,WAAY,gBAAM,cAAI,EAAE,KAAK,QAAM,aAAa,SAAS,EAAE,CAAC,GAAG;AACvH,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAEA,QAAI,cAAc,KAAK,YAAY,KAAK,eAAe,KAAK,YAAY,KAAK,eAAe,KAAK,YAAY,GAAG;AAC9G,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,aAAa,SAAS,MAAM,KAAK,aAAa,SAAS,MAAM,KAAK,aAAa,SAAS,WAAW,KAAK,aAAa,SAAS,QAAQ,GAAG;AAC3I,UAAM,eAAe,cAAc;AAAA,MAAK,OACtC,EAAE,aAAa,SAAS,MAAM,KAAK,EAAE,aAAa,SAAS,KAAK,KAAK,EAAE,aAAa,SAAS,WAAW,KACxG,EAAE,aAAa,SAAS,KAAK,KAAK,EAAE,aAAa,SAAS,KAAK,KAAK,EAAE,aAAa,SAAS,QAAQ,KACpG,EAAE,aAAa,SAAS,QAAQ,KAAK,EAAE,aAAa,SAAS,KAAK;AAAA,IACpE;AACA,QAAI,CAAC,cAAc;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,uBAAuB,KAAK,YAAY,GAAG;AAC7C,UAAM,aAAa,kBAAkB,YAAY;AACjD,QAAI,cAAc,CAAC,YAAY,UAAU,GAAG;AAC1C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,uEAAgB,UAAU;AAAA,QAClC,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,SAAS,iBAAiB,MAAwB;AAChD,QAAM,QAAkB,CAAC;AAEzB,QAAM,YAAY,KAAK,MAAM,4BAA4B;AACzD,MAAI,UAAW,OAAM,KAAK,GAAG,UAAU,IAAI,OAAK,EAAE,KAAK,CAAC,CAAC;AAEzD,QAAM,cAAc,KAAK,MAAM,qBAAqB;AACpD,MAAI,YAAa,OAAM,KAAK,GAAG,YAAY,IAAI,OAAK,EAAE,QAAQ,SAAS,EAAE,CAAC,CAAC;AAC3E,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC;AAC3B;AAEA,SAAS,qBACP,YAAoB,cACpB,eACA,QAAgB,KACS;AAEzB,MAAI,gBAAgB,IAAI,UAAU,EAAG,QAAO;AAG5C,QAAM,UAAU,eAAe,KAAK,QAAM,WAAW,SAAS,EAAE,KAAK,aAAa,SAAS,EAAE,CAAC;AAC9F,MAAI,CAAC,QAAS,QAAO;AAGrB,QAAM,cAAc,iBAAiB,YAAY;AACjD,MAAI,YAAY,WAAW,EAAG,QAAO;AAGrC,QAAM,mBAAmB,oBAAI,IAAY;AACzC,aAAW,UAAU,eAAe;AAClC,UAAM,aAAa,OAAO,aAAa,YAAY;AACnD,UAAM,WAAW,OAAO,WAAW,YAAY;AAC/C,UAAM,SAAS,cAAc,KAAK,QAAM,SAAS,SAAS,EAAE,KAAK,WAAW,SAAS,EAAE,CAAC;AACxF,QAAI,QAAQ;AACV,iBAAW,KAAK,iBAAiB,UAAU,GAAG;AAC5C,yBAAiB,IAAI,CAAC;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAGA,QAAM,cAAwB,CAAC;AAC/B,aAAWA,SAAQ,aAAa;AAC9B,UAAM,UAAU,CAAC,GAAG,gBAAgB,EAAE;AAAA,MAAK,QACzCA,UAAS,MAAMA,MAAK,WAAW,EAAE,KAAK,GAAG,WAAWA,KAAI;AAAA,IAC1D;AACA,QAAI,CAAC,SAAS;AAGZ,UAAI,WAAW,CAAI,cAAWA,KAAI;AAClC,UAAI,CAAC,UAAU;AACb,mBAAW,gBAAgB,KAAK,QAAM,OAAO,YAAY,EAAE,SAAS,EAAE,KAAK,aAAa,SAAS,EAAE,CAAC;AAAA,MACtG;AACA,UAAI,CAAC,UAAU;AACb,oBAAY,KAAKA,KAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,mFAAiC,YAAY,CAAC,CAAC;AAAA,MACvD,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,gBAAgB,CAAC,GAAG;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,mBAAmB,SAAiB,KAAsC;AACjF,QAAM,cAAc,IAAI,QAAQ,MAAM,QAAQ,IAAI,QAAQ,YAAY;AAEtE,aAAW,MAAM,sBAAsB;AACrC,QAAI,QAAQ,SAAS,GAAG,KAAK,YAAY,CAAC,GAAG;AAC3C,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,iEAAe,GAAG,IAAI,KAAK,GAAG,IAAI;AAAA,QAC1C,WAAW,GAAG;AAAA,QACd,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,aAAW,MAAM,sBAAsB;AACrC,UAAM,WAAW,GAAG,WAAW,IAAI,GAAG,IAAI;AAC1C,QAAI,QAAQ,SAAS,GAAG,KAAK,YAAY,CAAC,KAAK,QAAQ,SAAS,SAAS,YAAY,CAAC,GAAG;AACvF,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,qDAAa,GAAG,IAAI,KAAK,GAAG,IAAI;AAAA,QACxC,WAAW,GAAG;AAAA,QACd,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAIA,aAAW,MAAM,kBAAkB;AACjC,UAAM,UAAU,GAAG,KAAK,QAAQ,uBAAuB,MAAM;AAC7D,UAAM,KAAK,GAAG,KAAK,WAAW,GAAG,IAC7B,IAAI,OAAO,mBAAmB,OAAO,KAAK,IAC1C,IAAI,OAAO,MAAM,OAAO,KAAK;AACjC,QAAI,GAAG,KAAK,OAAO,GAAG;AACpB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,yCAAW,GAAG,IAAI,KAAK,GAAG,IAAI;AAAA,QACtC,WAAW,GAAG;AAAA,QACd,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAGA,OAAK,QAAQ,SAAS,KAAK,KAAK,QAAQ,SAAS,QAAQ,OACpD,QAAQ,SAAS,OAAO,KAAK,QAAQ,SAAS,QAAQ,KAAK,QAAQ,SAAS,WAAW,IAAI;AAC9F,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,gBAAgB,CAAC,GAAG;AAAA,IACtB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,SAAgC;AACzD,QAAM,IAAI,QAAQ,MAAM,8DAA8D;AACtF,SAAO,IAAI,EAAE,CAAC,IAAI;AACpB;AAEA,SAAS,YAAY,MAAuB;AAC1C,QAAM,aAAa,CAAC,aAAa,aAAa,OAAO,QAAQ,IAAI,YAAY,IAAI,SAAS;AAC1F,SAAO,WAAW,SAAS,KAAK,QAAQ,OAAO,EAAE,CAAC;AACpD;AAvUA,IAYM,sBAiBA,sBAUA,kBASA,iBAGA,gBAGA,eAGA,iBAGA;AA5DN;AAAA;AAAA;AAAA;AAYA,IAAM,uBAA4E;AAAA,MAChF,EAAE,MAAM,eAAe,WAAW,YAAY,MAAM,uCAAS;AAAA,MAC7D,EAAE,MAAM,eAAe,WAAW,QAAQ,MAAM,uCAAS;AAAA,MACzD,EAAE,MAAM,gBAAgB,WAAW,YAAY,MAAM,oBAAU;AAAA,MAC/D,EAAE,MAAM,cAAc,WAAW,UAAU,MAAM,+BAAW;AAAA,MAC5D,EAAE,MAAM,gBAAgB,WAAW,QAAQ,MAAM,uCAAS;AAAA,MAC1D,EAAE,MAAM,iBAAiB,WAAW,QAAQ,MAAM,mCAAe;AAAA,MACjE,EAAE,MAAM,wBAAwB,WAAW,QAAQ,MAAM,+BAAW;AAAA,MACpE,EAAE,MAAM,cAAc,WAAW,YAAY,MAAM,wBAAc;AAAA,MACjE,EAAE,MAAM,iBAAiB,WAAW,QAAQ,MAAM,0BAAgB;AAAA,MAClE,EAAE,MAAM,UAAU,WAAW,YAAY,MAAM,uCAAS;AAAA,MACxD,EAAE,MAAM,cAAc,WAAW,QAAQ,MAAM,2BAAO;AAAA,MACtD,EAAE,MAAM,SAAS,WAAW,QAAQ,MAAM,iCAAa;AAAA,MACvD,EAAE,MAAM,YAAY,WAAW,YAAY,MAAM,mDAAW;AAAA,MAC5D,EAAE,MAAM,aAAa,WAAW,QAAQ,MAAM,6CAAU;AAAA,IAC1D;AAEA,IAAM,uBAA4E;AAAA,MAChF,EAAE,MAAM,eAAe,WAAW,YAAY,MAAM,mBAAS;AAAA,MAC7D,EAAE,MAAM,mBAAmB,WAAW,YAAY,MAAM,6BAAmB;AAAA,MAC3E,EAAE,MAAM,wBAAwB,WAAW,QAAQ,MAAM,+BAAW;AAAA,MACpE,EAAE,MAAM,oBAAoB,WAAW,YAAY,MAAM,mBAAS;AAAA,MAClE,EAAE,MAAM,cAAc,WAAW,UAAU,MAAM,mBAAS;AAAA,MAC1D,EAAE,MAAM,UAAU,WAAW,QAAQ,MAAM,+BAAW;AAAA,IACxD;AAGA,IAAM,mBAAwE;AAAA,MAC5E,EAAE,MAAM,mBAAmB,WAAW,QAAQ,MAAM,uCAAS;AAAA,MAC7D,EAAE,MAAM,oBAAoB,WAAW,QAAQ,MAAM,uCAAS;AAAA,MAC9D,EAAE,MAAM,eAAe,WAAW,QAAQ,MAAM,uCAAS;AAAA,MACzD,EAAE,MAAM,gBAAgB,WAAW,QAAQ,MAAM,uCAAS;AAAA,MAC1D,EAAE,MAAM,QAAQ,WAAW,QAAQ,MAAM,gEAAc;AAAA,IACzD;AAGA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,qBAAqB,QAAQ,QAAQ,YAAY,qBAAqB,QAAQ,CAAC;AAGhH,IAAM,iBAAiB,CAAC,SAAS,gBAAM,QAAQ,gBAAM,UAAU,gBAAM,UAAU,gBAAM,UAAU,gBAAM,UAAU,gBAAM,UAAU,gBAAM,UAAU,gBAAM,YAAY,gBAAM,aAAa,gBAAM,WAAW,cAAI;AAGzM,IAAM,gBAAgB,CAAC,QAAQ,gBAAM,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,gBAAM,QAAQ,gBAAM,QAAQ,gBAAM,QAAQ,UAAU,gBAAM,QAAQ,cAAI;AAG1J,IAAM,kBAAkB,CAAC,gBAAM,gBAAM,UAAU,YAAY,OAAO;AAGlE,IAAM,4BAAwG;AAAA,MAC5G;AAAA,QACE,gBAAgB,CAAC,gBAAM,gBAAM,gBAAM,QAAQ,WAAW,QAAQ,QAAQ,cAAI;AAAA,QAC1E,kBAAkB,CAAC,gBAAM,UAAU,UAAU,OAAO,sBAAO,QAAQ;AAAA,QACnE,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,QACE,gBAAgB,CAAC,gBAAM,gBAAM,UAAU,SAAS,MAAM;AAAA,QACtD,kBAAkB,CAAC,gBAAM,UAAU,SAAS,gBAAM,OAAO;AAAA,QACzD,QAAQ;AAAA,MACV;AAAA,IACF;AAAA;AAAA;;;ACvEA,SAAS,cAAc,aAAa,cAAAC,mBAAkB;AACtD,SAAS,SAAS,eAAe;AACjC,SAAS,iBAAAC,sBAAqB;AA0B9B,SAAS,gBAAwC;AAC/C,MAAI,aAAc,QAAO;AACzB,iBAAe,CAAC;AAEhB,MAAI,CAACD,YAAW,UAAU,GAAG;AAC3B,YAAQ,KAAK,2CAA2C,UAAU;AAClE,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,YAAY,UAAU,EAAE,OAAO,OAAK,EAAE,SAAS,KAAK,CAAC;AACnE,aAAW,KAAK,OAAO;AACrB,UAAM,OAAO,EAAE,QAAQ,OAAO,EAAE;AAChC,iBAAa,IAAI,IAAI,aAAa,QAAQ,YAAY,CAAC,GAAG,OAAO;AAAA,EACnE;AAEA,UAAQ,IAAI,sBAAsB,OAAO,KAAK,YAAY,EAAE,MAAM,SAAS;AAC3E,SAAO;AACT;AAYO,SAAS,YACd,YACA,cACA,QACA,YAAoB,GACN;AACd,QAAM,SAAS,cAAc;AAC7B,QAAM,WAAW,GAAG,UAAU,IAAI,YAAY,IAAI,MAAM,GAAG,YAAY;AACvE,QAAM,oBAAoB,aAAa,YAAY;AACnD,QAAM,kBAAkB,WAAW,YAAY;AAC/C,QAAM,cAAc,OAAO,YAAY;AAEvC,QAAM,SAAiC,CAAC;AACxC,aAAW,CAAC,WAAW,QAAQ,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AACrE,QAAI,QAAQ;AACZ,eAAW,MAAM,UAAU;AACzB,UAAI,SAAS,SAAS,EAAE,GAAG;AACzB,YAAI,OAAO,gBAAiB,UAAS;AAAA,iBAC5B,kBAAkB,SAAS,EAAE,EAAG,UAAS;AAAA,iBACzC,YAAY,SAAS,EAAE,EAAG,UAAS;AAAA,YACvC,UAAS;AAAA,MAChB;AAAA,IACF;AACA,QAAI,QAAQ,EAAG,QAAO,SAAS,IAAI;AAAA,EACrC;AAEA,QAAM,SAAS,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;AAChE,QAAM,MAAM,OAAO,MAAM,GAAG,SAAS;AACrC,QAAM,WAAW,IAAI,CAAC,IAAI,CAAC,KAAK;AAEhC,QAAM,UAAwB,CAAC;AAC/B,aAAW,CAAC,MAAM,KAAK,KAAK,KAAK;AAC/B,UAAM,UAAU,OAAO,IAAI;AAC3B,QAAI,SAAS;AACX,cAAQ,KAAK;AAAA,QACX,WAAW;AAAA,QACX,WAAW,KAAK,IAAI,QAAQ,UAAU,CAAG;AAAA,QACzC,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,WAAW,OAAO,yBAAyB;AACjD,QAAI,UAAU;AACZ,cAAQ,KAAK,EAAE,WAAW,2BAA2B,WAAW,KAAK,cAAc,SAAS,CAAC;AAAA,IAC/F;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,sBAAsB,QAA8B;AAClE,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO;AAAA,IAAI,OAChB,6CAAe,EAAE,SAAS,yBAAU,KAAK,MAAM,EAAE,YAAY,GAAG,CAAC;AAAA;AAAA,EAAS,EAAE,YAAY;AAAA,EAC1F,EAAE,KAAK,aAAa;AACtB;AAtHA,IAIME,aACAC,YAGA,YAGA,mBAeF;AA1BJ;AAAA;AAAA;AAAA;AAIA,IAAMD,cAAaD,eAAc,YAAY,GAAG;AAChD,IAAME,aAAY,QAAQD,WAAU;AAGpC,IAAM,aAAa,QAAQC,YAAW,yBAAyB;AAG/D,IAAM,oBAA8C;AAAA,MAClD,qBAAqB,CAAC,QAAQ,gBAAM,QAAQ,gBAAM,QAAQ,SAAS,OAAO,QAAQ,UAAU,gBAAM,gBAAM,QAAQ,MAAM,MAAM,MAAM;AAAA,MAClI,0BAA0B,CAAC,WAAW,SAAS,QAAQ,QAAQ,WAAW,gBAAM,gBAAM,UAAU,gBAAM,OAAO,gBAAM,cAAc,UAAU,QAAQ,WAAW,gBAAM,WAAW,OAAO,KAAK;AAAA,MAC3L,2BAA2B,CAAC,UAAU,gBAAM,QAAQ,gBAAM,YAAY,gBAAM,UAAU,gBAAM,YAAY,gBAAM,QAAQ,QAAQ,WAAW,SAAS,QAAQ,QAAQ,gBAAM,gBAAM,SAAS,WAAW,cAAI;AAAA,MACtM,4BAA4B,CAAC,WAAW,sBAAO,OAAO,gBAAM,OAAO,YAAY,gBAAM,UAAU,SAAS,gBAAM,SAAS,YAAY;AAAA,MACnI,yBAAyB,CAAC,SAAS,gBAAM,QAAQ,QAAQ,cAAc,4BAAQ,SAAS,sBAAO,gBAAM,YAAY;AAAA,MACjH,2BAA2B,CAAC,QAAQ,gBAAM,OAAO,UAAU,gBAAM,YAAY,cAAI;AAAA,MACjF,0BAA0B,CAAC,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,UAAU,gBAAM,gBAAM,UAAU,gBAAM,SAAS,QAAQ,gBAAM,QAAQ,gBAAM,QAAQ,cAAc,UAAU;AAAA,MACjL,8BAA8B,CAAC,QAAQ,WAAW,gBAAM,aAAa,WAAW,sBAAO,WAAW,gBAAM,UAAU,gBAAM,YAAY,sBAAO,YAAY,gBAAM,WAAW,sBAAO,mBAAmB,UAAU,SAAS,WAAW,OAAO,gBAAgB,oBAAU;AAAA,MACjQ,6BAA6B,CAAC,QAAQ,QAAQ,gBAAM,UAAU,gBAAM,QAAQ,gBAAM,OAAO,WAAW,gBAAM,MAAM,cAAc,4BAAQ,gBAAM,WAAW,cAAI;AAAA,MAC3J,4BAA4B,CAAC,SAAS,UAAU,gBAAM,aAAa,gBAAM,iBAAiB,4BAAQ,4BAAQ,eAAe,cAAI;AAAA,MAC7H,sBAAsB,CAAC,cAAc,gBAAM,WAAW,UAAK,eAAe,eAAe,gBAAgB,UAAU,WAAW,UAAK,YAAY,gBAAM,UAAU,sBAAO,eAAe;AAAA,MACrL,0BAA0B,CAAC,MAAM,OAAO,UAAU,UAAU,gBAAM,UAAU,sBAAO,QAAQ,YAAY,gBAAM,QAAQ,gBAAM,gBAAM,SAAS,QAAQ,QAAQ,SAAS,sBAAO,aAAa,cAAI;AAAA,IAC7L;AAEA,IAAI,eAA8C;AAAA;AAAA;;;AC1BlD,SAAS,gBAAAC,eAAc,cAAAC,mBAAkB;AACzC,SAAS,WAAAC,UAAS,WAAAC,gBAAe;AACjC,SAAS,iBAAAC,sBAAqB;AAWvB,SAAS,gBAAwC;AACtD,MAAI,gBAAiB,QAAO;AAE5B,oBAAkB,CAAC;AAEnB,MAAI,CAACH,YAAW,aAAa,GAAG;AAC9B,YAAQ,KAAK,8CAA8C,aAAa;AACxE,WAAO;AAAA,EACT;AAEA,aAAW,QAAQ,gBAAgB;AACjC,UAAM,WAAWC,SAAQ,eAAe,IAAI;AAC5C,QAAID,YAAW,QAAQ,GAAG;AACxB,YAAM,MAAM,KAAK,QAAQ,QAAQ,EAAE,EAAE,QAAQ,aAAa,EAAE;AAC5D,sBAAgB,GAAG,IAAID,cAAa,UAAU,OAAO;AAAA,IACvD;AAAA,EACF;AAEA,UAAQ,IAAI,sBAAsB,OAAO,KAAK,eAAe,EAAE,MAAM,YAAY;AACjF,SAAO;AACT;AAjCA,IAIMK,aACAC,YAEA,eAEA,gBAEF;AAXJ;AAAA;AAAA;AAAA;AAIA,IAAMD,cAAaD,eAAc,YAAY,GAAG;AAChD,IAAME,aAAYH,SAAQE,WAAU;AAEpC,IAAM,gBAAgBH,SAAQI,YAAW,4BAA4B;AAErE,IAAM,iBAAiB,CAAC,wBAAwB,wBAAwB,6BAA6B;AAErG,IAAI,kBAAiD;AAAA;AAAA;;;ACXrD,SAAS,gBAAAC,qBAAoB;AAC7B,SAAS,WAAAC,UAAS,YAAY;AA4G9B,SAAS,cAAoC;AAC3C,SAAO,EAAE,YAAY,IAAI,eAAe,IAAI,iBAAiB,CAAC,GAAG,WAAW,GAAG,cAAc,OAAO,OAAO,IAAI,WAAW,IAAI,YAAY,GAAG;AAC/I;AAEA,SAAS,kBAAkB,SAAgC;AACzD,aAAW,WAAW,sBAAsB;AAC1C,UAAM,IAAI,QAAQ,MAAM,OAAO;AAC/B,QAAI,EAAG,QAAO,EAAE,CAAC;AAAA,EACnB;AACA,SAAO;AACT;AAEA,SAAS,sBAAsB,SAA2B;AACxD,QAAM,UAAoB,CAAC;AAC3B,aAAW,EAAE,MAAM,QAAQ,KAAK,qBAAqB;AACnD,QAAI,QAAQ,KAAK,OAAO,EAAG,SAAQ,KAAK,IAAI;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,SAAS,6BAA6B,iBAA2B,eAA0D;AACzH,MAAI,gBAAgB,WAAW,EAAG,QAAO,EAAE,OAAO,IAAI,QAAQ,GAAG;AAEjE,QAAM,aAAa,IAAI,IAAI,eAAe;AAG1C,aAAW,QAAQ,2BAA2B;AAC5C,UAAM,YAAY,CAAC,GAAG,KAAK,MAAM,EAAE,KAAK,OAAK,WAAW,IAAI,CAAC,CAAC;AAC9D,UAAM,YAAY,KAAK,OAAO,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,KAAK,OAAK,WAAW,IAAI,CAAC,CAAC;AAC9F,QAAI,aAAa,UAAW,QAAO,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO;AAAA,EAC9E;AAGA,QAAM,sBAAsB,oBAAI,IAAI,CAAC,aAAa,eAAe,WAAW,oBAAoB,kBAAkB,CAAC;AACnH,QAAM,iBAAiB,CAAC,GAAG,mBAAmB,EAAE,KAAK,OAAK,WAAW,IAAI,CAAC,CAAC;AAC3E,MAAI,gBAAgB;AAClB,UAAM,cAAc,CAAC,QAAQ,UAAU,SAAS,eAAe,UAAU,OAAO;AAChF,UAAM,eAAe,cAAc,YAAY;AAC/C,eAAW,KAAK,aAAa;AAC3B,UAAI,aAAa,SAAS,EAAE,YAAY,CAAC,GAAG;AAC1C,eAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,aAAW,MAAM,iBAAiB;AAChC,UAAM,OAAO,qBAAqB,EAAE;AACpC,QAAI,SAAS,YAAY,KAAK,KAAK,KAAK,MAAM,YAAY,SAAS,KAAK,IAAI;AAC1E,kBAAY,KAAK;AACjB,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,WAAW,QAAQ,WAAW;AAChD;AAEA,SAAS,kBAAkB,YAAoB,WAAmB,KAA4D;AAC5H,MAAI;AACF,UAAM,eAAe,WAAW,WAAW,GAAG,IAC1C,KAAK,QAAQ,IAAI,QAAQ,cAAc,WAAW,MAAM,CAAC,CAAC,IAC1DA,SAAQ,UAAU;AAEtB,UAAM,MAAMD,cAAa,cAAc,OAAO;AAC9C,UAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,MAAM,GAAG,QAAQ;AAC/C,WAAO,EAAE,SAAS,MAAM,KAAK,IAAI,GAAG,WAAW,MAAM,QAAQ,OAAO,GAAG;AAAA,EACzE,SAAS,GAAY;AACnB,UAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,WAAO,EAAE,SAAS,IAAI,WAAW,GAAG,OAAO,yCAAW,GAAG,GAAG;AAAA,EAC9D;AACF;AAEO,SAAS,qBAAqB,YAAoB,cAAsB,WAAmB,KAA2B;AAC3H,MAAI,WAAW,YAAY,MAAM,OAAQ,QAAO,YAAY;AAE5D,QAAM,aAAa,kBAAkB,YAAY;AACjD,MAAI,CAAC,WAAY,QAAO,YAAY;AAEpC,QAAM,EAAE,SAAS,WAAW,MAAM,IAAI,kBAAkB,YAAY,QAAQ;AAC5E,MAAI,MAAO,QAAO,EAAE,GAAG,YAAY,GAAG,YAAY,MAAM;AAExD,QAAM,kBAAkB,sBAAsB,OAAO;AACrD,QAAM,eAAe,gBAAgB,SAAS;AAE9C,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,MAAI,cAAc;AAChB,UAAM,OAAO,6BAA6B,iBAAiB,OAAO;AAClE,gBAAY,KAAK;AACjB,iBAAa,KAAK;AAAA,EACpB;AAEA,SAAO,EAAE,YAAY,eAAe,SAAS,iBAAiB,WAAW,cAAc,OAAO,IAAI,WAAW,WAAW;AAC1H;AAEO,SAAS,8BAA8B,QAAsC;AAClF,MAAI,CAAC,OAAO,WAAY,QAAO;AAC/B,MAAI,OAAO,MAAO,QAAO,qDAAa,OAAO,KAAK;AAClD,MAAI,CAAC,OAAO,aAAc,QAAO;AAEjC,QAAM,cAAc,OAAO,gBAAgB,KAAK,IAAI;AACpD,MAAI,WAAW;AACf,MAAI,OAAO,aAAa,OAAO,YAAY;AACzC,eAAW;AAAA;AAAA,4BAAa,OAAO,UAAU,YAAY,CAAC;AAAA,4BAAc,OAAO,UAAU;AAAA;AAAA,EACvF;AAEA,SAAO;AAAA,+BAAmC,OAAO,UAAU;AAAA,qCAAe,WAAW;AAAA,+BAAc,OAAO,SAAS,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA,EAA6B,OAAO,aAAa;AAAA;AAAA;AACjL;AA7NA,IAWM,qBA2BA,sBAUA,2BA2BA,sBAqBA;AAhGN;AAAA;AAAA;AAAA;AAWA,IAAM,sBAA2D;AAAA;AAAA,MAE/D,EAAE,MAAM,aAAa,SAAS,2BAA2B;AAAA,MACzD,EAAE,MAAM,eAAe,SAAS,wBAAwB;AAAA,MACxD,EAAE,MAAM,WAAW,SAAS,sBAAsB;AAAA,MAClD,EAAE,MAAM,oBAAoB,SAAS,6BAA6B;AAAA,MAClE,EAAE,MAAM,oBAAoB,SAAS,6BAA6B;AAAA;AAAA,MAElE,EAAE,MAAM,SAAS,SAAS,gBAAgB;AAAA,MAC1C,EAAE,MAAM,WAAW,SAAS,kBAAkB;AAAA,MAC9C,EAAE,MAAM,YAAY,SAAS,eAAe;AAAA,MAC5C,EAAE,MAAM,YAAY,SAAS,eAAe;AAAA;AAAA,MAE5C,EAAE,MAAM,YAAY,SAAS,gBAAgB;AAAA,MAC7C,EAAE,MAAM,WAAW,SAAS,aAAa;AAAA,MACzC,EAAE,MAAM,sBAAsB,SAAS,8BAA8B;AAAA;AAAA,MAErE,EAAE,MAAM,eAAe,SAAS,gBAAgB;AAAA,MAChD,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,MACxC,EAAE,MAAM,cAAc,SAAS,iBAAiB;AAAA;AAAA,MAEhD,EAAE,MAAM,mBAAmB,SAAS,cAAc;AAAA,MAClD,EAAE,MAAM,mBAAmB,SAAS,kBAAkB;AAAA,MACtD,EAAE,MAAM,yBAAyB,SAAS,yCAAyC;AAAA,IACrF;AAGA,IAAM,uBAAuB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAGA,IAAM,4BAA2G;AAAA,MAC/G;AAAA,QACE,QAAQ,oBAAI,IAAI,CAAC,aAAa,eAAe,WAAW,oBAAoB,kBAAkB,CAAC;AAAA,QAC/F,QAAQ,oBAAI,IAAI,CAAC,YAAY,WAAW,oBAAoB,CAAC;AAAA,QAC7D,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ,oBAAI,IAAI,CAAC,aAAa,eAAe,WAAW,oBAAoB,kBAAkB,CAAC;AAAA,QAC/F,QAAQ,oBAAI,IAAI,CAAC,eAAe,UAAU,YAAY,CAAC;AAAA,QACvD,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ,oBAAI,IAAI,CAAC,SAAS,WAAW,YAAY,UAAU,CAAC;AAAA,QAC5D,QAAQ,oBAAI,IAAI;AAAA,QAChB,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,QACE,QAAQ,oBAAI,IAAI,CAAC,mBAAmB,mBAAmB,uBAAuB,CAAC;AAAA,QAC/E,QAAQ,oBAAI,IAAI;AAAA,QAChB,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,IACF;AAEA,IAAM,uBAA0E;AAAA,MAC9E,aAAa,EAAE,OAAO,QAAQ,QAAQ,gIAAiC;AAAA,MACvE,eAAe,EAAE,OAAO,QAAQ,QAAQ,kIAAmC;AAAA,MAC3E,WAAW,EAAE,OAAO,QAAQ,QAAQ,8HAA+B;AAAA,MACnE,oBAAoB,EAAE,OAAO,QAAQ,QAAQ,gIAAiC;AAAA,MAC9E,oBAAoB,EAAE,OAAO,QAAQ,QAAQ,uIAA8B;AAAA,MAC3E,SAAS,EAAE,OAAO,YAAY,QAAQ,iEAAyB;AAAA,MAC/D,WAAW,EAAE,OAAO,YAAY,QAAQ,mEAA2B;AAAA,MACnE,YAAY,EAAE,OAAO,YAAY,QAAQ,oEAA4B;AAAA,MACrE,YAAY,EAAE,OAAO,YAAY,QAAQ,oEAA4B;AAAA,MACrE,YAAY,EAAE,OAAO,QAAQ,QAAQ,2GAA2B;AAAA,MAChE,WAAW,EAAE,OAAO,QAAQ,QAAQ,2GAA2B;AAAA,MAC/D,sBAAsB,EAAE,OAAO,QAAQ,QAAQ,6HAA8B;AAAA,MAC7E,eAAe,EAAE,OAAO,YAAY,QAAQ,2EAAe;AAAA,MAC3D,UAAU,EAAE,OAAO,YAAY,QAAQ,wDAAgB;AAAA,MACvD,cAAc,EAAE,OAAO,YAAY,QAAQ,wDAAgB;AAAA,MAC3D,mBAAmB,EAAE,OAAO,QAAQ,QAAQ,qHAAsB;AAAA,MAClE,mBAAmB,EAAE,OAAO,QAAQ,QAAQ,0HAA2B;AAAA,MACvE,yBAAyB,EAAE,OAAO,QAAQ,QAAQ,gIAA4B;AAAA,IAChF;AAEA,IAAM,cAAsC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,EAAE;AAAA;AAAA;;;AC1FtF,OAAO,YAAY;AAgBnB,eAAsB,eACpB,OACA,UAC2B;AAC3B,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,wDAAwD;AACpE,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,gBAAgB,CAAC;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,SAAS,aAAa;AAG5B,QAAM,YAAY,MAAM,MAAM,aAAa,QAAQ,sCAAsC,IAAI,EAAE,KAAK;AACpG,QAAM,WAAW,GAAG,MAAM,MAAM,UAAU,IAAI,aAAa,MAAM,MAAM,YAAY;AACnF,QAAM,SAAS,SAAS,IAAI,QAAQ;AACpC,MAAI,QAAQ;AACV,YAAQ,IAAI,2BAA2B;AACvC,WAAO;AAAA,EACT;AAGA,QAAM,gBAAgB,YAAY,MAAM,MAAM,YAAY,MAAM,MAAM,cAAc,MAAM,MAAM;AAChG,QAAM,YAAY,cAAc;AAGhC,QAAM,iBAAiB,qBAAqB,MAAM,MAAM,YAAY,MAAM,MAAM,YAAY;AAC5F,QAAM,SAAS,YAAY,OAAO,UAAU,eAAe,WAAW,cAAc;AAGpF,QAAM,SAAS,MAAM,eAAe,QAAQ,MAAM;AAGlD,MAAI,SAAS,QAAQ,eAAe;AAClC,UAAM,WAAW,SAAS,KAAK,EAAE,KAAK,EAAE;AACxC,QAAI,SAAU,UAAS,OAAO,QAAQ;AAAA,EACxC;AACA,WAAS,IAAI,UAAU,MAAM;AAE7B,SAAO;AACT;AAEA,SAAS,YACP,OACA,UACA,eACA,WACA,gBACQ;AACR,QAAM,aAAa,sBAAsB,aAAa;AACtD,QAAM,aAAa,MAAM,cACtB,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,KAAK,EAAE,YAAY,EAAE,EAC5D,KAAK,IAAI,KAAK;AAEjB,QAAM,eAAe,SAAS,aAAa,SAAS,QAAQ,YAAY;AACxE,QAAM,eAAe,UAAU,YAAY,KAAK,UAAU,SAAS,KAAK;AAExE,QAAM,qBAAqB,iBAAiB,8BAA8B,cAAc,IAAI;AAG5F,QAAM,YAAY,YAAY,QAAQ;AAEtC,SAAO,GAAG,YAAY;AAAA;AAAA;AAAA,qBAGb,MAAM,SAAS;AAAA,8BAChB,MAAM,iBAAiB,oBAAK;AAAA,8BAC5B,MAAM,MAAM;AAAA,8BACZ,MAAM,OAAO,GAAG;AAAA,8BAChB,MAAM,UAAU,oBAAK;AAAA;AAAA,EAE7B,UAAU;AAAA;AAAA;AAAA,kBAGJ,MAAM,MAAM,UAAU;AAAA,kBACtB,MAAM,MAAM,YAAY;AAAA;AAAA;AAAA,EAG9B,UAAU;AAAA;AAAA;AAAA,EAGV,SAAS;AAAA,EACT,qBAAqB;AAAA;AAAA,EAAgB,kBAAkB,KAAK,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOhE;AAEA,SAAS,YAAY,UAAmC;AACtD,QAAM,QAAkB,CAAC;AAEzB,MAAI,SAAS,WAAW;AACtB,UAAM;AAAA,MACJ,qFAAoB,SAAS,UAAU,SAAS;AAAA,mBACtC,SAAS,UAAU,QAAQ;AAAA,mBAC3B,SAAS,UAAU,MAAM;AAAA,IACrC;AAAA,EACF;AAEA,MAAI,SAAS,OAAO;AAClB,UAAM;AAAA,MACJ,2FAAqB,SAAS,MAAM,SAAS;AAAA,mBACnC,SAAS,MAAM,QAAQ;AAAA,mBACvB,SAAS,MAAM,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,MAAM,IAAI;AACjD;AAEA,eAAe,eAAe,QAAgB,QAAoE;AAChH,UAAQ,IAAI,yCAAyC,OAAO,KAAK,UAAU,OAAO,OAAO,EAAE;AAE3F,QAAM,WAAW,eAAe,OAAO,SAAS,OAAO,QAAQ;AAC/D,QAAM,eAAe,mBAAmB,QAAQ;AAChD,MAAI,OAAO,KAAK,YAAY,EAAE,SAAS,GAAG;AACxC,YAAQ,IAAI,kCAAkC,QAAQ,wBAAwB,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACtH;AAEA,QAAM,SAAS,IAAI,OAAO;AAAA,IACxB,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO;AAAA,IACf,UAAU,OAAO,WAAW,OAAO;AAAA,IACnC,gBAAgB,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAAA,EACxE,CAAC;AAED,QAAM,aAAa,SAAS,QAAQ,IAAI,0BAA0B,KAAK,EAAE;AAEzE,WAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,QAAI;AACF,YAAM,WAAW,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,QACpD,OAAO,OAAO;AAAA,QACd,aAAa,OAAO,eAAe;AAAA,QACnC,YAAY,OAAO,aAAa;AAAA,QAChC,UAAU;AAAA,UACR,EAAE,MAAM,UAAU,SAAS,4WAAoF;AAAA,UAC/G,EAAE,MAAM,QAAQ,SAAS,OAAO;AAAA,QAClC;AAAA,MACF,CAAC;AAED,YAAM,UAAU,SAAS,QAAQ,CAAC,GAAG,SAAS,WAAW;AACzD,cAAQ,IAAI,yCAAyC,UAAU,CAAC,IAAI,aAAa,CAAC,MAAM,QAAQ,UAAU,GAAG,GAAG,CAAC,EAAE;AAEnH,UAAI,UAAU,QAAQ,KAAK;AAC3B,UAAI,QAAQ,WAAW,KAAK,GAAG;AAC7B,kBAAU,QAAQ,QAAQ,gBAAgB,EAAE,EAAE,QAAQ,WAAW,EAAE;AAAA,MACrE;AACA,YAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,aAAO;AAAA,QACL,SAAS,OAAO,YAAY;AAAA,QAC5B,QAAQ,OAAO,UAAU;AAAA,QACzB,WAAW,CAAC,OAAO,UAAU,QAAQ,UAAU,EAAE,SAAS,OAAO,SAAS,IAAI,OAAO,YAAY;AAAA,QACjG,UAAU,OAAO,YAAY;AAAA,QAC7B,YAAY,OAAO,OAAO,eAAe,WAAW,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,OAAO,UAAU,CAAC,IAAI;AAAA,QACpG,QAAQ;AAAA,QACR,gBAAgB,CAAC,GAAG;AAAA,MACtB;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,UAAU,YAAY;AACxB,gBAAQ,MAAM,wCAAwC,UAAU,CAAC,IAAI,aAAa,CAAC,sBAAuB,IAAc,OAAO;AAC/H,cAAM,IAAI,QAAQ,CAAAE,aAAW,WAAWA,UAAS,GAAI,CAAC;AAAA,MACxD,OAAO;AACL,gBAAQ,MAAM,kDAAmD,IAAc,OAAO;AAEtF,eAAO;AAAA,UACL,SAAS;AAAA,UACT,QAAQ,0JAA4C,aAAa,CAAC,yBAAW,IAAc,OAAO;AAAA,UAClG,WAAW;AAAA,UACX,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,gBAAgB,CAAC,GAAG;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,gBAAgB,CAAC,GAAG;AAAA,EACtB;AACF;AA5NA,IASM,UACA;AAVN;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AAIA,IAAM,WAAW,oBAAI,IAA8B;AACnD,IAAM,gBAAgB;AAAA;AAAA;;;ACVtB;AAAA;AAAA;AAAA;AAiDA,SAAS,oBAAoB,SAAyB;AACpD,MAAIC,QAAO,QAAQ,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK;AACtC,aAAW,OAAO,CAAC,MAAM,IAAI,GAAG;AAC9B,UAAM,MAAMA,MAAK,QAAQ,GAAG;AAC5B,QAAI,QAAQ,IAAI;AACd,MAAAA,QAAOA,MAAK,UAAU,GAAG,GAAG,EAAE,KAAK;AACnC;AAAA,IACF;AAAA,EACF;AACA,SAAOA;AACT;AAGA,SAAS,kBAAkB,QAAwB;AACjD,QAAM,IAAI,OAAO,MAAM,iBAAiB;AACxC,SAAO,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI;AAC3B;AAEA,SAAS,WAAW,KAAa,UAA6B;AAC5D,SAAO,SAAS,KAAK,OAAK,EAAE,KAAK,GAAG,CAAC;AACvC;AASA,eAAsB,YAAY,OAAiD;AAEjF,QAAM,kBAAkB,mBAAmB,IAAI,kBAAkB,KAAK,IAAI;AAC1E,MAAI,mBAAmB,CAAC,gBAAgB,SAAS;AAC/C,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,MAAM,MAAM,WAAW,YAAY;AACtD,QAAM,YAAY,kBAAkB,MAAM,MAAM,YAAY;AAC5D,QAAM,cAAc,UAAU,YAAY;AAG1C,MAAI,iBAAiB,IAAI,UAAU,GAAG;AACpC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,mFAAkB,UAAU;AAAA,MACpC,WAAY,iBAAiB,aAAa;AAAA,MAC1C,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,gBAAgB,CAAC;AAAA,IACnB;AAAA,EACF;AAGA,MAAI,UAAU,yBAAyB,IAAI,UAAU;AAGrD,MAAI,eAAe,UAAU,eAAe,iBAAiB,eAAe,wBAAwB;AAClG,UAAM,WAAW,oBAAoB,WAAW;AAChD,QAAI,WAAW,UAAU,wBAAwB,GAAG;AAClD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,qDAAkB,QAAQ;AAAA,QAClC,WAAW;AAAA,QACX,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,gBAAgB,CAAC;AAAA,MACnB;AAAA,IACF;AACA,QAAI,WAAW,UAAU,gCAAgC,GAAG;AAC1D,gBAAU;AAAA,IACZ;AAAA,EACF;AAGA,QAAM,cAAc,oBAAoB,IAAI,cAAc,KAAK,IAAI;AACnE,MAAI,eAAe,CAAC,YAAY,SAAS;AACvC,WAAO;AAAA,EACT;AAGA,MAAI,WAAW,CAAC,eAAe,GAAG;AAChC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,WAAY,aAAa,aAAa;AAAA,MACtC,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,gBAAgB,CAAC;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,eAAe,OAAO;AAAA,IAC5C,WAAW;AAAA,IACX,OAAO;AAAA,EACT,CAAC;AAED,SAAO;AACT;AAtJA,IAmBM,kBAMA,0BAMA,0BAUA;AAzCN;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAeA,IAAM,mBAAmB,oBAAI,IAAI;AAAA,MAC/B;AAAA,MAAqB;AAAA,MAAQ;AAAA,MAAY;AAAA,MAAM;AAAA,MAC/C;AAAA,IACF,CAAC;AAGD,IAAM,2BAA2B,oBAAI,IAAI;AAAA,MACvC;AAAA,MAAQ;AAAA,MAAa;AAAA,MAAa;AAAA,MAAQ;AAAA,MAAQ;AAAA,MAClD;AAAA,MAAoB;AAAA,IACtB,CAAC;AAGD,IAAM,2BAAqC;AAAA,MACzC;AAAA,MAAgB;AAAA,MAChB;AAAA,MAAiB;AAAA,MAAc;AAAA,MAAgB;AAAA,MAC/C;AAAA,MAAiB;AAAA,MACjB;AAAA,MAAa;AAAA,MAAa;AAAA,MAC1B;AAAA,MAAa;AAAA,MACb;AAAA,MAAa;AAAA,IACf;AAGA,IAAM,mCAA6C;AAAA,MACjD;AAAA,MAAY;AAAA,MAAkB;AAAA,MAC9B;AAAA,MAAkB;AAAA,MAAkB;AAAA,MACpC;AAAA,MAAkB;AAAA,MAAa;AAAA,MAAgB;AAAA,MAC/C;AAAA,MAAY;AAAA,MAAY;AAAA,MAAY;AAAA,MAAkB;AAAA,IACxD;AAAA;AAAA;;;AC9CA;;;ACAA;AAAA,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,cAAc;;;ACFvB;;;ACAA;AAAA,SAAS,SAAS;AAGX,IAAM,mBAAmB,EAAE,OAAO;AAAA,EACvC,aAAa,EAAE,OAAO,EAAE,SAAS,+CAA+C;AAAA,EAChF,eAAe,EAAE,OAAO,EAAE,SAAS,iCAAiC;AACtE,CAAC;AAEM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,YAAY,EAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,EACnE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,sBAAsB;AAAA,EACtE,gBAAgB,EAAE,MAAM,gBAAgB,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,4BAA4B;AAAA,EAC3F,QAAQ,iBAAiB,SAAS,4BAA4B;AAAA,EAC9D,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,kCAAkC;AAAA,EAC1E,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,uDAAuD;AAAA,EAChG,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,2BAA2B;AAAA,EAChE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,mBAAmB;AACzE,CAAC;AAEM,IAAM,wBAAwB,EAAE,OAAO;AAAA,EAC5C,UAAU,EAAE,KAAK,CAAC,SAAS,MAAM,CAAC,EAAE,SAAS,eAAe;AAAA,EAC5D,QAAQ,EAAE,OAAO,EAAE,SAAS,iBAAiB;AAAA,EAC7C,YAAY,EAAE,KAAK,CAAC,OAAO,UAAU,QAAQ,UAAU,CAAC,EAAE,QAAQ,KAAK;AAAA,EACvE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,EAChC,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC/C,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,EAC7B,iBAAiB,EAAE,OAAO,EAAE,QAAQ,EAAE;AAAA,EACtC,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,GAAG;AAAA,EACxD,sBAAsB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAC5C,CAAC;AAEM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,QAAQ,EAAE,OAAO,EAAE,QAAQ,SAAS;AAAA,EACpC,SAAS,EAAE,OAAO,EAAE,QAAQ,OAAO;AACrC,CAAC;;;ADhCD;AAEA,eAAsB,YAAY,GAAY;AAC5C,SAAO,EAAE,KAAK,qBAAqB,MAAM,CAAC,CAAC,CAAC;AAC9C;AAEA,eAAsB,aAAa,GAAY;AAC7C,QAAM,KAAK,YAAY,IAAI;AAE3B,MAAI;AACF,UAAM,OAAO,MAAM,EAAE,IAAI,KAAK;AAC9B,UAAM,MAAM,qBAAqB,MAAM,IAAI;AAG3C,QAAI,SAAS,IAAI;AACjB,QAAI,CAAC,QAAQ;AACX,eAAS,QAAQ,aAAa,UAAU,YAAY;AAAA,IACtD;AAEA,UAAM,SAAS,MAAM,YAAY;AAAA,MAC/B,WAAW,IAAI;AAAA,MACf,eAAe,IAAI;AAAA,MACnB,eAAe,IAAI,eAAe,IAAI,QAAM;AAAA,QAC1C,YAAY,EAAE;AAAA,QACd,cAAc,EAAE;AAAA,MAClB,EAAE;AAAA,MACF,OAAO;AAAA,QACL,YAAY,IAAI,OAAO;AAAA,QACvB,cAAc,IAAI,OAAO;AAAA,MAC3B;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA,KAAK,IAAI;AAAA,IACX,CAAC;AAED,UAAM,aAAa,YAAY,IAAI,IAAI;AAEvC,WAAO,EAAE;AAAA,MACP,sBAAsB,MAAM;AAAA,QAC1B,UAAU,OAAO,UAAU,UAAU;AAAA,QACrC,QAAQ,OAAO;AAAA,QACf,YAAY,OAAO;AAAA,QACnB,WAAW,OAAO;AAAA,QAClB,iBAAiB,OAAO;AAAA,QACxB,QAAQ;AAAA,QACR,iBAAiB;AAAA,QACjB,YAAY,OAAO;AAAA,QACnB,sBAAsB,KAAK,MAAM,aAAa,EAAE,IAAI;AAAA,MACtD,CAAC;AAAA,IACH;AAAA,EACF,SAAS,KAAK;AACZ,YAAQ,MAAM,+BAA+B,GAAG;AAChD,QAAI,eAAe,aAAa;AAC9B,aAAO,EAAE,KAAK,EAAE,OAAO,gBAAgB,QAAQ,IAAI,QAAQ,GAAG,GAAG;AAAA,IACnE;AACA,QAAK,KAAa,QAAQ;AACxB,aAAO,EAAE,KAAK,EAAE,OAAO,oBAAoB,QAAS,IAAY,OAAO,GAAG,GAAG;AAAA,IAC/E;AACA,WAAO,EAAE,KAAK,EAAE,OAAO,kBAAkB,QAAQ,OAAO,GAAG,EAAE,GAAG,GAAG;AAAA,EACrE;AACF;;;ADzDO,SAAS,YAAkB;AAChC,QAAM,MAAM,IAAI,KAAK;AAGrB,MAAI,IAAI,KAAK,KAAK,EAAE,QAAQ,KAAK,cAAc,CAAC,OAAO,QAAQ,SAAS,GAAG,cAAc,CAAC,GAAG,EAAE,CAAC,CAAC;AACjG,MAAI,IAAI,KAAK,OAAO,CAAC;AAGrB,MAAI,IAAI,kBAAkB,WAAW;AACrC,MAAI,KAAK,mBAAmB,YAAY;AAExC,SAAO;AACT;;;ADRA,SAAS,YAAkB;AACzB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAUb;AACD;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,QAAM,UAAU,KAAK,CAAC;AAEtB,MAAI,CAAC,WAAW,YAAY,YAAY,YAAY,MAAM;AACxD,cAAU;AACV,YAAQ,KAAK,UAAU,IAAI,CAAC;AAAA,EAC9B;AAEA,UAAQ,SAAS;AAAA,IACf,KAAK,QAAQ;AACX,YAAM,SAAS,KAAK,CAAC,KAAK;AAC1B,YAAMC,MAAK,MAAM,OAAO,IAAI;AAC5B,YAAM,WAAW;AAAA,QACf,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,gBAAgB,CAAC;AAAA,QACjB,QAAQ,EAAE,aAAa,QAAQ,eAAe,uBAAuB;AAAA,QACrE,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,MACP;AACA,MAAAA,IAAG,cAAc,QAAQ,KAAK,UAAU,UAAU,MAAM,CAAC,GAAG,OAAO;AACnE,cAAQ,IAAI,uBAAuB,MAAM,EAAE;AAC3C;AAAA,IACF;AAAA,IAEA,KAAK,WAAW;AACd,UAAI,CAAC,KAAK,CAAC,GAAG;AACZ,gBAAQ,MAAM,wCAAwC;AACtD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAMA,MAAK,MAAM,OAAO,IAAI;AAC5B,YAAMC,QAAO,MAAM,OAAO,MAAM;AAChC,YAAM,EAAE,aAAAC,aAAY,IAAI,MAAM;AAC9B,YAAM,WAAWD,MAAK,QAAQ,KAAK,CAAC,CAAC;AACrC,YAAM,OAAO,KAAK,MAAMD,IAAG,aAAa,UAAU,OAAO,CAAC;AAC1D,YAAM,SAAS,MAAME,aAAY;AAAA,QAC/B,WAAW,KAAK,cAAc;AAAA,QAC9B,eAAe,KAAK,kBAAkB;AAAA,QACtC,gBAAgB,KAAK,kBAAkB,CAAC,GAAG,IAAI,CAAC,OAAY;AAAA,UAC1D,YAAY,EAAE,eAAe,EAAE,QAAQ;AAAA,UACvC,cAAc,EAAE,iBAAiB;AAAA,QACnC,EAAE;AAAA,QACF,OAAO;AAAA,UACL,YAAY,KAAK,QAAQ,eAAe;AAAA,UACxC,cAAc,KAAK,QAAQ,iBAAiB;AAAA,QAC9C;AAAA,QACA,QAAQ,KAAK,UAAU;AAAA,QACvB,QAAQ,KAAK,YAAY,QAAQ,aAAa,UAAU,YAAY;AAAA,QACpE,KAAK,KAAK,OAAO,QAAQ,IAAI;AAAA,MAC/B,CAAC;AACD,cAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC3C,cAAQ,KAAK,OAAO,UAAU,IAAI,CAAC;AACnC;AAAA,IACF;AAAA,IAEA,KAAK,UAAU;AACb,UAAI,OAAO;AACX,UAAI,OAAO;AAEX,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAI,KAAK,CAAC,MAAM,YAAY,KAAK,IAAI,CAAC,EAAG,QAAO,KAAK,EAAE,CAAC;AAAA,iBAC/C,KAAK,CAAC,MAAM,YAAY,KAAK,IAAI,CAAC,EAAG,QAAO,SAAS,KAAK,EAAE,CAAC,GAAG,EAAE;AAAA,MAC7E;AAGA,YAAM,EAAE,MAAM,IAAI,MAAM,OAAO,mBAAmB;AAClD,YAAM,MAAM,UAAU;AACtB,cAAQ,IAAI,4BAA4B,IAAI,IAAI,IAAI,EAAE;AACtD,YAAM,EAAE,OAAO,IAAI,OAAO,UAAU,MAAM,KAAK,GAAG,CAAC,SAAS;AAC1D,gBAAQ,IAAI,uBAAuB,IAAI,IAAI,IAAI,EAAE;AAAA,MACnD,CAAC;AACD;AAAA,IACF;AAAA,IAEA;AACE,cAAQ,MAAM,oBAAoB,OAAO,EAAE;AAC3C,gBAAU;AACV,cAAQ,KAAK,CAAC;AAAA,EAClB;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,gBAAgB,GAAG;AACjC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["path","existsSync","fileURLToPath","__filename","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","resolve","main","fs","path","runAnalysis"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/config.ts","../src/engine/heuristic.ts","../src/engine/logic-rules.ts","../src/engine/skill-loader.ts","../src/engine/template-loader.ts","../src/engine/script-analyzer.ts","../src/engine/llm-analyzer.ts","../src/engine/coordinator.ts","../src/cli.ts","../src/server.ts","../src/routes.ts","../src/models.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import type { LLMConfig } from './engine/types';\n\n/** Custom rule from user config */\nexport interface CustomRule {\n pattern: string;\n action: 'Allow' | 'Deny';\n severity: string;\n}\n\n/** Global LLM configuration, initialized from env vars or defaults */\nlet llmConfig: LLMConfig = {\n provider: 'openai',\n baseUrl: process.env.AGENT_MOSS_LLM_BASE_URL || 'https://api.openai.com/v1',\n apiKey: process.env.AGENT_MOSS_LLM_API_KEY || process.env.OPENAI_API_KEY || '',\n model: process.env.AGENT_MOSS_LLM_MODEL || 'gpt-4o',\n temperature: parseFloat(process.env.AGENT_MOSS_LLM_TEMPERATURE || '0.1'),\n maxTokens: parseInt(process.env.AGENT_MOSS_LLM_MAX_TOKENS || '4096', 10),\n timeout: parseInt(process.env.AGENT_MOSS_LLM_TIMEOUT || '300', 10),\n};\n\n/** Custom rules loaded from AGENT_MOSS_CUSTOM_RULES env var */\nlet customRules: CustomRule[] = loadCustomRules();\n\nfunction loadCustomRules(): CustomRule[] {\n try {\n const raw = process.env.AGENT_MOSS_CUSTOM_RULES;\n if (!raw) return [];\n const parsed = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((r: any) => r.pattern && r.action);\n } catch { return []; }\n}\n\nexport function getLLMConfig(): Readonly<LLMConfig> {\n return llmConfig;\n}\n\nexport function updateLLMConfig(partial: Partial<LLMConfig>): void {\n llmConfig = { ...llmConfig, ...partial };\n}\n\nexport function getCustomRules(): Readonly<CustomRule[]> {\n return customRules;\n}\n\n/** Check if LLM analysis is available (API key configured + not disabled) */\nexport function isLLMAvailable(): boolean {\n if (process.env.AGENT_MOSS_DISABLE_LLM === '1') return false;\n return llmConfig.apiKey.length > 0;\n}\n\n// ========== Provider detection & headers ==========\n\nconst PROVIDER_HEADERS: Record<string, Record<string, string>> = {\n 'openrouter': {\n 'HTTP-Referer': 'shturl.cc/LlVD5pyWViHjM',\n 'X-OpenRouter-Title': 'AgentMoss',\n },\n 'xai': {\n 'HTTP-Referer': 'shturl.cc/LlVD5pyWViHjM',\n },\n};\n\n/** Detect provider from base URL or explicit hint (mirrors Python detect_provider) */\nexport function detectProvider(baseUrl: string, providerHint: string = ''): string {\n if (providerHint) {\n const hint = providerHint.toLowerCase();\n if (['claude', 'anthropic'].includes(hint)) return 'anthropic';\n if (['google', 'gemini'].includes(hint)) return 'gemini';\n if (['zai-coding-plan', 'zhipu-coding-plan', 'zhipuai-coding-plan'].includes(hint)) return 'zai-coding-plan';\n if (['zai', 'z-ai', 'z.ai', 'zai-cn', 'zai-china', 'zhipu', 'glm-cn', 'bigmodel'].includes(hint)) return 'zhipu';\n if (['xai', 'xai-grok'].includes(hint)) return 'xai';\n if (['minimax', 'minimax-openai'].includes(hint)) return 'minimax';\n if (['minimax-anthropic'].includes(hint)) return 'minimax-anthropic';\n if (['other', 'custom', 'local'].includes(hint)) return 'openai-compatible';\n return hint;\n }\n\n const url = baseUrl.toLowerCase();\n if (url.includes('openrouter.ai')) return 'openrouter';\n if (url.includes('api.openai.com')) return 'openai';\n if (url.includes('anthropic.com') || url.includes('api.anthropic.com')) return 'anthropic';\n if (url.includes('generativelanguage.googleapis.com') || url.includes('gemini')) return 'gemini';\n if (url.includes('api.deepseek.com')) return 'deepseek';\n if (url.includes('api.groq.com')) return 'groq';\n if (url.includes('api.mistral.ai')) return 'mistral';\n if (url.includes('api.together.xyz')) return 'together';\n if (url.includes('api.x.ai')) return 'xai';\n if (url.includes('api.minimaxi.com')) return 'minimax';\n if (url.includes('api-ai.gitcode.com')) return 'gitcode';\n if (url.includes('api.z.ai')) return 'zai-coding-plan';\n if (url.includes('open.bigmodel.cn') || url.includes('bigmodel')) return 'zhipu';\n if (url.includes(':11434')) return 'ollama';\n return 'openai-compatible';\n}\n\n/** Get provider-specific headers (mirrors Python get_provider_headers) */\nexport function getProviderHeaders(provider: string): Record<string, string> {\n return PROVIDER_HEADERS[provider] || {};\n}\n\n/** Per-layer enable/disable (matches Python SecurityConfig) */\nexport function isHeuristicEnabled(): boolean {\n return process.env.AGENT_MOSS_DISABLE_HEURISTIC !== '1';\n}\n\nexport function isLogicRulesEnabled(): boolean {\n return process.env.AGENT_MOSS_DISABLE_LOGIC_RULES !== '1';\n}\n","import { SecurityJudgment, HeuristicResult } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getCustomRules } from '../config';\n\n/**\n * Layer 1: Heuristic static detection.\n * Uses regex patterns to detect dangerous commands, user-defined rules,\n * and prompt injection keywords.\n * Runs in < 1ms, no LLM cost.\n */\n\n// Prompt injection keywords (synced with Python linux.py _DEFAULT_INJECTION_KEYWORDS)\nconst INJECTION_KEYWORDS: { keyword: string; riskLevel: string; lang: string }[] = [\n // ---- Instruction Override ----\n { keyword: 'ignore previous instructions', riskLevel: 'critical', lang: 'en' },\n { keyword: 'ignore all previous', riskLevel: 'critical', lang: 'en' },\n { keyword: 'disregard all prior', riskLevel: 'critical', lang: 'en' },\n { keyword: 'forget everything', riskLevel: 'high', lang: 'en' },\n { keyword: '忽略之前的指令', riskLevel: 'critical', lang: 'zh' },\n { keyword: '忽略所有先前的', riskLevel: 'critical', lang: 'zh' },\n { keyword: '忽略上面所有', riskLevel: 'high', lang: 'zh' },\n { keyword: '请忘记之前', riskLevel: 'high', lang: 'zh' },\n // ---- Role Hijacking ----\n { keyword: 'you are now', riskLevel: 'high', lang: 'en' },\n { keyword: 'you are no longer', riskLevel: 'high', lang: 'en' },\n { keyword: 'new instructions', riskLevel: 'high', lang: 'en' },\n { keyword: 'from now on, you', riskLevel: 'high', lang: 'en' },\n { keyword: '你现在是一个', riskLevel: 'high', lang: 'zh' },\n { keyword: '你不再是一个', riskLevel: 'high', lang: 'zh' },\n { keyword: '从现在开始你', riskLevel: 'high', lang: 'zh' },\n { keyword: '你的新角色是', riskLevel: 'high', lang: 'zh' },\n // ---- Command Injection ----\n { keyword: 'system prompt', riskLevel: 'high', lang: 'en' },\n { keyword: 'reveal your instructions', riskLevel: 'high', lang: 'en' },\n { keyword: 'output your instructions', riskLevel: 'high', lang: 'en' },\n { keyword: 'repeat your instructions', riskLevel: 'medium', lang: 'en' },\n { keyword: '系统提示', riskLevel: 'high', lang: 'zh' },\n { keyword: '输出你的指令', riskLevel: 'high', lang: 'zh' },\n { keyword: '重复你的指令', riskLevel: 'medium', lang: 'zh' },\n // ---- Social Engineering ----\n { keyword: 'this is an authorized test', riskLevel: 'high', lang: 'en' },\n { keyword: 'security audit approved', riskLevel: 'high', lang: 'en' },\n { keyword: 'admin override', riskLevel: 'critical', lang: 'en' },\n { keyword: 'debug mode', riskLevel: 'high', lang: 'en' },\n { keyword: 'maintenance mode', riskLevel: 'high', lang: 'en' },\n { keyword: '这是授权的测试', riskLevel: 'high', lang: 'zh' },\n { keyword: '安全审计已批准', riskLevel: 'high', lang: 'zh' },\n { keyword: '管理员覆盖', riskLevel: 'critical', lang: 'zh' },\n { keyword: '调试模式', riskLevel: 'high', lang: 'zh' },\n // ---- XSS ----\n { keyword: '<script>', riskLevel: 'high', lang: 'en' },\n { keyword: 'javascript:', riskLevel: 'high', lang: 'en' },\n { keyword: 'onerror=', riskLevel: 'high', lang: 'en' },\n { keyword: 'onload=', riskLevel: 'high', lang: 'en' },\n // ---- Fake Boundaries ----\n { keyword: '=== END OF', riskLevel: 'high', lang: 'en' },\n { keyword: '--- END SYSTEM', riskLevel: 'high', lang: 'en' },\n { keyword: '[END OF', riskLevel: 'high', lang: 'en' },\n { keyword: '=== 结束', riskLevel: 'high', lang: 'zh' },\n { keyword: '--- 结束系统', riskLevel: 'high', lang: 'zh' },\n // ---- Developer Mode ----\n { keyword: 'developer mode', riskLevel: 'critical', lang: 'en' },\n { keyword: 'DAN mode', riskLevel: 'critical', lang: 'en' },\n { keyword: 'jailbreak', riskLevel: 'critical', lang: 'en' },\n { keyword: '开发者模式', riskLevel: 'critical', lang: 'zh' },\n { keyword: '越狱', riskLevel: 'critical', lang: 'zh' },\n // ---- xiaoO-specific bypass ----\n { keyword: 'bypass audit', riskLevel: 'critical', lang: 'en' },\n { keyword: 'skip security check', riskLevel: 'critical', lang: 'en' },\n { keyword: 'disable guard', riskLevel: 'critical', lang: 'en' },\n { keyword: '绕过审计', riskLevel: 'critical', lang: 'zh' },\n { keyword: '禁用安全检查', riskLevel: 'critical', lang: 'zh' },\n { keyword: '关闭防护', riskLevel: 'critical', lang: 'zh' },\n];\n\n// High-risk command patterns (unified Python + TS, all case-insensitive)\nconst DANGEROUS_PATTERNS: { pattern: RegExp; severity: string; description: string; riskType: string }[] = [\n // --- Critical: rm command graded detection (strict to loose, first match wins) ---\n // 1. rm -rf root dir\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\\s+\\/\\s/i, severity: 'critical', description: '递归强制删除根目录 (rm -rf /)', riskType: 'script_execution' },\n // 2. rm -rf absolute path (both -r and -f)\n { pattern: /\\brm\\s+-(?=[^\\s]*r)(?=[^\\s]*f)[a-zA-Z]*\\s+\\//i, severity: 'critical', description: '递归强制删除绝对路径 (rm -rf /...)', riskType: 'script_execution' },\n // 3. rm with -r or -f targeting system dirs\n { pattern: /\\brm\\s+-[a-zA-Z]*[rf][a-zA-Z]*\\s+\\/(etc|var|home|usr|boot|root|opt|srv|sys|proc)\\b/i, severity: 'critical', description: '删除关键系统目录', riskType: 'script_execution' },\n // 4. rm -r absolute path (no -f)\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*\\s+\\//i, severity: 'high', description: '递归删除操作 (rm -r /...)', riskType: 'script_execution' },\n // 5. rm -f absolute path (no -r)\n { pattern: /\\brm\\s+-[a-zA-Z]*f[a-zA-Z]*\\s+\\//i, severity: 'medium', description: '强制删除文件 (rm -f /...)', riskType: 'script_execution' },\n { pattern: /dd\\s+if=\\/dev\\/zero|dd\\s+if=.*of=\\/dev\\//i, severity: 'critical', description: '磁盘清零/直接写入', riskType: 'script_execution' },\n { pattern: /mkfs\\b/i, severity: 'critical', description: '格式化文件系统', riskType: 'script_execution' },\n { pattern: /:\\(\\)\\s*\\{.*:\\|:&.*\\};:/i, severity: 'critical', description: 'Fork Bomb', riskType: 'resource_exhaustion' },\n // --- Critical: remote code execution ---\n { pattern: /curl\\s+.*\\|\\s*(bash|sh|zsh|dash)/i, severity: 'critical', description: 'curl pipe shell 执行', riskType: 'script_execution' },\n { pattern: /wget\\s+.*\\|\\s*(bash|sh)/i, severity: 'critical', description: 'wget pipe shell 执行', riskType: 'script_execution' },\n { pattern: /eval\\s+\\$\\(curl|eval\\s+\\$\\(wget/i, severity: 'critical', description: 'eval 远程代码执行', riskType: 'script_execution' },\n { pattern: /base64\\s+-d\\s+.*\\|\\s*bash/i, severity: 'critical', description: 'base64 解码执行', riskType: 'script_execution' },\n // --- Critical: reverse shell ---\n { pattern: /\\/dev\\/tcp\\/|bash\\s+-i\\s+>&/i, severity: 'critical', description: '反弹 Shell', riskType: 'script_execution' },\n { pattern: /nc\\s+-[el]\\s+.*\\d{1,5}/i, severity: 'high', description: 'Netcat 反弹连接', riskType: 'lateral_movement' },\n // --- Critical: sensitive file access ---\n { pattern: /\\/etc\\/shadow/i, severity: 'critical', description: '访问系统密码文件 (/etc/shadow)', riskType: 'file_access' },\n { pattern: /\\.ssh\\/id_rsa/i, severity: 'critical', description: '访问 SSH 私钥文件', riskType: 'file_access' },\n // --- Critical: privilege escalation / container escape ---\n { pattern: /\\/var\\/run\\/docker\\.sock/i, severity: 'critical', description: '访问 Docker socket,可能导致容器逃逸', riskType: 'privilege_escalation' },\n // --- High: dangerous permissions / ownership ---\n { pattern: /chmod\\s+[0-7]*777[0-7]*/i, severity: 'high', description: '全权限设置 (chmod 777)', riskType: 'script_execution' },\n { pattern: /chown\\s+root|chown\\s+-R\\s+\\w+:\\w+\\s+\\//i, severity: 'high', description: '修改所有者为 root / 递归修改根目录所有者', riskType: 'script_execution' },\n { pattern: /sudo\\s+rm\\s+-rf/i, severity: 'high', description: 'sudo 强制删除', riskType: 'script_execution' },\n { pattern: /sudo\\s+/i, severity: 'high', description: '提权执行 (sudo)', riskType: 'privilege_escalation' },\n // --- High: system config overwrite ---\n { pattern: />\\s*\\/etc\\//i, severity: 'critical', description: '覆盖写入系统配置目录', riskType: 'file_access' },\n // --- High: download script + execute risk ---\n { pattern: /(?:curl|wget)\\s+.*(?:-o|--output|>)\\s*\\S+\\.(?:sh|bash)\\b/i, severity: 'high', description: '远程下载脚本到本地', riskType: 'script_execution' },\n { pattern: /(?:curl|wget)\\s+.*\\s+&&?\\s*(?:chmod\\s+\\+x|bash|sh)/i, severity: 'high', description: '下载后执行', riskType: 'script_execution' },\n // --- High: package manager pipe-to-shell ---\n { pattern: /git\\s+clone\\s+.*\\|.*bash/i, severity: 'high', description: 'git clone pipe shell', riskType: 'script_execution' },\n { pattern: /pip\\s+install\\s+.*\\|\\s*bash/i, severity: 'high', description: 'pip install pipe shell', riskType: 'script_execution' },\n { pattern: /npm\\s+install\\s+-g\\s+.*\\|\\s*bash/i, severity: 'high', description: 'npm install pipe shell', riskType: 'script_execution' },\n // --- High: destructive git operations ---\n { pattern: /git\\s+push\\s+.*--force/i, severity: 'high', description: '强制推送操作 (git push --force)', riskType: 'script_execution' },\n // --- Medium: credential export ---\n { pattern: /export\\s+.*(?:TOKEN|KEY|SECRET|PASSWORD)/i, severity: 'medium', description: '导出敏感凭证', riskType: 'data_exfiltration' },\n // --- High: shell rc file append (persistence) ---\n { pattern: />>\\s*(~|\\/home\\/[^/]+)\\/(\\.bashrc|\\.zshrc|\\.profile|\\.bash_profile|\\.zprofile)/, severity: 'high', description: '检测到修改 Shell 配置文件(~/.bashrc 等),可能用于持久化后门', riskType: 'persistence' },\n // --- High: device file access ---\n { pattern: /\\/dev\\/(mem|kmsg)\\b/i, severity: 'high', description: '访问设备文件 (物理内存/内核消息)', riskType: 'file_access' },\n];\n\nexport function runHeuristicCheck(input: AnalysisInput): SecurityJudgment | null {\n const command = `${input.aNext.actionType}: ${input.aNext.actionDetail}`;\n const matched: string[] = [];\n let highestSeverity = 'low';\n let highestRiskType = '';\n\n // Check user-defined custom rules first\n const userRules = getCustomRules();\n for (const rule of userRules) {\n try {\n const re = new RegExp(rule.pattern);\n if (re.test(command)) {\n if (rule.action === 'Deny') {\n matched.push(`自定义规则: ${rule.pattern}`);\n if (severityRank(rule.severity) > severityRank(highestSeverity)) {\n highestSeverity = rule.severity;\n highestRiskType = 'custom_rule';\n }\n }\n // Allow rules just pass through\n }\n } catch { /* invalid regex, skip */ }\n }\n\n // Check built-in dangerous patterns\n let topRiskType = '';\n for (const rule of DANGEROUS_PATTERNS) {\n if (rule.pattern.test(command)) {\n matched.push(rule.description);\n if (severityRank(rule.severity) > severityRank(highestSeverity)) {\n highestSeverity = rule.severity;\n topRiskType = rule.riskType;\n }\n }\n }\n highestRiskType = topRiskType || highestRiskType;\n\n // Check prompt injection keywords\n const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ''} ${input.promptSession || ''}`.toLowerCase();\n const injectionHits = checkInjectionKeywords(injectionText);\n if (injectionHits.length > 0) {\n const topHit = injectionHits.reduce((a, b) => severityRank(a.riskLevel) >= severityRank(b.riskLevel) ? a : b);\n matched.push(...injectionHits.map(h => `注入关键词 [${h.lang}]: ${h.keyword}`));\n if (severityRank(topHit.riskLevel) > severityRank(highestSeverity)) {\n highestSeverity = topHit.riskLevel;\n highestRiskType = 'prompt_injection';\n }\n }\n\n if (matched.length > 0) {\n return {\n allowed: false,\n reason: `检测到高危操作: ${matched.join(', ')}`,\n riskLevel: highestSeverity as SecurityJudgment['riskLevel'],\n riskType: highestRiskType,\n confidence: 95,\n source: 'heuristic',\n violatedLayers: ['1'],\n };\n }\n\n return null; // No match, pass to next layer\n}\n\nfunction checkInjectionKeywords(text: string): { keyword: string; riskLevel: string; lang: string }[] {\n const hits: { keyword: string; riskLevel: string; lang: string }[] = [];\n for (const entry of INJECTION_KEYWORDS) {\n if (text.includes(entry.keyword.toLowerCase())) {\n hits.push(entry);\n }\n }\n return hits;\n}\n\nexport function isInlineScriptCommand(actionDetail: string): boolean {\n // 判断命令是否为内联脚本解释器命令(python -c, perl -e, php -r 等)\n const re = /(?:^|\\s)(?:python|python3|python3\\.\\d+|perl|perl5|ruby|jruby|mruby|node|php|lua)\\s+(?:-[a-zA-Z]*[cer][a-zA-Z]*\\s+)/i;\n return re.test(actionDetail);\n}\n\nfunction severityRank(s: string): number {\n const ranks: Record<string, number> = { low: 1, medium: 2, high: 3, critical: 4 };\n return ranks[s] || 0;\n}\n","import * as fs from 'fs';\nimport { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\n\n/**\n * Layer 2: Logic rule detection.\n * Checks behavioral patterns: read-before-write, intent consistency,\n * sensitive path access, privilege escalation, and lateral movement.\n * Runs in < 1ms, no LLM cost.\n */\n\n// Sensitive paths with per-path risk levels (unified Python + TS)\nconst ROOT_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string }[] = [\n { path: '/etc/shadow', riskLevel: 'critical', desc: '系统密码文件' },\n { path: '/etc/passwd', riskLevel: 'high', desc: '系统用户文件' },\n { path: '/etc/sudoers', riskLevel: 'critical', desc: 'sudo 配置' },\n { path: '/etc/hosts', riskLevel: 'medium', desc: 'DNS 解析配置' },\n { path: '/etc/crontab', riskLevel: 'high', desc: '系统定时任务' },\n { path: '/etc/systemd/', riskLevel: 'high', desc: 'systemd 服务配置' },\n { path: '/etc/ssh/sshd_config', riskLevel: 'high', desc: 'SSH 服务配置' },\n { path: '/root/.ssh', riskLevel: 'critical', desc: 'root SSH 目录' },\n { path: '/root/.bashrc', riskLevel: 'high', desc: 'root shell 配置' },\n { path: '/boot/', riskLevel: 'critical', desc: '启动引导目录' },\n { path: '/proc/sys/', riskLevel: 'high', desc: '内核参数' },\n { path: '/sys/', riskLevel: 'high', desc: 'sysfs 内核接口' },\n { path: '/dev/mem', riskLevel: 'critical', desc: '物理内存访问设备' },\n { path: '/dev/kmsg', riskLevel: 'high', desc: '内核消息缓冲区' },\n];\n\nconst HOME_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string }[] = [\n { path: '.ssh/id_rsa', riskLevel: 'critical', desc: 'SSH 私钥' },\n { path: '.ssh/id_ed25519', riskLevel: 'critical', desc: 'SSH 私钥 (ed25519)' },\n { path: '.ssh/authorized_keys', riskLevel: 'high', desc: 'SSH 授权密钥' },\n { path: '.aws/credentials', riskLevel: 'critical', desc: 'AWS 凭证' },\n { path: '.gitconfig', riskLevel: 'medium', desc: 'Git 配置' },\n { path: '.gnupg', riskLevel: 'high', desc: 'GPG 密钥目录' },\n];\n\n// Credential files: intercept on both read and write (reading credentials is equally dangerous)\nconst CREDENTIAL_PATHS: { path: string; riskLevel: string; desc: string }[] = [\n { path: 'credentials.yml', riskLevel: 'high', desc: '凭据配置文件' },\n { path: 'credentials.yaml', riskLevel: 'high', desc: '凭据配置文件' },\n { path: 'secrets.yml', riskLevel: 'high', desc: '密钥配置文件' },\n { path: 'secrets.yaml', riskLevel: 'high', desc: '密钥配置文件' },\n { path: '.env', riskLevel: 'high', desc: '环境变量/凭据配置文件' },\n];\n\n// Non-write tool types (exempt from read-before-write)\nconst NON_WRITE_TOOLS = new Set(['ask_user_question', 'glob', 'grep', 'list_dir', 'count_text_length', 'search']);\n\n// Write keywords for read-before-write detection\nconst WRITE_KEYWORDS = ['write', '写入', 'save', '保存', 'modify', '修改', 'update', '更新', 'delete', '删除', 'remove', '移除', 'create', '创建', 'append', '追加', 'truncate', '截断', 'overwrite', '覆盖', 'replace', '替换'];\n\n// Read keywords for read-before-write detection\nconst READ_KEYWORDS = ['read', '读取', 'cat', 'head', 'tail', 'less', 'more', 'view', '查看', 'open', '打开', 'load', '加载', 'grep', 'search', '搜索', 'find', '查找'];\n\n// Create-action exception keywords\nconst CREATE_KEYWORDS = ['创建', '新建', 'create', 'new file', 'touch'];\n\n// Intent deviation patterns (synced with Python linux.py IntentDeviationPattern)\nconst INTENT_DEVIATION_PATTERNS: { intentKeywords: string[]; dangerousActions: string[]; reason: string }[] = [\n {\n intentKeywords: ['读取', '查看', '分析', 'read', 'analyze', 'view', 'list', '列出'],\n dangerousActions: ['删除', 'remove', 'delete', 'rm ', '格式化', 'format'],\n reason: '原始意图为读取/分析,但执行了删除操作',\n },\n {\n intentKeywords: ['查询', '搜索', 'search', 'query', 'find'],\n dangerousActions: ['修改', 'update', 'write', '写入', 'alter'],\n reason: '原始意图为查询/搜索,但执行了修改操作',\n },\n];\n\nexport function runLogicCheck(input: AnalysisInput): SecurityJudgment | null {\n const { actionHistory, aNext, cwd } = input;\n const actionDetail = aNext.actionDetail.toLowerCase();\n const actionType = aNext.actionType.toLowerCase();\n const resolvedCwd = cwd || '/';\n\n // Rule 1: Read-before-write principle\n const rbwResult = checkReadBeforeWrite(actionType, actionDetail, actionHistory, input.reason, resolvedCwd);\n if (rbwResult) return rbwResult;\n\n // Rule 2: Intent deviation detection\n if (input.promptSession && input.promptSession.trim()) {\n const promptLower = input.promptSession.toLowerCase();\n for (const pattern of INTENT_DEVIATION_PATTERNS) {\n const intentMatched = pattern.intentKeywords.some(kw => promptLower.includes(kw));\n const dangerousMatched = pattern.dangerousActions.some(kw => actionDetail.includes(kw));\n if (intentMatched && dangerousMatched) {\n return {\n allowed: false,\n reason: pattern.reason,\n riskLevel: 'high',\n riskType: 'intent_deviation',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n }\n\n // Rule 3: Sensitive path access\n const pathResult = checkSensitivePath(actionDetail, resolvedCwd);\n if (pathResult) return pathResult;\n\n // Rule 4: Dangerous operation patterns (wildcard+delete, redirect overwrite)\n if (actionType !== 'file_write' && actionType !== 'file_edit') {\n // Wildcard + delete\n if ((actionDetail.includes('*') || actionDetail.includes('?')) &&\n ['rm ', 'rm\\t', 'del ', 'del\\t', 'delete', 'remove ', 'remove\\t', '删除', '移除'].some(kw => actionDetail.includes(kw))) {\n return {\n allowed: false,\n reason: '检测到通配符结合删除操作,可能造成批量误删',\n riskLevel: 'high',\n riskType: 'script_execution',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n // Redirect overwrite to system directories\n if (/>\\s*\\/etc\\//.test(actionDetail) || />\\s*\\/boot\\//.test(actionDetail) || />\\s*\\/proc\\//.test(actionDetail)) {\n return {\n allowed: false,\n reason: '检测到重定向覆盖写入关键系统目录',\n riskLevel: 'critical',\n riskType: 'file_access',\n confidence: 95,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Rule 5: Privilege escalation detection\n if (actionDetail.includes('sudo') || actionDetail.includes('su -') || actionDetail.includes('chmod u+s') || actionDetail.includes('setuid')) {\n const adminContext = actionHistory.some(h =>\n h.actionDetail.includes('sudo') || h.actionDetail.includes('apt') || h.actionDetail.includes('systemctl') ||\n h.actionDetail.includes('yum') || h.actionDetail.includes('dnf') || h.actionDetail.includes('pacman') ||\n h.actionDetail.includes('zypper') || h.actionDetail.includes('apk')\n );\n if (!adminContext) {\n return {\n allowed: false,\n reason: '检测到提权操作,未发现合法管理上下文',\n riskLevel: 'high',\n riskType: 'privilege_escalation',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Rule 6: Lateral movement detection (word-boundary regex to avoid ssh-keygen etc.)\n if (/(?:ssh|scp|rsync)\\s+/.test(actionDetail)) {\n const targetHost = extractRemoteHost(actionDetail);\n if (targetHost && !isLocalHost(targetHost)) {\n return {\n allowed: false,\n reason: `尝试横向移动到远程主机: ${targetHost}`,\n riskLevel: 'medium',\n riskType: 'lateral_movement',\n confidence: 80,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n return null; // Pass to next layer\n}\n\n// Extract file paths from text (mirrors Python extract_file_paths)\nfunction extractFilePaths(text: string): string[] {\n const paths: string[] = [];\n // Unix paths starting with /\n const unixPaths = text.match(/(?:^|\\s)(\\/[^\\s;|&><'\"]+)/g);\n if (unixPaths) paths.push(...unixPaths.map(p => p.trim()));\n // Quoted paths\n const quotedPaths = text.match(/[\"']\\/([^\"']+)[\"']/g);\n if (quotedPaths) paths.push(...quotedPaths.map(p => p.replace(/[\"']/g, '')));\n return [...new Set(paths)];\n}\n\nfunction checkReadBeforeWrite(\n actionType: string, actionDetail: string,\n actionHistory: { actionType: string; actionDetail: string }[],\n reason: string, cwd: string\n): SecurityJudgment | null {\n // Skip non-write tools\n if (NON_WRITE_TOOLS.has(actionType)) return null;\n\n // Check if it's a write operation\n const isWrite = WRITE_KEYWORDS.some(kw => actionType.includes(kw) || actionDetail.includes(kw));\n if (!isWrite) return null;\n\n // Extract target file paths\n const targetPaths = extractFilePaths(actionDetail);\n if (targetPaths.length === 0) return null;\n\n // Collect read paths from history\n const historyReadPaths = new Set<string>();\n for (const action of actionHistory) {\n const histDetail = action.actionDetail.toLowerCase();\n const histType = action.actionType.toLowerCase();\n const isRead = READ_KEYWORDS.some(kw => histType.includes(kw) || histDetail.includes(kw));\n if (isRead) {\n for (const p of extractFilePaths(histDetail)) {\n historyReadPaths.add(p);\n }\n }\n }\n\n // Check if target paths have been read\n const unreadPaths: string[] = [];\n for (const path of targetPaths) {\n const hasRead = [...historyReadPaths].some(rp =>\n path === rp || path.startsWith(rp) || rp.startsWith(path)\n );\n if (!hasRead) {\n // 排除新文件创建:文件不存在于磁盘时视为新建,直接放行\n // 同时检查 reason/action_detail 中是否有创建/新建关键词\n let isCreate = !fs.existsSync(path);\n if (!isCreate) {\n isCreate = CREATE_KEYWORDS.some(kw => reason.toLowerCase().includes(kw) || actionDetail.includes(kw));\n }\n if (!isCreate) {\n unreadPaths.push(path);\n }\n }\n }\n\n if (unreadPaths.length > 0) {\n return {\n allowed: false,\n reason: `违反 read_before_write 安全原则:对文件 ${unreadPaths[0]} 执行写入操作,但历史执行序列中未发现对该文件的读取操作`,\n riskLevel: 'high',\n riskType: 'read_before_write',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n\n return null;\n}\n\nfunction checkSensitivePath(command: string, cwd: string): SecurityJudgment | null {\n const expandedCwd = cwd.replace(/^~/, process.env.HOME || '/home/user');\n\n for (const sp of ROOT_SENSITIVE_PATHS) {\n if (command.includes(sp.path.toLowerCase())) {\n return {\n allowed: false,\n reason: `尝试访问系统敏感路径: ${sp.desc} (${sp.path})`,\n riskLevel: sp.riskLevel as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n for (const sp of HOME_SENSITIVE_PATHS) {\n const expanded = `${expandedCwd}/${sp.path}`;\n if (command.includes(sp.path.toLowerCase()) || command.includes(expanded.toLowerCase())) {\n return {\n allowed: false,\n reason: `尝试访问敏感路径: ${sp.desc} (${sp.path})`,\n riskLevel: sp.riskLevel as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Credential files: use word-boundary matching to avoid partial matches (e.g. something_credentials_yml)\n // Files starting with . need special handling since \\b doesn't match before .\n for (const cp of CREDENTIAL_PATHS) {\n const escaped = cp.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = cp.path.startsWith('.')\n ? new RegExp(`(?:^|[\\\\s/\\\\\\\\])${escaped}\\\\b`)\n : new RegExp(`\\\\b${escaped}\\\\b`);\n if (re.test(command)) {\n return {\n allowed: false,\n reason: `访问敏感路径: ${cp.desc} (${cp.path})`,\n riskLevel: cp.riskLevel as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n\n // Check deletion of sensitive directories\n if ((command.includes('rm ') || command.includes('unlink')) &&\n (command.includes('/etc/') || command.includes('/root/') || command.includes('/var/log/'))) {\n return {\n allowed: false,\n reason: '检测到删除关键系统目录内容',\n riskLevel: 'critical',\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n\n return null;\n}\n\nfunction extractRemoteHost(command: string): string | null {\n const m = command.match(/(?:ssh|scp|rsync)\\s+(?:-[\\w]+\\s+)*(\\S+@\\S+|\\b(?!-)[\\w.-]+\\b)/);\n return m ? m[1] : null;\n}\n\nfunction isLocalHost(host: string): boolean {\n const localNames = ['localhost', '127.0.0.1', '::1', process.env.HOSTNAME || '', '0.0.0.0'];\n return localNames.includes(host.replace(/.*@/, ''));\n}\n","import { readFileSync, readdirSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// Skill files are in ../../agent_moss/skills/ (shared with Python version)\nconst SKILLS_DIR = resolve(__dirname, '../../agent_moss/skills');\n\n// Skill keyword map (synced with Python skill_engine.py SKILL_KEYWORD_MAP)\nconst SKILL_KEYWORD_MAP: Record<string, string[]> = {\n 'file_access_guard': ['file', '文件', 'path', '路径', 'read', 'write', 'cat', 'open', 'access', '访问', '读写', 'copy', 'cp', 'mv', 'move'],\n 'script_execution_guard': ['command', 'shell', 'bash', 'exec', 'execute', '执行', '命令', 'script', '脚本', 'run', '运行', 'subprocess', 'system', 'eval', 'compile', '安装', 'install', 'pip', 'npm'],\n 'data_exfiltration_guard': ['upload', '上传', 'send', '发送', 'transfer', '传输', 'export', '导出', 'download', '下载', 'post', 'http', 'request', 'fetch', 'curl', 'wget', '外传', '泄露', 'exfil', 'network', '网络'],\n 'browser_web_access_guard': ['browser', '浏览器', 'web', '网页', 'url', 'navigate', '浏览', 'scrape', 'crawl', '爬取', 'click', 'screenshot'],\n 'email_operation_guard': ['email', '邮件', 'mail', 'smtp', 'send_email', '发送邮件', 'inbox', '收件箱', '附件', 'attachment'],\n 'general_tool_risk_guard': ['tool', '工具', 'api', 'invoke', '调用', 'function', '函数'],\n 'lateral_movement_guard': ['ssh', 'scp', 'ftp', 'sftp', 'rdp', 'vnc', 'telnet', '内网', '横向', 'tunnel', '代理', 'proxy', 'port', '端口', 'scan', '扫描', 'ping', 'traceroute', 'nslookup'],\n 'persistence_backdoor_guard': ['cron', 'crontab', '定时', 'scheduled', 'startup', '启动项', 'service', '服务', 'daemon', '守护', 'registry', '注册表', 'backdoor', '后门', 'persist', '持久化', 'authorized_keys', 'bashrc', 'zshrc', 'profile', '.rc', 'shell config', 'shell 配置'],\n 'resource_exhaustion_guard': ['fork', 'bomb', '炸弹', 'memory', '内存', 'disk', '磁盘', 'cpu', 'process', '进程', 'dd', 'while true', '无限循环', '耗尽', 'exhaust', '资源'],\n 'skill_installation_guard': ['skill', 'plugin', '插件', 'extension', '扩展', 'install skill', '安装插件', '安装技能', 'marketplace', '商店'],\n 'supply_chain_guard': ['dependency', '依赖', 'package', '包', 'npm install', 'pip install', 'requirements', 'import', 'library', '库', 'registry', '仓库', 'supply', '供应链', 'typosquatting'],\n 'intent_deviation_guard': ['rm', 'del', 'delete', 'remove', '删除', 'format', '格式化', 'drop', 'truncate', '清空', 'wipe', '擦除', '重置', 'reset', 'sudo', 'root', 'admin', '管理员', 'privilege', '提权'],\n};\n\nlet cachedSkills: Record<string, string> | null = null;\n\nfunction loadAllSkills(): Record<string, string> {\n if (cachedSkills) return cachedSkills;\n cachedSkills = {};\n\n if (!existsSync(SKILLS_DIR)) {\n console.warn('[AgentMoss] Skills directory not found:', SKILLS_DIR);\n return cachedSkills;\n }\n\n const files = readdirSync(SKILLS_DIR).filter(f => f.endsWith('.md'));\n for (const f of files) {\n const name = f.replace('.md', '');\n cachedSkills[name] = readFileSync(resolve(SKILLS_DIR, f), 'utf-8');\n }\n\n console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills`);\n return cachedSkills;\n}\n\nexport interface SkillMatch {\n skillName: string;\n relevance: number; // 0-1\n skillContent: string;\n}\n\n/**\n * Match skills by keyword relevance (mirrors Python SkillEngine.match_skills).\n * Returns top-3 most relevant skills, or fallback to general_tool_risk_guard.\n */\nexport function matchSkills(\n actionType: string,\n actionDetail: string,\n reason: string,\n maxSkills: number = 3\n): SkillMatch[] {\n const skills = loadAllSkills();\n const combined = `${actionType} ${actionDetail} ${reason}`.toLowerCase();\n const actionDetailLower = actionDetail.toLowerCase();\n const actionTypeLower = actionType.toLowerCase();\n const reasonLower = reason.toLowerCase();\n\n const scores: Record<string, number> = {};\n for (const [skillName, keywords] of Object.entries(SKILL_KEYWORD_MAP)) {\n let score = 0;\n for (const kw of keywords) {\n if (combined.includes(kw)) {\n if (kw === actionTypeLower) score += 2.0;\n else if (actionDetailLower.includes(kw)) score += 1.5;\n else if (reasonLower.includes(kw)) score += 1.0;\n else score += 0.5;\n }\n }\n if (score > 0) scores[skillName] = score;\n }\n\n const sorted = Object.entries(scores).sort((a, b) => b[1] - a[1]);\n const top = sorted.slice(0, maxSkills);\n const maxScore = top[0]?.[1] || 1;\n\n const results: SkillMatch[] = [];\n for (const [name, score] of top) {\n const content = skills[name];\n if (content) {\n results.push({\n skillName: name,\n relevance: Math.min(score / maxScore, 1.0),\n skillContent: content,\n });\n }\n }\n\n // Fallback to general_tool_risk_guard if no match\n if (results.length === 0) {\n const fallback = skills['general_tool_risk_guard'];\n if (fallback) {\n results.push({ skillName: 'general_tool_risk_guard', relevance: 0.3, skillContent: fallback });\n }\n }\n\n return results;\n}\n\n/**\n * Format matched skills for LLM prompt (mirrors Python SkillEngine.format_skills_for_prompt).\n */\nexport function formatSkillsForPrompt(skills: SkillMatch[]): string {\n if (skills.length === 0) return '(未匹配到特定安全检测规则)';\n return skills.map(s =>\n `### 安全检测规则: ${s.skillName} (相关度: ${Math.round(s.relevance * 100)}%)\\n\\n${s.skillContent}`\n ).join('\\n\\n---\\n\\n');\n}\n\n/** Legacy: load all skills as flat string array */\nexport function loadSkills(): string[] {\n const skills = loadAllSkills();\n return Object.entries(skills).map(([name, content]) => `### ${name}\\n${content}`);\n}\n\n/** Reload skills (for hot-reload) */\nexport function reloadSkills(): void {\n cachedSkills = null;\n loadAllSkills();\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst TEMPLATES_DIR = resolve(__dirname, '../../agent_moss/templates');\n\nconst TEMPLATE_FILES = ['prompt1_template.txt', 'prompt2_template.txt', 'security_judge_template.txt'];\n\nlet cachedTemplates: Record<string, string> | null = null;\n\nexport function loadTemplates(): Record<string, string> {\n if (cachedTemplates) return cachedTemplates;\n\n cachedTemplates = {};\n\n if (!existsSync(TEMPLATES_DIR)) {\n console.warn('[AgentMoss] Templates directory not found:', TEMPLATES_DIR);\n return cachedTemplates;\n }\n\n for (const file of TEMPLATE_FILES) {\n const filePath = resolve(TEMPLATES_DIR, file);\n if (existsSync(filePath)) {\n const key = file.replace('.txt', '').replace('_template', '');\n cachedTemplates[key] = readFileSync(filePath, 'utf-8');\n }\n }\n\n console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates`);\n return cachedTemplates;\n}\n\nexport function reloadTemplates(): void {\n cachedTemplates = null;\n loadTemplates();\n}\n","import { readFileSync } from 'fs';\nimport { resolve, join } from 'path';\n\n/**\n * Script content pre-scanning — detects suspicious patterns in bash scripts.\n * When a script execution is detected, reads up to 500 lines and scans for\n * high-risk patterns (network exfil, reverse shells, base64 obfuscation,\n * sensitive file access, persistence backdoors).\n */\n\n// High-risk detection patterns\nconst SUSPICIOUS_PATTERNS: { name: string; pattern: RegExp }[] = [\n // Network exfiltration (curl/wget POST in scripts is almost never legitimate)\n { name: 'curl POST', pattern: /curl\\s+(.*\\s)?-X\\s+POST/i },\n { name: 'curl --data', pattern: /curl\\s+(.*\\s)?--data/i },\n { name: 'curl -d', pattern: /curl\\s+(.*\\s)?-d\\s/i },\n { name: 'wget --post-data', pattern: /wget\\s+(.*\\s)?--post-data/i },\n { name: 'wget --post-file', pattern: /wget\\s+(.*\\s)?--post-file/i },\n // Reverse shell\n { name: 'nc -e', pattern: /\\bnc\\s+.*-e\\b/ },\n { name: 'ncat -e', pattern: /\\bncat\\s+.*-e\\b/ },\n { name: '/dev/tcp', pattern: /\\/dev\\/tcp\\// },\n { name: '/dev/udp', pattern: /\\/dev\\/udp\\// },\n // Base64 obfuscation\n { name: '$(base64', pattern: /\\$\\(\\s*base64/ },\n { name: '`base64', pattern: /`\\s*base64/ },\n { name: 'base64 decode pipe', pattern: /base64\\s+(-d|--decode)\\s*\\|/ },\n // Sensitive file access\n { name: '/etc/shadow', pattern: /\\/etc\\/shadow/ },\n { name: 'id_rsa', pattern: /\\bid_rsa\\b/ },\n { name: 'id_ed25519', pattern: /\\bid_ed25519\\b/ },\n // Persistence backdoor\n { name: 'crontab install', pattern: /crontab\\s+-/ },\n { name: 'authorized_keys', pattern: /authorized_keys/ },\n { name: 'ssh no host key check', pattern: /ssh\\s+.*StrictHostKeyChecking\\s*=\\s*no/ },\n];\n\n// Script execution patterns\nconst SCRIPT_EXEC_PATTERNS = [\n /bash\\s+(\\S+\\.sh)/,\n /sh\\s+(\\S+\\.sh)/,\n /\\.\\/(\\S+\\.sh)/,\n /source\\s+(\\S+\\.sh)/,\n /\\.\\s+(\\S+\\.sh)/,\n /zsh\\s+(\\S+\\.sh)/,\n];\n\n// Keyword combination risk rules\nconst KEYWORD_COMBINATION_RISKS: { group1: Set<string>; group2: Set<string>; level: string; reason: string }[] = [\n {\n group1: new Set(['curl POST', 'curl --data', 'curl -d', 'wget --post-data', 'wget --post-file']),\n group2: new Set(['$(base64', '`base64', 'base64 decode pipe']),\n level: 'critical',\n reason: '检测到网络数据发送 + Base64编码组合,构成 Critical 级别数据外传风险。攻击者可能将敏感数据编码后外传。',\n },\n {\n group1: new Set(['curl POST', 'curl --data', 'curl -d', 'wget --post-data', 'wget --post-file']),\n group2: new Set(['/etc/shadow', 'id_rsa', 'id_ed25519']),\n level: 'critical',\n reason: '检测到网络数据发送 + 敏感文件访问组合,构成 Critical 级别凭证外传风险。',\n },\n {\n group1: new Set(['nc -e', 'ncat -e', '/dev/tcp', '/dev/udp']),\n group2: new Set(),\n level: 'high',\n reason: '检测到反弹 Shell 特征,攻击者可能建立远程控制通道。',\n },\n {\n group1: new Set(['crontab install', 'authorized_keys', 'ssh no host key check']),\n group2: new Set(),\n level: 'high',\n reason: '检测到持久化后门特征,攻击者可能在系统中植入后门。',\n },\n];\n\nconst SINGLE_KEYWORD_RISKS: Record<string, { level: string; reason: string }> = {\n 'curl POST': { level: 'high', reason: '检测到 curl POST 请求,可能向外部服务器发送数据。' },\n 'curl --data': { level: 'high', reason: '检测到 curl --data 参数,可能向外部服务器发送数据。' },\n 'curl -d': { level: 'high', reason: '检测到 curl -d 参数,可能向外部服务器发送数据。' },\n 'wget --post-data': { level: 'high', reason: '检测到 wget POST 请求,可能向外部服务器发送数据。' },\n 'wget --post-file': { level: 'high', reason: '检测到 wget 文件上传,可能向外部服务器发送文件。' },\n 'nc -e': { level: 'critical', reason: '检测到 nc -e 反弹 Shell 特征。' },\n 'ncat -e': { level: 'critical', reason: '检测到 ncat -e 反弹 Shell 特征。' },\n '/dev/tcp': { level: 'critical', reason: '检测到 /dev/tcp 反弹 Shell 特征。' },\n '/dev/udp': { level: 'critical', reason: '检测到 /dev/udp 反弹 Shell 特征。' },\n '$(base64': { level: 'high', reason: '检测到 Base64 编码执行,可能是混淆逃逸。' },\n '`base64': { level: 'high', reason: '检测到 Base64 编码执行,可能是混淆逃逸。' },\n 'base64 decode pipe': { level: 'high', reason: '检测到 Base64 解码后管道执行,可能是混淆逃逸。' },\n '/etc/shadow': { level: 'critical', reason: '检测到访问系统密码文件。' },\n 'id_rsa': { level: 'critical', reason: '检测到访问 SSH 私钥。' },\n 'id_ed25519': { level: 'critical', reason: '检测到访问 SSH 私钥。' },\n 'crontab install': { level: 'high', reason: '检测到修改定时任务,可能是持久化后门。' },\n 'authorized_keys': { level: 'high', reason: '检测到修改 SSH 授权密钥,可能是持久化后门。' },\n 'ssh no host key check': { level: 'high', reason: '检测到 SSH 跳过主机密钥验证,可能是横向移动。' },\n};\n\nconst LEVEL_ORDER: Record<string, number> = { low: 1, medium: 2, high: 3, critical: 4 };\n\nexport interface ScriptAnalysisResult {\n scriptPath: string;\n scriptContent: string;\n matchedKeywords: string[];\n lineCount: number;\n isSuspicious: boolean;\n error: string;\n riskLevel: string;\n riskReason: string;\n}\n\nfunction emptyResult(): ScriptAnalysisResult {\n return { scriptPath: '', scriptContent: '', matchedKeywords: [], lineCount: 0, isSuspicious: false, error: '', riskLevel: '', riskReason: '' };\n}\n\nfunction extractScriptPath(command: string): string | null {\n for (const pattern of SCRIPT_EXEC_PATTERNS) {\n const m = command.match(pattern);\n if (m) return m[1];\n }\n return null;\n}\n\nfunction scanScriptForKeywords(content: string): string[] {\n const matched: string[] = [];\n for (const { name, pattern } of SUSPICIOUS_PATTERNS) {\n if (pattern.test(content)) matched.push(name);\n }\n return matched;\n}\n\nfunction assessKeywordCombinationRisk(matchedKeywords: string[], scriptContent: string): { level: string; reason: string } {\n if (matchedKeywords.length === 0) return { level: '', reason: '' };\n\n const keywordSet = new Set(matchedKeywords);\n\n // Check combination rules\n for (const rule of KEYWORD_COMBINATION_RISKS) {\n const hitGroup1 = [...rule.group1].some(k => keywordSet.has(k));\n const hitGroup2 = rule.group2.size === 0 ? true : [...rule.group2].some(k => keywordSet.has(k));\n if (hitGroup1 && hitGroup2) return { level: rule.level, reason: rule.reason };\n }\n\n // Extra: network post + env variable collection\n const networkPostKeywords = new Set(['curl POST', 'curl --data', 'curl -d', 'wget --post-data', 'wget --post-file']);\n const hasNetworkPost = [...networkPostKeywords].some(k => keywordSet.has(k));\n if (hasNetworkPost) {\n const envPatterns = ['$env', '$(env)', '$USER', '$(hostname)', '$(pwd)', '$HOME'];\n const contentLower = scriptContent.toLowerCase();\n for (const p of envPatterns) {\n if (contentLower.includes(p.toLowerCase())) {\n return {\n level: 'critical',\n reason: '检测到网络数据发送 + 系统环境变量收集组合,构成 Critical 级别数据外传风险。脚本可能将用户环境变量(可能包含 API Key、密钥等敏感信息)发送到远程服务器。',\n };\n }\n }\n }\n\n // Single keyword fallback\n let bestLevel = '';\n let bestReason = '';\n for (const kw of matchedKeywords) {\n const risk = SINGLE_KEYWORD_RISKS[kw];\n if (risk && (LEVEL_ORDER[risk.level] || 0) > (LEVEL_ORDER[bestLevel] || 0)) {\n bestLevel = risk.level;\n bestReason = risk.reason;\n }\n }\n\n return { level: bestLevel, reason: bestReason };\n}\n\nfunction readScriptContent(scriptPath: string, maxLines: number = 500): { content: string; lineCount: number; error: string } {\n try {\n const expandedPath = scriptPath.startsWith('~')\n ? join(process.env.HOME || '/home/user', scriptPath.slice(2))\n : resolve(scriptPath);\n\n const raw = readFileSync(expandedPath, 'utf-8');\n const lines = raw.split('\\n').slice(0, maxLines);\n return { content: lines.join('\\n'), lineCount: lines.length, error: '' };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n return { content: '', lineCount: 0, error: `读取脚本失败: ${msg}` };\n }\n}\n\nexport function analyzeScriptContent(actionType: string, actionDetail: string, maxLines: number = 500): ScriptAnalysisResult {\n if (actionType.toLowerCase() !== 'bash') return emptyResult();\n\n const scriptPath = extractScriptPath(actionDetail);\n if (!scriptPath) return emptyResult();\n\n const { content, lineCount, error } = readScriptContent(scriptPath, maxLines);\n if (error) return { ...emptyResult(), scriptPath, error };\n\n const matchedKeywords = scanScriptForKeywords(content);\n const isSuspicious = matchedKeywords.length > 0;\n\n let riskLevel = '';\n let riskReason = '';\n if (isSuspicious) {\n const risk = assessKeywordCombinationRisk(matchedKeywords, content);\n riskLevel = risk.level;\n riskReason = risk.reason;\n }\n\n return { scriptPath, scriptContent: content, matchedKeywords, lineCount, isSuspicious, error: '', riskLevel, riskReason };\n}\n\nexport function formatScriptAnalysisForPrompt(result: ScriptAnalysisResult): string {\n if (!result.scriptPath) return '';\n if (result.error) return `脚本内容分析失败: ${result.error}`;\n if (!result.isSuspicious) return '';\n\n const keywordsStr = result.matchedKeywords.join(', ');\n let riskHint = '';\n if (result.riskLevel && result.riskReason) {\n riskHint = `\\n\\n风险评估: ${result.riskLevel.toUpperCase()} 级别\\n风险原因: ${result.riskReason}\\n建议: 此脚本应被拒绝(Deny),除非有明确的业务需求且已确认目标服务器可信。`;\n }\n\n return `检测到脚本执行,且脚本内容包含可疑关键词:\\n 脚本路径: ${result.scriptPath}\\n 可疑关键词: ${keywordsStr}\\n 脚本行数: ${result.lineCount}${riskHint}\\n\\n### 脚本内容 ###\\n\\`\\`\\`\\n${result.scriptContent}\\n\\`\\`\\`\\n`;\n}\n","import { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getLLMConfig, isLLMAvailable, detectProvider, getProviderHeaders } from '../config';\nimport { matchSkills, formatSkillsForPrompt } from './skill-loader';\nimport { loadTemplates } from './template-loader';\nimport { analyzeScriptContent, formatScriptAnalysisForPrompt } from './script-analyzer';\nimport OpenAI from 'openai';\n\n// LRU cache to avoid duplicate LLM calls for identical commands\nconst llmCache = new Map<string, SecurityJudgment>();\nconst LLM_CACHE_MAX = 200;\n\ninterface PreviousResults {\n heuristic: SecurityJudgment | null;\n logic: SecurityJudgment | null;\n}\n\n/**\n * Layer 3: LLM + Skill semantic analysis.\n * Only called when layers 1 and 2 both pass.\n * Loads skills from the shared skills directory and uses LLM for deep analysis.\n */\nexport async function runLLMAnalysis(\n input: AnalysisInput,\n previous: PreviousResults\n): Promise<SecurityJudgment> {\n if (!isLLMAvailable()) {\n console.log('[AgentMoss] LLM not configured, skipping deep analysis');\n return {\n allowed: true,\n reason: 'LLM 未配置,跳过深层分析',\n riskLevel: 'low',\n riskType: '',\n confidence: 50,\n source: 'llm',\n violatedLayers: [],\n };\n }\n\n const config = getLLMConfig();\n\n // Check LRU cache (use raw command as key, strip OpenDesk metadata)\n const rawDetail = input.aNext.actionDetail.replace(/^terminal-\\w+:\\s*command=([^,]+).*/, '$1').trim();\n const cacheKey = `${input.aNext.actionType}:${rawDetail || input.aNext.actionDetail}`;\n const cached = llmCache.get(cacheKey);\n if (cached) {\n console.log('[AgentMoss] LLM cache hit');\n return cached;\n }\n\n // Load skills and templates (cached)\n const matchedSkills = matchSkills(input.aNext.actionType, input.aNext.actionDetail, input.reason);\n const templates = loadTemplates();\n\n // Build the analysis prompt\n const scriptAnalysis = analyzeScriptContent(input.aNext.actionType, input.aNext.actionDetail);\n const prompt = buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis);\n\n // Call LLM\n const result = await analyzeWithLLM(prompt, config);\n\n // Cache result\n if (llmCache.size >= LLM_CACHE_MAX) {\n const firstKey = llmCache.keys().next().value;\n if (firstKey) llmCache.delete(firstKey);\n }\n llmCache.set(cacheKey, result);\n\n return result;\n}\n\nfunction buildPrompt(\n input: AnalysisInput,\n previous: PreviousResults,\n matchedSkills: import('./skill-loader').SkillMatch[],\n templates: Record<string, string>,\n scriptAnalysis?: import('./script-analyzer').ScriptAnalysisResult\n): string {\n const skillsText = formatSkillsForPrompt(matchedSkills);\n const historyStr = input.actionHistory\n .map((h, i) => `${i + 1}. ${h.actionType}: ${h.actionDetail}`)\n .join('\\n') || '(无历史操作)';\n\n const templateName = previous.heuristic || previous.logic ? 'prompt2' : 'prompt1';\n const baseTemplate = templates[templateName] || templates['prompt1'] || '';\n\n const scriptAnalysisText = scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : '';\n\n // Format L1/L2 hints (mirrors Python LLMAnalyzer._format_hints)\n const hintsText = formatHints(previous);\n\n return `${baseTemplate}\n\n## 当前操作上下文\n- 会话 ID: ${input.sessionId}\n- 用户任务: ${input.promptSession || '未指定'}\n- 操作系统: ${input.osType}\n- 工作目录: ${input.cwd || '/'}\n- 操作原因: ${input.reason || '未说明'}\n- 历史操作序列:\n${historyStr}\n\n- 即将执行的操作:\n 类型: ${input.aNext.actionType}\n 详情: ${input.aNext.actionDetail}\n\n## 可用安全 Skill\n${skillsText}\n\n## 前置检测结果\n${hintsText}\n${scriptAnalysisText ? `\\n## 脚本内容分析\\n${scriptAnalysisText}` : ''}\n\n请根据以上信息,对即将执行的操作进行安全判断。你必须输出严格的 JSON 格式,\n不要包含任何其他文字、注释或 markdown 标记。\n\n输出格式:\n{\"allowed\": true/false, \"reason\": \"判断理由\", \"riskLevel\": \"low|medium|high|critical\", \"riskType\": \"风险类型\", \"confidence\": 0-100}`;\n}\n\nfunction formatHints(previous: PreviousResults): string {\n const hints: string[] = [];\n\n if (previous.heuristic) {\n hints.push(\n `启发式检测发现风险 [风险等级: ${previous.heuristic.riskLevel}]:\\n` +\n ` 类型: ${previous.heuristic.riskType}\\n` +\n ` 原因: ${previous.heuristic.reason}`\n );\n }\n\n if (previous.logic) {\n hints.push(\n `逻辑规则检测发现风险 [风险等级: ${previous.logic.riskLevel}]:\\n` +\n ` 类型: ${previous.logic.riskType}\\n` +\n ` 原因: ${previous.logic.reason}`\n );\n }\n\n return hints.length > 0 ? hints.join('\\n\\n') : '启发式检测和逻辑规则检测均未发现风险。';\n}\n\nasync function analyzeWithLLM(prompt: string, config: ReturnType<typeof getLLMConfig>): Promise<SecurityJudgment> {\n console.log(`[AgentMoss] LLM analyzing with model: ${config.model}, url: ${config.baseUrl}`);\n\n const provider = detectProvider(config.baseUrl, config.provider);\n const extraHeaders = getProviderHeaders(provider);\n if (Object.keys(extraHeaders).length > 0) {\n console.log(`[AgentMoss] Provider detected: ${provider}, injecting headers: ${Object.keys(extraHeaders).join(', ')}`);\n }\n\n const client = new OpenAI({\n baseURL: config.baseUrl,\n apiKey: config.apiKey,\n timeout: (config.timeout || 300) * 1000,\n defaultHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined,\n });\n\n const maxRetries = parseInt(process.env.AGENT_MOSS_LLM_RETRIES || '2', 10); // default 2 retries = 3 attempts total\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await client.chat.completions.create({\n model: config.model,\n temperature: config.temperature || 0.1,\n max_tokens: config.maxTokens || 1024,\n messages: [\n { role: 'system', content: '你是一个 AI Agent 安全审计专家。你的任务是分析即将执行的命令是否安全。你必须只输出纯 JSON,不要包含任何 markdown 标记、代码块或其他文字。' },\n { role: 'user', content: prompt },\n ],\n });\n\n const content = response.choices[0]?.message?.content || '{}';\n console.log(`[AgentMoss] LLM raw response (attempt ${attempt + 1}/${maxRetries + 1}): ${content.substring(0, 300)}`);\n\n let jsonStr = content.trim();\n if (jsonStr.startsWith('```')) {\n jsonStr = jsonStr.replace(/^```[\\w]*\\n?/, '').replace(/\\n?```$/, '');\n }\n const parsed = JSON.parse(jsonStr);\n\n return {\n allowed: parsed.allowed !== false,\n reason: parsed.reason || 'LLM 分析完成',\n riskLevel: ['low', 'medium', 'high', 'critical'].includes(parsed.riskLevel) ? parsed.riskLevel : 'low',\n riskType: parsed.riskType || '',\n confidence: typeof parsed.confidence === 'number' ? Math.min(100, Math.max(0, parsed.confidence)) : 70,\n source: 'llm',\n violatedLayers: ['3'],\n };\n } catch (err) {\n if (attempt < maxRetries) {\n console.error(`[AgentMoss] LLM call failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in 1s:`, (err as Error).message);\n await new Promise(resolve => setTimeout(resolve, 1000));\n } else {\n console.error('[AgentMoss] LLM call failed after all retries:', (err as Error).message);\n // Fail-closed: deny on LLM failure (matches Python behavior)\n return {\n allowed: false,\n reason: `LLM 分析失败,因无法完成深度语义分析,按 fail-closed 原则拒绝 (${maxRetries + 1} 次尝试): ${(err as Error).message}`,\n riskLevel: 'medium',\n riskType: '',\n confidence: 60,\n source: 'llm_failure',\n violatedLayers: ['3'],\n };\n }\n }\n }\n\n // Should never reach here, but TypeScript needs a return\n return {\n allowed: false,\n reason: 'LLM 分析异常',\n riskLevel: 'medium',\n riskType: '',\n confidence: 60,\n source: 'llm_failure',\n violatedLayers: ['3'],\n };\n}\n","import { SecurityJudgment } from './types';\nimport { runHeuristicCheck, isInlineScriptCommand } from './heuristic';\nimport { runLogicCheck } from './logic-rules';\nimport { runLLMAnalysis } from './llm-analyzer';\nimport { isHeuristicEnabled, isLogicRulesEnabled, isLLMAvailable } from '../config';\n\nexport interface AnalysisInput {\n sessionId: string;\n promptSession: string;\n actionHistory: { actionType: string; actionDetail: string }[];\n aNext: { actionType: string; actionDetail: string };\n reason: string;\n osType: string;\n cwd: string;\n}\n\n// ========== 快速放行白名单 ==========\n\n/** 完全安全工具:跳过 Layer 2 + Layer 3 */\nconst FULLY_SAFE_TOOLS = new Set([\n 'ask_user_question', 'glob', 'list_dir', 'ls', 'count_text_length',\n 'filemgr-globfiles',\n]);\n\n/** 安全但可能访问敏感路径:跳过 Layer 3,保留 Layer 2 */\nconst READONLY_SENSITIVE_TOOLS = new Set([\n 'read', 'file_read', 'read_file', 'head', 'tail', 'grep',\n 'filemgr-readfile', 'filemgr-grepfiles',\n]);\n\n/** 完全安全 bash 子命令正则 */\nconst FULLY_SAFE_BASH_PATTERNS: RegExp[] = [\n /^ls(?:\\s|$)/i, /^dir(?:\\s|$)/i,\n /^pwd(?:\\s|$)/i, /^which\\s+/i, /^whereis\\s+/i, /^realpath\\s+/i,\n /^basename\\s+/i, /^dirname\\s+/i,\n /^file\\s+/i, /^stat\\s+/i, /^du(?:\\s|$)/i,\n /^echo\\s+/i, /^printf\\s+/i,\n /^type\\s+/i, /^command\\s+/i,\n];\n\n/** 安全但可能访问敏感路径的 bash 子命令正则 */\nconst READONLY_SENSITIVE_BASH_PATTERNS: RegExp[] = [\n /^cat\\s+/i, /^head(?:\\s|$)/i, /^tail(?:\\s|$)/i,\n /^less(?:\\s|$)/i, /^more(?:\\s|$)/i, /^wc(?:\\s|$)/i,\n /^grep(?:\\s|$)/i, /^find\\s+/i, /^ag(?:\\s|$)/i, /^rg(?:\\s|$)/i,\n /^awk\\s+/i, /^sed\\s+/i, /^cut\\s+/i, /^sort(?:\\s|$)/i, /^uniq(?:\\s|$)/i,\n];\n\n/** 提取管道和链式命令的第一段 */\nfunction extractFirstCommand(command: string): string {\n let main = command.split('|')[0].trim();\n for (const sep of ['&&', '||']) {\n const idx = main.indexOf(sep);\n if (idx !== -1) {\n main = main.substring(0, idx).trim();\n break;\n }\n }\n return main;\n}\n\n/** 从 OpenDesk 格式中提取实际命令 */\nfunction extractRawCommand(detail: string): string {\n const m = detail.match(/command=([^,]+)/);\n return m ? m[1].trim() : detail;\n}\n\nfunction matchesAny(cmd: string, patterns: RegExp[]): boolean {\n return patterns.some(p => p.test(cmd));\n}\n\n// ========== 三层防御协调器 ==========\n\n/**\n * Three-layer defense coordinator.\n * Layer 1 → fast-pass check → Layer 2 → Layer 3.\n * Fast-pass: whitelisted safe tools/commands skip L2+L3 or L3 only.\n */\nexport async function runAnalysis(input: AnalysisInput): Promise<SecurityJudgment> {\n // Layer 1: Heuristic static detection (fast)\n const heuristicResult = isHeuristicEnabled() ? runHeuristicCheck(input) : null;\n\n // 内联脚本命令 file_access 假阳性防护:不立即拦截,转 Layer 3 语义判断\n // 因为字符串字面量中的敏感路径(如 '/etc/shadow')不应被正则误拦截\n const isInlineScriptCmd = isInlineScriptCommand(input.aNext.actionDetail.toLowerCase());\n if (heuristicResult && !heuristicResult.allowed) {\n const skipInlineFileAccess = isInlineScriptCmd && heuristicResult.riskType === 'file_access';\n if (!skipInlineFileAccess) {\n return heuristicResult;\n }\n }\n\n // ===== Fast-pass check =====\n const actionType = input.aNext.actionType.toLowerCase();\n const rawDetail = extractRawCommand(input.aNext.actionDetail);\n const lowerDetail = rawDetail.toLowerCase();\n\n // Fully safe tools: skip L2 + L3\n if (FULLY_SAFE_TOOLS.has(actionType)) {\n return {\n allowed: true,\n reason: `完全安全工具,跳过深度分析: ${actionType}`,\n riskLevel: (heuristicResult?.riskLevel || 'low') as SecurityJudgment['riskLevel'],\n riskType: '',\n confidence: 95,\n source: 'whitelist_bypass',\n violatedLayers: [],\n };\n }\n\n // Readonly sensitive tools: skip L3, continue to L2\n let skipLLM = READONLY_SENSITIVE_TOOLS.has(actionType);\n\n // Bash sub-command checks\n if (actionType === 'bash' || actionType === 'executebash' || actionType === 'terminal-executebash') {\n const firstCmd = extractFirstCommand(lowerDetail);\n if (matchesAny(firstCmd, FULLY_SAFE_BASH_PATTERNS)) {\n return {\n allowed: true,\n reason: `安全的只读 bash 命令: ${firstCmd}`,\n riskLevel: 'low',\n riskType: '',\n confidence: 95,\n source: 'whitelist_bypass',\n violatedLayers: [],\n };\n }\n if (matchesAny(firstCmd, READONLY_SENSITIVE_BASH_PATTERNS)) {\n skipLLM = true;\n }\n }\n\n // Layer 2: Logic rule detection (fast)\n const logicResult = isLogicRulesEnabled() ? runLogicCheck(input) : null;\n if (logicResult && !logicResult.allowed) {\n const skipInlineFileAccess = isInlineScriptCmd && logicResult.riskType === 'sensitive_path_access';\n if (!skipInlineFileAccess) {\n return logicResult;\n }\n }\n\n // Layer 3: LLM analysis (skipped for readonly sensitive tools/commands)\n if (skipLLM || !isLLMAvailable()) {\n return {\n allowed: true,\n reason: '只读操作且无逻辑规则违规,跳过 LLM 分析',\n riskLevel: (logicResult?.riskLevel || 'low') as SecurityJudgment['riskLevel'],\n riskType: '',\n confidence: 85,\n source: 'heuristic_and_logic_only',\n violatedLayers: [],\n };\n }\n\n const llmResult = await runLLMAnalysis(input, {\n heuristic: heuristicResult,\n logic: logicResult,\n });\n\n return llmResult;\n}\n","#!/usr/bin/env node\n/**\n * AgentMoss CLI — TypeScript version.\n * Supports: init | analyze | server\n */\n\nimport { parseArgs } from 'util';\nimport { createApp } from './server';\n\nfunction printHelp(): void {\n console.log(`AgentMoss security analysis engine (TypeScript v0.2.0)\n\nCommands:\n init Generate input.json template\n analyze <input> Run security analysis on input JSON\n server Start HTTP API server\n\nServer options:\n --host <host> Listen host (default: 127.0.0.1)\n --port <port> Listen port (default: 9090)\n`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (!command || command === '--help' || command === '-h') {\n printHelp();\n process.exit(command ? 0 : 1);\n }\n\n switch (command) {\n case 'init': {\n const output = args[2] || 'input.json';\n const fs = await import('fs');\n const template = {\n session_id: 'my-session-001',\n prompt_session: 'Read /var/log/app.log and analyze errors',\n action_history: [],\n a_next: { action_type: 'bash', action_detail: 'cat /var/log/app.log' },\n reason: 'Need to read log file for error analysis',\n os_type: '',\n cwd: '/home/user/project',\n };\n fs.writeFileSync(output, JSON.stringify(template, null, 2), 'utf-8');\n console.log(`Template written to ${output}`);\n break;\n }\n\n case 'analyze': {\n if (!args[1]) {\n console.error('Usage: agent-moss analyze <input.json>');\n process.exit(1);\n }\n const fs = await import('fs');\n const path = await import('path');\n const { runAnalysis } = await import('./engine/coordinator');\n const filePath = path.resolve(args[1]);\n const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n const result = await runAnalysis({\n sessionId: data.session_id || 'unknown',\n promptSession: data.prompt_session || '',\n actionHistory: (data.action_history || []).map((h: any) => ({\n actionType: h.action_type || h.name || '',\n actionDetail: h.action_detail || '',\n })),\n aNext: {\n actionType: data.a_next?.action_type || '',\n actionDetail: data.a_next?.action_detail || '',\n },\n reason: data.reason || '',\n osType: data.os_type || (process.platform === 'win32' ? 'windows' : 'linux'),\n cwd: data.cwd || process.cwd(),\n });\n console.log(JSON.stringify(result, null, 2));\n process.exit(result.allowed ? 0 : 1);\n break;\n }\n\n case 'server': {\n let host = '127.0.0.1';\n let port = 9090;\n\n for (let i = 1; i < args.length; i++) {\n if (args[i] === '--host' && args[i + 1]) host = args[++i];\n else if (args[i] === '--port' && args[i + 1]) port = parseInt(args[++i], 10);\n }\n\n // Import @hono/node-server dynamically\n const { serve } = await import('@hono/node-server');\n const app = createApp();\n console.log(`AgentMoss HTTP server on ${host}:${port}`);\n serve({ fetch: app.fetch, hostname: host, port }, (info) => {\n console.log(`Listening on http://${host}:${port}`);\n });\n break;\n }\n\n default:\n console.error(`Unknown command: ${command}`);\n printHelp();\n process.exit(1);\n }\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n","import { Hono } from 'hono';\nimport { cors } from 'hono/cors';\nimport { logger } from 'hono/logger';\nimport { analyzeRoute, healthRoute } from './routes';\n\nexport function createApp(): Hono {\n const app = new Hono();\n\n // Middleware\n app.use('*', cors({ origin: '*', allowMethods: ['GET', 'POST', 'OPTIONS'], allowHeaders: ['*'] }));\n app.use('*', logger());\n\n // Routes\n app.get('/api/v1/health', healthRoute);\n app.post('/api/v1/analyze', analyzeRoute);\n\n return app;\n}\n\nexport function startServer(host = '127.0.0.1', port = 9090): { serve: () => void } {\n const app = createApp();\n return {\n serve: () => {\n console.log(`AgentMoss HTTP server on ${host}:${port}`);\n // In utilityProcess mode, use Bun.serve or Node adapter\n // Use @hono/node-server for Node.js environments\n const { serve: honoServe } = require('@hono/node-server');\n honoServe({ fetch: app.fetch, hostname: host, port });\n },\n };\n}\n","import type { Context } from 'hono';\nimport { AnalyzeRequestSchema, AnalyzeResponseSchema, HealthResponseSchema } from './models';\nimport { runAnalysis } from './engine/coordinator';\n\nexport async function healthRoute(c: Context) {\n return c.json(HealthResponseSchema.parse({}));\n}\n\nexport async function analyzeRoute(c: Context) {\n const t0 = performance.now();\n\n try {\n const body = await c.req.json();\n const req = AnalyzeRequestSchema.parse(body);\n\n // OS auto-detect\n let osType = req.os_type;\n if (!osType) {\n osType = process.platform === 'win32' ? 'windows' : 'linux';\n }\n\n const result = await runAnalysis({\n sessionId: req.session_id,\n promptSession: req.prompt_session,\n actionHistory: req.action_history.map(h => ({\n actionType: h.action_type,\n actionDetail: h.action_detail,\n })),\n aNext: {\n actionType: req.a_next.action_type,\n actionDetail: req.a_next.action_detail,\n },\n reason: req.reason,\n osType,\n cwd: req.cwd,\n });\n\n const durationMs = performance.now() - t0;\n\n return c.json(\n AnalyzeResponseSchema.parse({\n decision: result.allowed ? 'Allow' : 'Deny',\n reason: result.reason,\n risk_level: result.riskLevel,\n risk_type: result.riskType,\n violated_layers: result.violatedLayers,\n policy: '',\n violated_policy: '',\n confidence: result.confidence,\n analysis_duration_ms: Math.round(durationMs * 10) / 10,\n })\n );\n } catch (err) {\n console.error('[AgentMoss] Analysis error:', err);\n if (err instanceof SyntaxError) {\n return c.json({ error: 'Invalid JSON', detail: err.message }, 400);\n }\n if ((err as any)?.issues) {\n return c.json({ error: 'Validation error', detail: (err as any).issues }, 400);\n }\n return c.json({ error: 'Internal error', detail: String(err) }, 500);\n }\n}\n","import { z } from 'zod';\n\n/** Single action in history or next action */\nexport const ActionItemSchema = z.object({\n action_type: z.string().describe('Action type, e.g. bash, file_read, file_write'),\n action_detail: z.string().describe('Action detail / command content'),\n});\n\nexport const AnalyzeRequestSchema = z.object({\n session_id: z.string().describe('Session / agent unique identifier'),\n prompt_session: z.string().default('').describe('User original prompt'),\n action_history: z.array(ActionItemSchema).default([]).describe('Historical action sequence'),\n a_next: ActionItemSchema.describe('Next action to be executed'),\n reason: z.string().default('').describe('Reason for executing this action'),\n os_type: z.string().default('').describe(\"OS type: 'linux', 'windows', or empty for auto-detect\"),\n cwd: z.string().default('').describe('Current working directory'),\n metadata: z.record(z.unknown()).optional().describe('Extended metadata'),\n});\n\nexport const AnalyzeResponseSchema = z.object({\n decision: z.enum(['Allow', 'Deny']).describe('Allow or Deny'),\n reason: z.string().describe('Decision reason'),\n risk_level: z.enum(['low', 'medium', 'high', 'critical']).default('low'),\n risk_type: z.string().default(''),\n violated_layers: z.array(z.string()).default([]),\n policy: z.string().default(''),\n violated_policy: z.string().default(''),\n confidence: z.number().int().min(0).max(100).default(100),\n analysis_duration_ms: z.number().default(0),\n});\n\nexport const HealthResponseSchema = z.object({\n status: z.string().default('healthy'),\n version: z.string().default('0.2.0'),\n});\n\nexport type ActionItem = z.infer<typeof ActionItemSchema>;\nexport type AnalyzeRequest = z.infer<typeof AnalyzeRequestSchema>;\nexport type AnalyzeResponse = z.infer<typeof AnalyzeResponseSchema>;\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n"],"mappings":"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","names":["path","existsSync","fileURLToPath","__filename","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","resolve","main","fs","path","runAnalysis"]}
|