@kenhkl/agent-moss 0.6.0 → 0.7.1

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 CHANGED
@@ -65,7 +65,7 @@ const result = await resp.json();
65
65
  └── 只读敏感 (15 bash 模式 + 8 action types) → 跳过 L3
66
66
 
67
67
  层1: 启发式静态检测 (<1ms)
68
- ├── 危险命令正则: 30 个模式(rm 分级检测: 5 条严格→宽松规则)
68
+ ├── 危险命令正则: 48 个模式(rm 分级检测,sudo 只拦截危险命令,nmap/masscan/zmap 检测)
69
69
  ├── → high/critical → 直接 Deny
70
70
  ├── → 内联脚本 file_access 转层3(避免 'python -c "cat /etc/shadow"' 假阳性)
71
71
  ├── 注入关键词: 56 个中英双语关键词(9 类: 指令覆盖/角色劫持/命令注入/...)
@@ -75,9 +75,11 @@ const result = await resp.json();
75
75
  ├── Rule 1: read-before-write(有历史但无读取 → flag)
76
76
  ├── Rule 2: 意图偏离(读取意图 vs 删除动作)
77
77
  ├── Rule 3: 敏感路径访问(20 条路径 + 5 条凭据文件, \b边界匹配, 读写均拦截)
78
- ├── Rule 4: 危险操作(通配符删除 + 重定向覆盖 /etc/ /boot/ /proc/)
79
- ├── Rule 5: 提权检测(sudo/su/chmod u+s/setuid)
80
- └── Rule 6: 横向移动(ssh/scp/rsync,排除 localhost)
78
+ ├── Rule 4: 危险操作(通配符删除 + 重定向覆盖,临时目录排除)
79
+ ├── Rule 5: 密码修改授权(非交互式需 ask_user_question)
80
+ ├── Rule 6: 用户/组删除授权(需 ask_user_question)
81
+ ├── Rule 7: 提权检测(sudo+危险命令/su/chmod u+s/setuid)
82
+ └── Rule 8: 横向移动(ssh/scp/rsync,排除 localhost)
81
83
 
82
84
  层3: LLM + Skill 深度分析 (2-5s)
83
85
  ├── 脚本预扫描: 读取 .sh 文件(最多 500 行),16 个可疑模式
@@ -145,8 +147,8 @@ ts/src/
145
147
  └── engine/
146
148
  ├── types.ts # 核心类型 (SecurityJudgment, LLMConfig, ...)
147
149
  ├── coordinator.ts # 三层协调器 + 两级快速放行白名单
148
- ├── heuristic.ts # 层1: 30 危险模式 + 56 注入关键词 + isInlineScriptCommand
149
- ├── logic-rules.ts # 层2: 6 条规则 + 20 敏感路径
150
+ ├── heuristic.ts # 层1: 48 危险模式 + 56 注入关键词 + isInlineScriptCommand
151
+ ├── logic-rules.ts # 层2: 8 条规则 + 20 敏感路径
150
152
  ├── llm-analyzer.ts # 层3: LLM 分析 (缓存 + 重试 + fail-closed)
151
153
  ├── script-analyzer.ts # 脚本内容预扫描 (18 个可疑模式)
152
154
  ├── skill-loader.ts # Skill 加载与关键词匹配 (12 个 Skill)
package/dist/cli.js CHANGED
@@ -305,18 +305,19 @@ var init_heuristic = __esm({
305
305
  ];
306
306
  DANGEROUS_PATTERNS = [
307
307
  // --- Critical: rm command graded detection (strict to loose, first match wins) ---
308
- // 1. rm -rf root dir
309
- { 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" },
310
- // 2. rm -rf absolute path (both -r and -f)
311
- { 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" },
312
- // 3. rm with -r or -f targeting system dirs
308
+ // 1. rm -rf root dir (含通配符如 /* /.* 等) — 使用负向先行断言 (?!\w):/ 后面不是单词字符时匹配
309
+ { pattern: /\brm\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\s+\/(?!\w)/i, severity: "critical", description: "\u9012\u5F52\u5F3A\u5236\u5220\u9664\u6839\u76EE\u5F55 (rm -rf /)", riskType: "script_execution" },
310
+ // 注意:已移除"rm -rf /任意绝对路径"的宽泛规则,避免误杀 /tmp 等临时目录清理操作
311
+ // 2. rm with -r or -f targeting system dirs
313
312
  { 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" },
314
- // 4. rm -r absolute path (no -f)
313
+ // 3. rm -r absolute path (no -f)
315
314
  { 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" },
316
- // 5. rm -f absolute path (no -r)
315
+ // 4. rm -f absolute path (no -r)
317
316
  { 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" },
318
- { 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" },
319
- { pattern: /mkfs\b/i, severity: "critical", description: "\u683C\u5F0F\u5316\u6587\u4EF6\u7CFB\u7EDF", riskType: "script_execution" },
317
+ // dd 磁盘清零 — 只拦截写入系统关键目录,放行 /tmp 等临时目录
318
+ { pattern: /dd\s+if=\/dev\/zero.*\bof\s*=\s*\/(etc|var|home|usr|boot|root|opt|srv|sys|proc)\b/i, severity: "critical", description: "\u78C1\u76D8\u6E05\u96F6\u5199\u5165\u5173\u952E\u7CFB\u7EDF\u76EE\u5F55 (dd if=/dev/zero of=/\u7CFB\u7EDF\u76EE\u5F55)", riskType: "script_execution" },
319
+ // mkfs 格式化 — 只拦截对块设备(/dev/sdX 等)的格式化,放行对普通文件的格式化
320
+ { pattern: /mkfs\.\w+\s+\/dev\/(sd|hd|nvme|vd|loop|mapper|md|dm)\S+/i, severity: "critical", description: "\u683C\u5F0F\u5316\u5757\u8BBE\u5907 (mkfs /dev/\u5757\u8BBE\u5907)", riskType: "script_execution" },
320
321
  { pattern: /:\(\)\s*\{.*:\|:&.*\};:/i, severity: "critical", description: "Fork Bomb", riskType: "resource_exhaustion" },
321
322
  // --- Critical: remote code execution ---
322
323
  { pattern: /curl\s+.*\|\s*(bash|sh|zsh|dash)/i, severity: "critical", description: "curl pipe shell \u6267\u884C", riskType: "script_execution" },
@@ -329,14 +330,15 @@ var init_heuristic = __esm({
329
330
  // --- Critical: sensitive file access ---
330
331
  { pattern: /\/etc\/shadow/i, severity: "critical", description: "\u8BBF\u95EE\u7CFB\u7EDF\u5BC6\u7801\u6587\u4EF6 (/etc/shadow)", riskType: "file_access" },
331
332
  { pattern: /\/etc\/gshadow/i, severity: "critical", description: "\u8BBF\u95EE\u7CFB\u7EDF\u7EC4\u5BC6\u7801\u6587\u4EF6 (/etc/gshadow)", riskType: "file_access" },
333
+ // 注意:/etc/passwd 已从拦截列表移除,因为它是公开可读的标准系统文件,真正敏感的是 /etc/shadow
332
334
  { pattern: /\.ssh\/id_rsa/i, severity: "critical", description: "\u8BBF\u95EE SSH \u79C1\u94A5\u6587\u4EF6", riskType: "file_access" },
333
335
  // --- Critical: privilege escalation / container escape ---
334
336
  { 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" },
335
337
  // --- High: dangerous permissions / ownership ---
336
338
  { pattern: /chmod\s+[0-7]*777[0-7]*/i, severity: "high", description: "\u5168\u6743\u9650\u8BBE\u7F6E (chmod 777)", riskType: "script_execution" },
337
339
  { 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" },
338
- { pattern: /sudo\s+rm\s+-rf/i, severity: "high", description: "sudo \u5F3A\u5236\u5220\u9664", riskType: "script_execution" },
339
- { pattern: /sudo\s+/i, severity: "high", description: "\u63D0\u6743\u6267\u884C (sudo)", riskType: "privilege_escalation" },
340
+ // sudo 提权 — 只拦截 sudo 后跟的危险命令,不一刀切拦截所有 sudo
341
+ { pattern: /sudo\s+(rm|chmod|chown|dd|mkfs|format|iptables|crontab|passwd|userdel|useradd|groupdel)\b/i, severity: "high", description: "\u63D0\u6743\u6267\u884C\u9AD8\u5371\u547D\u4EE4 (sudo + \u5371\u9669\u64CD\u4F5C)", riskType: "privilege_escalation" },
340
342
  // --- High: system config overwrite ---
341
343
  { pattern: />\s*\/etc\//i, severity: "critical", description: "\u8986\u76D6\u5199\u5165\u7CFB\u7EDF\u914D\u7F6E\u76EE\u5F55", riskType: "file_access" },
342
344
  // --- High: download script + execute risk ---
@@ -346,19 +348,22 @@ var init_heuristic = __esm({
346
348
  { pattern: /git\s+clone\s+.*\|.*bash/i, severity: "high", description: "git clone pipe shell", riskType: "script_execution" },
347
349
  { pattern: /pip\s+install\s+.*\|\s*bash/i, severity: "high", description: "pip install pipe shell", riskType: "script_execution" },
348
350
  { pattern: /npm\s+install\s+-g\s+.*\|\s*bash/i, severity: "high", description: "npm install pipe shell", riskType: "script_execution" },
349
- // --- High: destructive git operations ---
350
- { pattern: /git\s+push\s+.*--force/i, severity: "high", description: "\u5F3A\u5236\u63A8\u9001\u64CD\u4F5C (git push --force)", riskType: "script_execution" },
351
+ // --- Medium: destructive git operations (降级为 medium,允许但记录) ---
352
+ { pattern: /git\s+push\s+.*--force/i, severity: "medium", description: "\u5F3A\u5236\u63A8\u9001\u64CD\u4F5C (git push --force)\uFF0C\u53EF\u80FD\u8986\u76D6\u8FDC\u7A0B\u63D0\u4EA4\u5386\u53F2", riskType: "script_execution" },
353
+ // --- High: network port scanning (横向移动侦察) ---
354
+ { pattern: /\bnmap\s+/i, severity: "high", description: "\u7F51\u7EDC\u7AEF\u53E3\u626B\u63CF (nmap)\uFF0C\u53EF\u80FD\u7528\u4E8E\u6A2A\u5411\u79FB\u52A8\u4FA6\u5BDF", riskType: "lateral_movement" },
355
+ { pattern: /\b(masscan|zmap|unicornscan)\s+/i, severity: "high", description: "\u7F51\u7EDC\u7AEF\u53E3\u626B\u63CF\u5DE5\u5177\uFF0C\u53EF\u80FD\u7528\u4E8E\u6A2A\u5411\u79FB\u52A8\u4FA6\u5BDF", riskType: "lateral_movement" },
351
356
  // --- Medium: credential export ---
352
357
  { pattern: /export\s+.*(?:TOKEN|KEY|SECRET|PASSWORD)/i, severity: "medium", description: "\u5BFC\u51FA\u654F\u611F\u51ED\u8BC1", riskType: "data_exfiltration" },
353
358
  // --- High: shell rc file append (persistence) ---
354
359
  { 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" },
355
- // --- High: device file access ---
356
- { 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" },
360
+ // --- High: device file write (只拦截重定向写入设备文件,不拦截读取) ---
361
+ { pattern: />\s*\/dev\/(sd|hd|nvme|vd|loop|mem|kmsg|port|zero|random|urandom|full|core)/i, severity: "high", description: "\u91CD\u5B9A\u5411\u5199\u5165\u8BBE\u5907\u6587\u4EF6", riskType: "file_access" },
357
362
  // --- High: non-interactive password modification ---
358
363
  { pattern: /\|\s*passwd\b/i, severity: "high", description: "\u68C0\u6D4B\u5230\u7BA1\u9053\u65B9\u5F0F\u8C03\u7528 passwd\uFF08\u975E\u4EA4\u4E92\u5F0F\u5BC6\u7801\u4FEE\u6539\uFF09", riskType: "script_execution" },
359
364
  { pattern: /\bpasswd\s+--stdin\b/i, severity: "high", description: "\u68C0\u6D4B\u5230 passwd --stdin \u975E\u4EA4\u4E92\u5F0F\u5BC6\u7801\u8F93\u5165", riskType: "script_execution" },
360
365
  { pattern: /\bchpasswd\b/i, severity: "high", description: "\u68C0\u6D4B\u5230 chpasswd \u6279\u91CF\u5BC6\u7801\u4FEE\u6539\u547D\u4EE4", riskType: "script_execution" },
361
- { pattern: /\bnewusers\b/i, severity: "high", description: "\u68C0\u6D4B\u5230 newusers \u6279\u91CF\u7528\u6237\u6DFB\u52A0\u547D\u4EE4", riskType: "script_execution" },
366
+ { pattern: /\b(newusers|lnewusers)\b/i, severity: "high", description: "\u68C0\u6D4B\u5230 newusers/lnewusers \u6279\u91CF\u7528\u6237\u6DFB\u52A0\u547D\u4EE4", riskType: "script_execution" },
362
367
  { pattern: /\bpasswd\s+-[a-zA-Z]*d\b/i, severity: "high", description: "\u68C0\u6D4B\u5230\u5220\u9664\u7528\u6237\u5BC6\u7801\u64CD\u4F5C (passwd -d)", riskType: "script_execution" },
363
368
  { pattern: /\bpasswd\s+-[a-zA-Z]*l\b/i, severity: "high", description: "\u68C0\u6D4B\u5230\u9501\u5B9A\u7528\u6237\u8D26\u6237\u64CD\u4F5C (passwd -l)", riskType: "script_execution" },
364
369
  // --- High: non-interactive password modification (extended) ---
@@ -407,7 +412,9 @@ function runLogicCheck(input) {
407
412
  const pathResult = checkSensitivePath(actionDetail, resolvedCwd);
408
413
  if (pathResult) return pathResult;
409
414
  if (actionType !== "file_write" && actionType !== "file_edit") {
410
- if ((actionDetail.includes("*") || actionDetail.includes("?")) && ["rm ", "rm ", "del ", "del ", "delete", "remove ", "remove ", "\u5220\u9664", "\u79FB\u9664"].some((kw) => actionDetail.includes(kw))) {
415
+ const TEMP_DIRS = ["/tmp/", "/var/tmp/", "/run/", "/dev/shm/"];
416
+ const isTempPath = TEMP_DIRS.some((td) => actionDetail.includes(td));
417
+ if (!isTempPath && (actionDetail.includes("*") || actionDetail.includes("?")) && ["rm ", "rm ", "del ", "del ", "delete", "remove ", "remove ", "\u5220\u9664", "\u79FB\u9664"].some((kw) => actionDetail.includes(kw))) {
411
418
  return {
412
419
  allowed: false,
413
420
  reason: "\u68C0\u6D4B\u5230\u901A\u914D\u7B26\u7ED3\u5408\u5220\u9664\u64CD\u4F5C\uFF0C\u53EF\u80FD\u9020\u6210\u6279\u91CF\u8BEF\u5220",
@@ -634,6 +641,7 @@ var init_logic_rules = __esm({
634
641
  ROOT_SENSITIVE_PATHS = [
635
642
  { path: "/etc/shadow", riskLevel: "critical", desc: "\u7CFB\u7EDF\u5BC6\u7801\u6587\u4EF6" },
636
643
  { path: "/etc/gshadow", riskLevel: "critical", desc: "\u7CFB\u7EDF\u7EC4\u5BC6\u7801\u6587\u4EF6" },
644
+ // 注意:/etc/passwd 仅从 L1 启发式规则移除(公开可读),L2 敏感路径仍保留
637
645
  { path: "/etc/passwd", riskLevel: "high", desc: "\u7CFB\u7EDF\u7528\u6237\u6587\u4EF6" },
638
646
  { path: "/etc/sudoers", riskLevel: "critical", desc: "sudo \u914D\u7F6E" },
639
647
  { path: "/etc/hosts", riskLevel: "medium", desc: "DNS \u89E3\u6790\u914D\u7F6E" },
@@ -673,7 +681,7 @@ var init_logic_rules = __esm({
673
681
  /\bpasswd\s+--stdin\b/i,
674
682
  /\bchpasswd\b/i,
675
683
  /\bchgpasswd\b/i,
676
- /\bnewusers\b/i,
684
+ /\b(newusers|lnewusers)\b/i,
677
685
  /\bpasswd\s+-[a-zA-Z]*d\b/i,
678
686
  /\bpasswd\s+-[a-zA-Z]*l\b/i
679
687
  ];
@@ -1392,6 +1400,15 @@ init_esm_shims();
1392
1400
  // src/models.ts
1393
1401
  init_esm_shims();
1394
1402
  import { z } from "zod";
1403
+
1404
+ // src/package-json.ts
1405
+ init_esm_shims();
1406
+ import { createRequire } from "module";
1407
+ var require2 = createRequire(import.meta.url);
1408
+ var pkg = require2("../package.json");
1409
+ var version = pkg.version;
1410
+
1411
+ // src/models.ts
1395
1412
  var ActionItemSchema = z.object({
1396
1413
  action_type: z.string().describe("Action type, e.g. bash, file_read, file_write"),
1397
1414
  action_detail: z.string().describe("Action detail / command content")
@@ -1419,7 +1436,7 @@ var AnalyzeResponseSchema = z.object({
1419
1436
  });
1420
1437
  var HealthResponseSchema = z.object({
1421
1438
  status: z.string().default("healthy"),
1422
- version: z.string().default("0.2.0")
1439
+ version: z.string().default(version)
1423
1440
  });
1424
1441
 
1425
1442
  // src/routes.ts
@@ -1609,7 +1626,7 @@ function createApp() {
1609
1626
 
1610
1627
  // src/cli.ts
1611
1628
  function printHelp() {
1612
- console.log(`AgentMoss security analysis engine (TypeScript v0.2.0)
1629
+ console.log(`AgentMoss security analysis engine (TypeScript v${version})
1613
1630
 
1614
1631
  Commands:
1615
1632
  init Generate input.json template
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","../src/actrail.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 fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport 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/** Read config from file (JSON), returns parsed object or null */\nfunction loadConfigFile(filePath: string): Record<string, any> | null {\n try {\n const raw = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\n/** Determine config file path with priority:\n * 1. AGENT_MOSS_CONFIG_PATH env var\n * 2. ~/.config/agentmoss/config.json (auto-create if missing)\n * 3. Package default (relative to __dirname)\n */\nfunction resolveConfigPath(): string {\n const envPath = process.env.AGENT_MOSS_CONFIG_PATH;\n if (envPath) return envPath;\n\n const userConfig = path.join(os.homedir(), '.config', 'agentmoss', 'config.json');\n if (fs.existsSync(userConfig)) return userConfig;\n\n // Auto-create from package default\n const defaultConfig = path.join(__dirname, '..', '..', 'agent_moss', 'infra', 'config.json.example');\n if (fs.existsSync(defaultConfig)) {\n const configDir = path.dirname(userConfig);\n fs.mkdirSync(configDir, { recursive: true });\n // Read the default config and filter out the api_key for safety\n const pkgConfig = loadConfigFile(defaultConfig);\n const safeConfig = pkgConfig ? { ...pkgConfig, llm: { ...pkgConfig.llm, api_key: '' } } : {};\n fs.writeFileSync(userConfig, JSON.stringify(safeConfig, null, 4), 'utf-8');\n console.log(`[AgentMoss] 已创建用户配置文件: ${userConfig}`);\n console.log(`[AgentMoss] 请编辑该文件配置你的 LLM API Key`);\n }\n return userConfig;\n}\n\n/** Load LLM config from file, merged with environment variables (env wins) */\nfunction loadLLMConfigFromFile(configPath: string): Partial<LLMConfig> {\n const data = loadConfigFile(configPath);\n if (!data?.llm) return {};\n\n const llm = data.llm;\n return {\n provider: llm.provider || '',\n baseUrl: llm.base_url || '',\n apiKey: llm.api_key || '',\n model: llm.model || '',\n temperature: llm.temperature ?? 0.1,\n maxTokens: llm.max_tokens ?? 4096,\n timeout: llm.timeout ?? 300,\n };\n}\n\n/** Global LLM configuration, initialized from file + env vars (env wins) */\nlet llmConfig: LLMConfig = (() => {\n const configPath = resolveConfigPath();\n const fileConfig = fs.existsSync(configPath) ? loadLLMConfigFromFile(configPath) : {};\n\n return {\n provider: process.env.AGENT_MOSS_LLM_PROVIDER || fileConfig.provider || 'openai',\n baseUrl: process.env.AGENT_MOSS_LLM_BASE_URL || fileConfig.baseUrl || 'https://api.openai.com/v1',\n apiKey: process.env.AGENT_MOSS_LLM_API_KEY || process.env.OPENAI_API_KEY || fileConfig.apiKey || '',\n model: process.env.AGENT_MOSS_LLM_MODEL || fileConfig.model || 'gpt-4o',\n temperature: parseFloat(process.env.AGENT_MOSS_LLM_TEMPERATURE || String(fileConfig.temperature ?? '0.1')),\n maxTokens: parseInt(process.env.AGENT_MOSS_LLM_MAX_TOKENS || String(fileConfig.maxTokens ?? '4096'), 10),\n timeout: parseInt(process.env.AGENT_MOSS_LLM_TIMEOUT || String(fileConfig.timeout ?? '300'), 10),\n };\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)\nexport const 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: /\\/etc\\/gshadow/i, severity: 'critical', description: '访问系统组密码文件 (/etc/gshadow)', 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 // --- High: non-interactive password modification ---\n { pattern: /\\|\\s*passwd\\b/i, severity: 'high', description: '检测到管道方式调用 passwd(非交互式密码修改)', riskType: 'script_execution' },\n { pattern: /\\bpasswd\\s+--stdin\\b/i, severity: 'high', description: '检测到 passwd --stdin 非交互式密码输入', riskType: 'script_execution' },\n { pattern: /\\bchpasswd\\b/i, severity: 'high', description: '检测到 chpasswd 批量密码修改命令', riskType: 'script_execution' },\n { pattern: /\\bnewusers\\b/i, severity: 'high', description: '检测到 newusers 批量用户添加命令', riskType: 'script_execution' },\n { pattern: /\\bpasswd\\s+-[a-zA-Z]*d\\b/i, severity: 'high', description: '检测到删除用户密码操作 (passwd -d)', riskType: 'script_execution' },\n { pattern: /\\bpasswd\\s+-[a-zA-Z]*l\\b/i, severity: 'high', description: '检测到锁定用户账户操作 (passwd -l)', riskType: 'script_execution' },\n // --- High: non-interactive password modification (extended) ---\n { pattern: /\\blpasswd\\s/i, severity: 'high', description: '检测到非交互式密码修改操作 (lpasswd)', riskType: 'script_execution' },\n { pattern: /\\bgpasswd\\s+(?!-[adA])/i, severity: 'high', description: '检测到组密码管理操作 (gpasswd)', riskType: 'script_execution' },\n { pattern: /\\bchgpasswd\\b/i, severity: 'high', description: '检测到批量修改组密码操作 (chgpasswd)', riskType: 'script_execution' },\n // --- High: user/group deletion (irreversible, requires user consent) ---\n { pattern: /\\buserdel\\s/i, severity: 'high', description: '检测到删除系统用户操作 (userdel)', riskType: 'script_execution' },\n { pattern: /\\bdeluser\\s/i, severity: 'high', description: '检测到删除系统用户操作 (deluser)', riskType: 'script_execution' },\n { pattern: /\\bluserdel\\s/i, severity: 'high', description: '检测到删除系统用户操作 (luserdel)', riskType: 'script_execution' },\n { pattern: /\\bgroupdel\\s/i, severity: 'high', description: '检测到删除用户组操作 (groupdel)', riskType: 'script_execution' },\n { pattern: /\\blgroupdel\\s/i, severity: 'high', description: '检测到删除用户组操作 (lgroupdel)', riskType: 'script_execution' },\n // --- High: generic command -p parameter password setting ---\n { pattern: /\\b(useradd|luseradd|groupadd|usermod|lusermod|groupmod|lgroupmod)\\b[^&|;]*?\\s-p\\b/i, severity: 'high', description: '检测到通过 -p 参数设置或修改密码 (useradd/usermod/groupmod)', riskType: 'script_execution' },\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/gshadow', 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// Read-only commands that use > for output redirection (not write intent)\nconst READ_ONLY_REDIR_CMDS = new Set(['cat', 'head', 'tail', 'less', 'more', 'grep', 'find', 'awk', 'sed', 'sort', 'uniq', 'wc', 'cut', 'strings', 'od', 'xxd', 'hexdump']);\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// Non-interactive password modification patterns\nconst PASSWORD_MODIFY_PATTERNS: RegExp[] = [\n /\\|\\s*passwd\\b/i,\n /\\bpasswd\\s+--stdin\\b/i,\n /\\bchpasswd\\b/i,\n /\\bchgpasswd\\b/i,\n /\\bnewusers\\b/i,\n /\\bpasswd\\s+-[a-zA-Z]*d\\b/i,\n /\\bpasswd\\s+-[a-zA-Z]*l\\b/i,\n];\n\n// Non-interactive user/group deletion patterns\nconst USER_DELETION_PATTERNS: RegExp[] = [\n /\\buserdel\\s/i,\n /\\bdeluser\\s/i,\n /\\bluserdel\\s/i,\n /\\bgroupdel\\s/i,\n /\\blgroupdel\\s/i,\n];\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 // Rule 7: Non-interactive password modification consent check\n const pwdResult = checkPasswordConsent(actionType, actionDetail, actionHistory);\n if (pwdResult) return pwdResult;\n\n // Rule 8: User/group deletion consent check\n const userDelResult = checkUserDeletionConsent(actionType, actionDetail, actionHistory);\n if (userDelResult) return userDelResult;\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 let isWrite = WRITE_KEYWORDS.some(kw => actionType.includes(kw) || actionDetail.includes(kw));\n\n // 补充检测 shell 重定向写入(>、>>)\n // 排除只读命令后的重定向(如 cat file > /dev/null 不是写入意图)\n if (!isWrite && actionDetail.includes('>')) {\n const firstWord = actionDetail.split(/\\s/)[0]?.toLowerCase() || '';\n if (!READ_ONLY_REDIR_CMDS.has(firstWord)) {\n isWrite = true;\n }\n }\n\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\nfunction checkPasswordConsent(\n actionType: string, actionDetail: string,\n actionHistory: { actionType: string; actionDetail: string }[]\n): SecurityJudgment | null {\n if (actionType !== 'bash') return null;\n\n const isPasswordModify = PASSWORD_MODIFY_PATTERNS.some(p => p.test(actionDetail));\n if (!isPasswordModify) return null;\n\n // 检查 action_history 中是否有 ask_user_question 且用户返回了答案\n const hasConsent = actionHistory.some(h =>\n h.actionType.toLowerCase() === 'ask_user_question' && h.actionDetail.trim().length > 0\n );\n if (hasConsent) return null;\n\n return {\n allowed: false,\n reason: '执行非交互式密码修改命令,但历史执行序列中未发现向用户确认密码的 ask_user_question 操作,可能存在未授权的密码修改风险',\n riskLevel: 'high',\n riskType: 'consent_missing',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n}\n\nfunction checkUserDeletionConsent(\n actionType: string, actionDetail: string,\n actionHistory: { actionType: string; actionDetail: string }[]\n): SecurityJudgment | null {\n if (actionType !== 'bash') return null;\n\n const isUserDeletion = USER_DELETION_PATTERNS.some(p => p.test(actionDetail));\n if (!isUserDeletion) return null;\n\n // 检查 action_history 中是否有 ask_user_question 且用户确认了\n const hasConsent = actionHistory.some(h =>\n h.actionType.toLowerCase() === 'ask_user_question' && h.actionDetail.trim().length > 0\n );\n if (hasConsent) return null;\n\n return {\n allowed: false,\n reason: '执行删除系统用户命令,但历史执行序列中未发现向用户确认的 ask_user_question 操作,可能存在未授权的用户删除风险',\n riskLevel: 'high',\n riskType: 'consent_missing',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\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, DANGEROUS_PATTERNS } 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/** 内置安全 Skill 白名单:加载时直接放行 */\nconst TRUSTED_SKILLS = new Set(['xiaoo-guardian']);\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 /^whoami(?:\\s|$)/i, /^id(?:\\s|$)/i,\n /^hostname(?:\\s|$)/i, /^uname(?:\\s|$)/i,\n /^date(?:\\s|$)/i, /^env(?:\\s|$)/i,\n /^printenv(?:\\s|$)/i, /^tty(?:\\s|$)/i,\n /^arch(?:\\s|$)/i, /^uptime(?:\\s|$)/i,\n /^groups(?:\\s|$)/i, /^logname(?:\\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 // 内置安全 Skill 直接放行(如 xiaoo-guardian)\n if (actionType === 'skill' && TRUSTED_SKILLS.has(lowerDetail)) {\n return {\n allowed: true,\n reason: `内置安全 Skill,跳过深度分析: ${lowerDetail}`,\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 // 安全兜底:检查完整命令是否命中高危模式(如 echo ... | passwd)\n const fullCmdHit = DANGEROUS_PATTERNS.some(p =>\n p.severity === 'critical' || p.severity === 'high'\n ) && DANGEROUS_PATTERNS.some(p =>\n (p.severity === 'critical' || p.severity === 'high') && p.pattern.test(lowerDetail)\n );\n if (!fullCmdHit) {\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 }\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';\nimport { reportEnforcementEvent } from './actrail';\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 // Report enforcement event to AcTrail (fire-and-forget)\n try {\n reportEnforcementEvent({\n traceId: req.session_id,\n decision: result.allowed ? 'allow' : 'deny',\n toolName: req.a_next.action_type,\n toolCommand: req.a_next.action_detail,\n sessionId: req.session_id,\n prompt: req.prompt_session,\n riskLevel: result.riskLevel,\n riskType: result.riskType,\n reason: result.reason,\n violatedLayers: result.violatedLayers,\n confidence: result.confidence,\n durationMs: Math.round(durationMs * 10) / 10,\n });\n } catch { /* non-fatal, never block response */ }\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\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","/**\n * AcTrail enforcement event reporter for TypeScript.\n *\n * Writes AgentMoss allow/deny decisions as Enforcement events to AcTrail's\n * SQLite storage, enabling unified agent behavior audit trails.\n *\n * Configuration (environment variables):\n * ACTRAIL_ENABLED: Set to \"1\" to enable reporting (default: disabled)\n * ACTRAIL_STORAGE_PATH: Path to AcTrail SQLite DB (default: /tmp/actrail.sqlite)\n * ACTRAIL_TIMEOUT_MS: Write timeout in milliseconds (default: 100)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/** AcTrail key=value escape (mirrors Rust encode_map) */\nfunction escape(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, '\\\\n').replace(/=/g, '\\\\e');\n}\n\n/** Convert session_id string to u64 trace_id (SHA-256 based, masked to signed 64-bit) */\nfunction sessionToTraceId(sessionId: string): number {\n // Simple hash - not cryptographic, but sufficient for ID generation\n let hash = 0;\n for (let i = 0; i < sessionId.length; i++) {\n const char = sessionId.charCodeAt(i);\n hash = ((hash << 5) - hash + char) | 0;\n }\n // Combine with length for better distribution, mask to signed 64-bit\n return Math.abs((hash * 31 + sessionId.length) % Number.MAX_SAFE_INTEGER);\n}\n\nexport interface ActrailReportOptions {\n traceId: string;\n decision: 'allow' | 'deny';\n toolName: string;\n toolCommand: string;\n sessionId: string;\n prompt?: string;\n riskLevel?: string;\n riskType?: string;\n reason?: string;\n violatedLayers?: string[];\n confidence?: number;\n durationMs?: number;\n}\n\nlet dbConnected = false;\nlet dbPath = '';\n\nfunction isEnabled(): boolean {\n return process.env.ACTRAIL_ENABLED === '1' || process.env.ACTRAIL_ENABLED === 'true';\n}\n\nfunction getStoragePath(): string {\n return process.env.ACTRAIL_STORAGE_PATH || '/tmp/actrail.sqlite';\n}\n\n/**\n * Report an enforcement event to AcTrail (fire-and-forget).\n * Returns true if written, false if disabled or write failed.\n */\nexport function reportEnforcementEvent(opts: ActrailReportOptions): boolean {\n if (!isEnabled()) return false;\n\n const storagePath = getStoragePath();\n if (!fs.existsSync(storagePath)) return false;\n\n try {\n // Dynamic import - better-sqlite3 is an optional dependency\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n let Database: any;\n try {\n Database = require('better-sqlite3');\n } catch {\n console.debug('[AgentMoss] better-sqlite3 not installed, AcTrail reporting disabled');\n return false;\n }\n\n const db = new Database(storagePath, { timeout: 100, readonly: false });\n\n // Verify events table exists\n const tableCheck = db.prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='events'\"\n ).get();\n if (!tableCheck) {\n db.close();\n return false;\n }\n\n const nowNs = BigInt(Date.now()) * 1000000n;\n const eventId = Number(nowNs % BigInt(2 ** 62));\n const traceIdInt = sessionToTraceId(opts.traceId);\n\n // Build payload fields in AcTrail's key=value format\n const rawFields: Record<string, string> = {\n 'backend': 'agent-moss',\n 'operation': 'tool_call',\n 'decision': opts.decision,\n 'result': opts.decision === 'allow' ? 'allowed' : 'denied',\n 'tool.name': opts.toolName,\n 'tool.command': (opts.toolCommand || '').slice(0, 500),\n 'agent.session_id': opts.sessionId,\n 'agent.prompt': (opts.prompt || '').slice(0, 500),\n 'risk.level': opts.riskLevel || '',\n 'risk.type': opts.riskType || '',\n 'reason': (opts.reason || '').slice(0, 500),\n 'violated_layers': (opts.violatedLayers || []).join(','),\n 'confidence': String(opts.confidence ?? 100),\n 'duration_ms': (opts.durationMs ?? 0).toFixed(1),\n };\n const payloadFields = Object.entries(rawFields)\n .map(([k, v]) => `${escape(k)}=${escape(v)}`)\n .join('\\n');\n\n db.prepare(`\n INSERT OR REPLACE INTO events (\n event_id, trace_id, observed_at,\n process_pid, process_task_id, process_start_ticks,\n process_pid_namespace, process_generation,\n collector, kind,\n bootstrap_observed, metadata_partial, policy_modified,\n payload_variant, payload_fields, payload_bytes,\n policy_verdict, policy_note,\n policy_redactions, policy_truncations\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n eventId,\n traceIdInt,\n Number(nowNs),\n process.pid,\n 0,\n 0,\n null,\n 0,\n 'agent-moss',\n 'enforcement',\n 0,\n 0,\n 0,\n 'enforcement',\n payloadFields,\n '',\n opts.decision === 'allow' ? 'allow' : 'drop',\n opts.reason || '',\n '[]',\n '[]'\n );\n\n db.close();\n return true;\n } catch (err) {\n // Non-fatal - never block the response\n console.debug(`[AgentMoss] AcTrail write failed (non-fatal): ${(err as Error).message}`);\n return false;\n }\n}\n"],"mappings":"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","names":["path","fs","path","existsSync","fileURLToPath","__filename","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","resolve","main","fs","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","../src/package-json.ts","../src/actrail.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 fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport 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/** Read config from file (JSON), returns parsed object or null */\nfunction loadConfigFile(filePath: string): Record<string, any> | null {\n try {\n const raw = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\n/** Determine config file path with priority:\n * 1. AGENT_MOSS_CONFIG_PATH env var\n * 2. ~/.config/agentmoss/config.json (auto-create if missing)\n * 3. Package default (relative to __dirname)\n */\nfunction resolveConfigPath(): string {\n const envPath = process.env.AGENT_MOSS_CONFIG_PATH;\n if (envPath) return envPath;\n\n const userConfig = path.join(os.homedir(), '.config', 'agentmoss', 'config.json');\n if (fs.existsSync(userConfig)) return userConfig;\n\n // Auto-create from package default\n const defaultConfig = path.join(__dirname, '..', '..', 'agent_moss', 'infra', 'config.json.example');\n if (fs.existsSync(defaultConfig)) {\n const configDir = path.dirname(userConfig);\n fs.mkdirSync(configDir, { recursive: true });\n // Read the default config and filter out the api_key for safety\n const pkgConfig = loadConfigFile(defaultConfig);\n const safeConfig = pkgConfig ? { ...pkgConfig, llm: { ...pkgConfig.llm, api_key: '' } } : {};\n fs.writeFileSync(userConfig, JSON.stringify(safeConfig, null, 4), 'utf-8');\n console.log(`[AgentMoss] 已创建用户配置文件: ${userConfig}`);\n console.log(`[AgentMoss] 请编辑该文件配置你的 LLM API Key`);\n }\n return userConfig;\n}\n\n/** Load LLM config from file, merged with environment variables (env wins) */\nfunction loadLLMConfigFromFile(configPath: string): Partial<LLMConfig> {\n const data = loadConfigFile(configPath);\n if (!data?.llm) return {};\n\n const llm = data.llm;\n return {\n provider: llm.provider || '',\n baseUrl: llm.base_url || '',\n apiKey: llm.api_key || '',\n model: llm.model || '',\n temperature: llm.temperature ?? 0.1,\n maxTokens: llm.max_tokens ?? 4096,\n timeout: llm.timeout ?? 300,\n };\n}\n\n/** Global LLM configuration, initialized from file + env vars (env wins) */\nlet llmConfig: LLMConfig = (() => {\n const configPath = resolveConfigPath();\n const fileConfig = fs.existsSync(configPath) ? loadLLMConfigFromFile(configPath) : {};\n\n return {\n provider: process.env.AGENT_MOSS_LLM_PROVIDER || fileConfig.provider || 'openai',\n baseUrl: process.env.AGENT_MOSS_LLM_BASE_URL || fileConfig.baseUrl || 'https://api.openai.com/v1',\n apiKey: process.env.AGENT_MOSS_LLM_API_KEY || process.env.OPENAI_API_KEY || fileConfig.apiKey || '',\n model: process.env.AGENT_MOSS_LLM_MODEL || fileConfig.model || 'gpt-4o',\n temperature: parseFloat(process.env.AGENT_MOSS_LLM_TEMPERATURE || String(fileConfig.temperature ?? '0.1')),\n maxTokens: parseInt(process.env.AGENT_MOSS_LLM_MAX_TOKENS || String(fileConfig.maxTokens ?? '4096'), 10),\n timeout: parseInt(process.env.AGENT_MOSS_LLM_TIMEOUT || String(fileConfig.timeout ?? '300'), 10),\n };\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)\nexport const 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 (含通配符如 /* /.* 等) — 使用负向先行断言 (?!\\w):/ 后面不是单词字符时匹配\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*\\s+\\/(?!\\w)/i, severity: 'critical', description: '递归强制删除根目录 (rm -rf /)', riskType: 'script_execution' },\n // 注意:已移除\"rm -rf /任意绝对路径\"的宽泛规则,避免误杀 /tmp 等临时目录清理操作\n // 2. 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 // 3. 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 // 4. 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 // dd 磁盘清零 — 只拦截写入系统关键目录,放行 /tmp 等临时目录\n { pattern: /dd\\s+if=\\/dev\\/zero.*\\bof\\s*=\\s*\\/(etc|var|home|usr|boot|root|opt|srv|sys|proc)\\b/i, severity: 'critical', description: '磁盘清零写入关键系统目录 (dd if=/dev/zero of=/系统目录)', riskType: 'script_execution' },\n // mkfs 格式化 — 只拦截对块设备(/dev/sdX 等)的格式化,放行对普通文件的格式化\n { pattern: /mkfs\\.\\w+\\s+\\/dev\\/(sd|hd|nvme|vd|loop|mapper|md|dm)\\S+/i, severity: 'critical', description: '格式化块设备 (mkfs /dev/块设备)', 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: /\\/etc\\/gshadow/i, severity: 'critical', description: '访问系统组密码文件 (/etc/gshadow)', riskType: 'file_access' },\n // 注意:/etc/passwd 已从拦截列表移除,因为它是公开可读的标准系统文件,真正敏感的是 /etc/shadow\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 // sudo 提权 — 只拦截 sudo 后跟的危险命令,不一刀切拦截所有 sudo\n { pattern: /sudo\\s+(rm|chmod|chown|dd|mkfs|format|iptables|crontab|passwd|userdel|useradd|groupdel)\\b/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 // --- Medium: destructive git operations (降级为 medium,允许但记录) ---\n { pattern: /git\\s+push\\s+.*--force/i, severity: 'medium', description: '强制推送操作 (git push --force),可能覆盖远程提交历史', riskType: 'script_execution' },\n // --- High: network port scanning (横向移动侦察) ---\n { pattern: /\\bnmap\\s+/i, severity: 'high', description: '网络端口扫描 (nmap),可能用于横向移动侦察', riskType: 'lateral_movement' },\n { pattern: /\\b(masscan|zmap|unicornscan)\\s+/i, severity: 'high', description: '网络端口扫描工具,可能用于横向移动侦察', riskType: 'lateral_movement' },\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 write (只拦截重定向写入设备文件,不拦截读取) ---\n { pattern: />\\s*\\/dev\\/(sd|hd|nvme|vd|loop|mem|kmsg|port|zero|random|urandom|full|core)/i, severity: 'high', description: '重定向写入设备文件', riskType: 'file_access' },\n // --- High: non-interactive password modification ---\n { pattern: /\\|\\s*passwd\\b/i, severity: 'high', description: '检测到管道方式调用 passwd(非交互式密码修改)', riskType: 'script_execution' },\n { pattern: /\\bpasswd\\s+--stdin\\b/i, severity: 'high', description: '检测到 passwd --stdin 非交互式密码输入', riskType: 'script_execution' },\n { pattern: /\\bchpasswd\\b/i, severity: 'high', description: '检测到 chpasswd 批量密码修改命令', riskType: 'script_execution' },\n { pattern: /\\b(newusers|lnewusers)\\b/i, severity: 'high', description: '检测到 newusers/lnewusers 批量用户添加命令', riskType: 'script_execution' },\n { pattern: /\\bpasswd\\s+-[a-zA-Z]*d\\b/i, severity: 'high', description: '检测到删除用户密码操作 (passwd -d)', riskType: 'script_execution' },\n { pattern: /\\bpasswd\\s+-[a-zA-Z]*l\\b/i, severity: 'high', description: '检测到锁定用户账户操作 (passwd -l)', riskType: 'script_execution' },\n // --- High: non-interactive password modification (extended) ---\n { pattern: /\\blpasswd\\s/i, severity: 'high', description: '检测到非交互式密码修改操作 (lpasswd)', riskType: 'script_execution' },\n { pattern: /\\bgpasswd\\s+(?!-[adA])/i, severity: 'high', description: '检测到组密码管理操作 (gpasswd)', riskType: 'script_execution' },\n { pattern: /\\bchgpasswd\\b/i, severity: 'high', description: '检测到批量修改组密码操作 (chgpasswd)', riskType: 'script_execution' },\n // --- High: user/group deletion (irreversible, requires user consent) ---\n { pattern: /\\buserdel\\s/i, severity: 'high', description: '检测到删除系统用户操作 (userdel)', riskType: 'script_execution' },\n { pattern: /\\bdeluser\\s/i, severity: 'high', description: '检测到删除系统用户操作 (deluser)', riskType: 'script_execution' },\n { pattern: /\\bluserdel\\s/i, severity: 'high', description: '检测到删除系统用户操作 (luserdel)', riskType: 'script_execution' },\n { pattern: /\\bgroupdel\\s/i, severity: 'high', description: '检测到删除用户组操作 (groupdel)', riskType: 'script_execution' },\n { pattern: /\\blgroupdel\\s/i, severity: 'high', description: '检测到删除用户组操作 (lgroupdel)', riskType: 'script_execution' },\n // --- High: generic command -p parameter password setting ---\n { pattern: /\\b(useradd|luseradd|groupadd|usermod|lusermod|groupmod|lgroupmod)\\b[^&|;]*?\\s-p\\b/i, severity: 'high', description: '检测到通过 -p 参数设置或修改密码 (useradd/usermod/groupmod)', riskType: 'script_execution' },\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/gshadow', riskLevel: 'critical', desc: '系统组密码文件' },\n // 注意:/etc/passwd 仅从 L1 启发式规则移除(公开可读),L2 敏感路径仍保留\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// Read-only commands that use > for output redirection (not write intent)\nconst READ_ONLY_REDIR_CMDS = new Set(['cat', 'head', 'tail', 'less', 'more', 'grep', 'find', 'awk', 'sed', 'sort', 'uniq', 'wc', 'cut', 'strings', 'od', 'xxd', 'hexdump']);\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// Non-interactive password modification patterns\nconst PASSWORD_MODIFY_PATTERNS: RegExp[] = [\n /\\|\\s*passwd\\b/i,\n /\\bpasswd\\s+--stdin\\b/i,\n /\\bchpasswd\\b/i,\n /\\bchgpasswd\\b/i,\n /\\b(newusers|lnewusers)\\b/i,\n /\\bpasswd\\s+-[a-zA-Z]*d\\b/i,\n /\\bpasswd\\s+-[a-zA-Z]*l\\b/i,\n];\n\n// Non-interactive user/group deletion patterns\nconst USER_DELETION_PATTERNS: RegExp[] = [\n /\\buserdel\\s/i,\n /\\bdeluser\\s/i,\n /\\bluserdel\\s/i,\n /\\bgroupdel\\s/i,\n /\\blgroupdel\\s/i,\n];\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 — 排除 /tmp 等临时目录的清理操作\n const TEMP_DIRS = ['/tmp/', '/var/tmp/', '/run/', '/dev/shm/'];\n const isTempPath = TEMP_DIRS.some(td => actionDetail.includes(td));\n if (!isTempPath && (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 // Rule 7: Non-interactive password modification consent check\n const pwdResult = checkPasswordConsent(actionType, actionDetail, actionHistory);\n if (pwdResult) return pwdResult;\n\n // Rule 8: User/group deletion consent check\n const userDelResult = checkUserDeletionConsent(actionType, actionDetail, actionHistory);\n if (userDelResult) return userDelResult;\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 let isWrite = WRITE_KEYWORDS.some(kw => actionType.includes(kw) || actionDetail.includes(kw));\n\n // 补充检测 shell 重定向写入(>、>>)\n // 排除只读命令后的重定向(如 cat file > /dev/null 不是写入意图)\n if (!isWrite && actionDetail.includes('>')) {\n const firstWord = actionDetail.split(/\\s/)[0]?.toLowerCase() || '';\n if (!READ_ONLY_REDIR_CMDS.has(firstWord)) {\n isWrite = true;\n }\n }\n\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\nfunction checkPasswordConsent(\n actionType: string, actionDetail: string,\n actionHistory: { actionType: string; actionDetail: string }[]\n): SecurityJudgment | null {\n if (actionType !== 'bash') return null;\n\n const isPasswordModify = PASSWORD_MODIFY_PATTERNS.some(p => p.test(actionDetail));\n if (!isPasswordModify) return null;\n\n // 检查 action_history 中是否有 ask_user_question 且用户返回了答案\n const hasConsent = actionHistory.some(h =>\n h.actionType.toLowerCase() === 'ask_user_question' && h.actionDetail.trim().length > 0\n );\n if (hasConsent) return null;\n\n return {\n allowed: false,\n reason: '执行非交互式密码修改命令,但历史执行序列中未发现向用户确认密码的 ask_user_question 操作,可能存在未授权的密码修改风险',\n riskLevel: 'high',\n riskType: 'consent_missing',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n}\n\nfunction checkUserDeletionConsent(\n actionType: string, actionDetail: string,\n actionHistory: { actionType: string; actionDetail: string }[]\n): SecurityJudgment | null {\n if (actionType !== 'bash') return null;\n\n const isUserDeletion = USER_DELETION_PATTERNS.some(p => p.test(actionDetail));\n if (!isUserDeletion) return null;\n\n // 检查 action_history 中是否有 ask_user_question 且用户确认了\n const hasConsent = actionHistory.some(h =>\n h.actionType.toLowerCase() === 'ask_user_question' && h.actionDetail.trim().length > 0\n );\n if (hasConsent) return null;\n\n return {\n allowed: false,\n reason: '执行删除系统用户命令,但历史执行序列中未发现向用户确认的 ask_user_question 操作,可能存在未授权的用户删除风险',\n riskLevel: 'high',\n riskType: 'consent_missing',\n confidence: 85,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\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, DANGEROUS_PATTERNS } 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/** 内置安全 Skill 白名单:加载时直接放行 */\nconst TRUSTED_SKILLS = new Set(['xiaoo-guardian']);\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 /^whoami(?:\\s|$)/i, /^id(?:\\s|$)/i,\n /^hostname(?:\\s|$)/i, /^uname(?:\\s|$)/i,\n /^date(?:\\s|$)/i, /^env(?:\\s|$)/i,\n /^printenv(?:\\s|$)/i, /^tty(?:\\s|$)/i,\n /^arch(?:\\s|$)/i, /^uptime(?:\\s|$)/i,\n /^groups(?:\\s|$)/i, /^logname(?:\\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 // 内置安全 Skill 直接放行(如 xiaoo-guardian)\n if (actionType === 'skill' && TRUSTED_SKILLS.has(lowerDetail)) {\n return {\n allowed: true,\n reason: `内置安全 Skill,跳过深度分析: ${lowerDetail}`,\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 // 安全兜底:检查完整命令是否命中高危模式(如 echo ... | passwd)\n const fullCmdHit = DANGEROUS_PATTERNS.some(p =>\n p.severity === 'critical' || p.severity === 'high'\n ) && DANGEROUS_PATTERNS.some(p =>\n (p.severity === 'critical' || p.severity === 'high') && p.pattern.test(lowerDetail)\n );\n if (!fullCmdHit) {\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 }\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';\nimport { version } from './package-json.js';\n\nfunction printHelp(): void {\n console.log(`AgentMoss security analysis engine (TypeScript v${version})\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';\nimport { reportEnforcementEvent } from './actrail';\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 // Report enforcement event to AcTrail (fire-and-forget)\n try {\n reportEnforcementEvent({\n traceId: req.session_id,\n decision: result.allowed ? 'allow' : 'deny',\n toolName: req.a_next.action_type,\n toolCommand: req.a_next.action_detail,\n sessionId: req.session_id,\n prompt: req.prompt_session,\n riskLevel: result.riskLevel,\n riskType: result.riskType,\n reason: result.reason,\n violatedLayers: result.violatedLayers,\n confidence: result.confidence,\n durationMs: Math.round(durationMs * 10) / 10,\n });\n } catch { /* non-fatal, never block response */ }\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\n","import { z } from 'zod';\nimport { version as PACKAGE_VERSION } from './package-json.js';\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(PACKAGE_VERSION),\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","/**\n * Single source of truth for the package version.\n * Read from package.json at runtime using createRequire — works in both ESM and bundled environments.\n */\nimport { createRequire } from 'module';\n\nconst require = createRequire(import.meta.url);\n// Resolve relative to this source file's location → ts/package.json\nconst pkg = require('../package.json');\n\n/** Version string from package.json — the ONLY place version is defined */\nexport const version: string = pkg.version;\n","/**\n * AcTrail enforcement event reporter for TypeScript.\n *\n * Writes AgentMoss allow/deny decisions as Enforcement events to AcTrail's\n * SQLite storage, enabling unified agent behavior audit trails.\n *\n * Configuration (environment variables):\n * ACTRAIL_ENABLED: Set to \"1\" to enable reporting (default: disabled)\n * ACTRAIL_STORAGE_PATH: Path to AcTrail SQLite DB (default: /tmp/actrail.sqlite)\n * ACTRAIL_TIMEOUT_MS: Write timeout in milliseconds (default: 100)\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/** AcTrail key=value escape (mirrors Rust encode_map) */\nfunction escape(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\\n/g, '\\\\n').replace(/=/g, '\\\\e');\n}\n\n/** Convert session_id string to u64 trace_id (SHA-256 based, masked to signed 64-bit) */\nfunction sessionToTraceId(sessionId: string): number {\n // Simple hash - not cryptographic, but sufficient for ID generation\n let hash = 0;\n for (let i = 0; i < sessionId.length; i++) {\n const char = sessionId.charCodeAt(i);\n hash = ((hash << 5) - hash + char) | 0;\n }\n // Combine with length for better distribution, mask to signed 64-bit\n return Math.abs((hash * 31 + sessionId.length) % Number.MAX_SAFE_INTEGER);\n}\n\nexport interface ActrailReportOptions {\n traceId: string;\n decision: 'allow' | 'deny';\n toolName: string;\n toolCommand: string;\n sessionId: string;\n prompt?: string;\n riskLevel?: string;\n riskType?: string;\n reason?: string;\n violatedLayers?: string[];\n confidence?: number;\n durationMs?: number;\n}\n\nlet dbConnected = false;\nlet dbPath = '';\n\nfunction isEnabled(): boolean {\n return process.env.ACTRAIL_ENABLED === '1' || process.env.ACTRAIL_ENABLED === 'true';\n}\n\nfunction getStoragePath(): string {\n return process.env.ACTRAIL_STORAGE_PATH || '/tmp/actrail.sqlite';\n}\n\n/**\n * Report an enforcement event to AcTrail (fire-and-forget).\n * Returns true if written, false if disabled or write failed.\n */\nexport function reportEnforcementEvent(opts: ActrailReportOptions): boolean {\n if (!isEnabled()) return false;\n\n const storagePath = getStoragePath();\n if (!fs.existsSync(storagePath)) return false;\n\n try {\n // Dynamic import - better-sqlite3 is an optional dependency\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n let Database: any;\n try {\n Database = require('better-sqlite3');\n } catch {\n console.debug('[AgentMoss] better-sqlite3 not installed, AcTrail reporting disabled');\n return false;\n }\n\n const db = new Database(storagePath, { timeout: 100, readonly: false });\n\n // Verify events table exists\n const tableCheck = db.prepare(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='events'\"\n ).get();\n if (!tableCheck) {\n db.close();\n return false;\n }\n\n const nowNs = BigInt(Date.now()) * 1000000n;\n const eventId = Number(nowNs % BigInt(2 ** 62));\n const traceIdInt = sessionToTraceId(opts.traceId);\n\n // Build payload fields in AcTrail's key=value format\n const rawFields: Record<string, string> = {\n 'backend': 'agent-moss',\n 'operation': 'tool_call',\n 'decision': opts.decision,\n 'result': opts.decision === 'allow' ? 'allowed' : 'denied',\n 'tool.name': opts.toolName,\n 'tool.command': (opts.toolCommand || '').slice(0, 500),\n 'agent.session_id': opts.sessionId,\n 'agent.prompt': (opts.prompt || '').slice(0, 500),\n 'risk.level': opts.riskLevel || '',\n 'risk.type': opts.riskType || '',\n 'reason': (opts.reason || '').slice(0, 500),\n 'violated_layers': (opts.violatedLayers || []).join(','),\n 'confidence': String(opts.confidence ?? 100),\n 'duration_ms': (opts.durationMs ?? 0).toFixed(1),\n };\n const payloadFields = Object.entries(rawFields)\n .map(([k, v]) => `${escape(k)}=${escape(v)}`)\n .join('\\n');\n\n db.prepare(`\n INSERT OR REPLACE INTO events (\n event_id, trace_id, observed_at,\n process_pid, process_task_id, process_start_ticks,\n process_pid_namespace, process_generation,\n collector, kind,\n bootstrap_observed, metadata_partial, policy_modified,\n payload_variant, payload_fields, payload_bytes,\n policy_verdict, policy_note,\n policy_redactions, policy_truncations\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n eventId,\n traceIdInt,\n Number(nowNs),\n process.pid,\n 0,\n 0,\n null,\n 0,\n 'agent-moss',\n 'enforcement',\n 0,\n 0,\n 0,\n 'enforcement',\n payloadFields,\n '',\n opts.decision === 'allow' ? 'allow' : 'drop',\n opts.reason || '',\n '[]',\n '[]'\n );\n\n db.close();\n return true;\n } catch (err) {\n // Non-fatal - never block the response\n console.debug(`[AgentMoss] AcTrail write failed (non-fatal): ${(err as Error).message}`);\n return false;\n }\n}\n"],"mappings":"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","names":["path","fs","path","existsSync","fileURLToPath","__filename","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","resolve","main","require","fs","fs","path","runAnalysis"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenhkl/agent-moss",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "description": "Multi-layer security analysis engine for AI agents (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",