@kenhkl/agent-moss 0.8.1 → 0.8.2
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/dist/cli.js +104 -0
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/config.ts","../src/agents/index.ts","../src/engine/heuristic.ts","../src/engine/inline-analyzer.ts","../src/engine/logic-rules.ts","../src/engine/skill-loader.ts","../src/engine/template-loader.ts","../src/engine/script-analyzer.ts","../src/engine/script-content-analyzer.ts","../src/engine/token-stats.ts","../src/engine/llm-analyzer.ts","../src/infra/runtime-config.ts","../src/engine/coordinator.ts","../src/cli.ts","../src/server.ts","../src/routes.ts","../src/models.ts","../src/package-json.ts","../src/actrail.ts","../src/console/index.ts","../src/console/router.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, TimeoutConfig, RetryConfig } 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 ?? 40,\n };\n}\n\n/** Load timeout/retry config from file (对齐 Python TimeoutConfig / RetryConfig) */\nfunction loadTimeoutRetryFromFile(configPath: string): { timeout: TimeoutConfig; retry: RetryConfig } {\n const data = loadConfigFile(configPath);\n const t = data?.timeout ?? {};\n const r = data?.retry ?? {};\n return {\n timeout: {\n totalTimeout: Number(t.total_timeout ?? 90),\n prompt1Timeout: Number(t.prompt1_timeout ?? 40),\n prompt2Timeout: Number(t.prompt2_timeout ?? 20),\n stepInterval: Number(t.step_interval ?? 0),\n },\n retry: {\n maxRetries: Number(r.max_retries ?? 2),\n retryInterval: Number(r.retry_interval ?? 2),\n },\n };\n}\n\n/** Global timeout/retry configuration (对齐 Python TimeoutConfig / RetryConfig) */\nlet timeoutConfig: TimeoutConfig;\nlet retryConfig: RetryConfig;\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 const tr = loadTimeoutRetryFromFile(configPath);\n timeoutConfig = tr.timeout;\n retryConfig = tr.retry;\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 // 优先用 env,否则用 timeout 块的 prompt1Timeout(对齐 py)\n timeout: parseInt(process.env.AGENT_MOSS_LLM_TIMEOUT || String(fileConfig.timeout ?? String(tr.timeout.prompt1Timeout)), 10),\n };\n})();\n\nexport function getTimeoutConfig(): Readonly<TimeoutConfig> {\n return timeoutConfig;\n}\n\nexport function getRetryConfig(): Readonly<RetryConfig> {\n return retryConfig;\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/**\n * LLM analysis failure mode (mirrors Python get_llm_fail_mode).\n *\n * - \"fail_open\" (default): when L3 LLM fails and prior layers did NOT block,\n * Allow + warning log (availability-first)\n * - \"fail_closed\": LLM failure -> Deny (safety-first)\n *\n * Priority: env AGENT_MOSS_LLM_FAIL_MODE > default fail_open.\n */\nexport function getLLMFailMode(): 'fail_open' | 'fail_closed' {\n const val = (process.env.AGENT_MOSS_LLM_FAIL_MODE || 'fail_open').toLowerCase();\n return val === 'fail_closed' ? 'fail_closed' : 'fail_open';\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","/**\n * 三方 agent 定制化注册中心 — TypeScript 加载器\n *\n * 按 `agentId` 加载该 agent 的专属规则集(JSON 单一事实源)。\n * 规则文件位置:`agent_moss/agents/<agentId>/rules.json`\n *\n * 与 Python `agent_moss/agents/__init__.py:get_agent_extensions` 一一对应。\n * 两端共享同一份 rules.json。\n *\n * 路径解析:\n * - prod(dist/cli.js):copy-assets.cjs 复制 rules.json 到 dist/agents/<id>/rules.json\n * - dev(tsx src/cli.ts):从 ts/src/agents/ 出发,回退到 ../../../agent_moss/agents\n *\n * 缓存:首次加载后缓存在 Map 中,clearAgentExtensionsCache 清空(测试用)。\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { AgentExtensions } from './types';\n\nexport type { AgentExtensions } from './types';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// 优先用 dist 内联目录(prod,copy-assets.cjs 复制后);\n// 缺失时回退到仓库根 agent_moss/agents(dev)。\n// 注意:从 ts/src/agents/ 出发,仓库根 agent_moss/agents 在 ../../../agent_moss/agents。\nconst AGENTS_DIR_PROD = resolve(__dirname, 'agents');\nconst AGENTS_DIR_DEV_FALLBACK = resolve(__dirname, '../../../agent_moss/agents');\n\nconst cache = new Map<string, AgentExtensions | null>();\n\nfunction resolveAgentsDir(): string {\n if (existsSync(AGENTS_DIR_PROD)) return AGENTS_DIR_PROD;\n if (existsSync(AGENTS_DIR_DEV_FALLBACK)) return AGENTS_DIR_DEV_FALLBACK;\n return AGENTS_DIR_PROD; // 不存在时也返回 prod 路径,让后续 existsSync 检查返回 false\n}\n\n/**\n * 按 agentId 加载该 agent 的专属规则集。\n *\n * @param agentId 调用方 agent 标识,如 \"xiaoo\" / \"opencode\" / \"opendesk\"。\n * 空字符串返回 null(通用模式)。\n * @returns AgentExtensions 实例,或 null(无 agent 专属规则 / rules.json 不存在 / 解析失败)\n */\nexport function getAgentExtensions(agentId: string): AgentExtensions | null {\n if (!agentId) return null;\n if (cache.has(agentId)) return cache.get(agentId) ?? null;\n\n const agentsDir = resolveAgentsDir();\n const rulesFile = resolve(agentsDir, agentId, 'rules.json');\n\n if (!existsSync(rulesFile)) {\n cache.set(agentId, null);\n return null;\n }\n\n try {\n const raw = readFileSync(rulesFile, 'utf-8');\n const ext = JSON.parse(raw) as AgentExtensions;\n if (!ext.agent_id) {\n console.warn(`[AgentMoss agents] rules.json 缺少 agent_id 字段: ${rulesFile}`);\n cache.set(agentId, null);\n return null;\n }\n cache.set(agentId, ext);\n console.log(\n `[AgentMoss agents] 加载 agent ${agentId} 定制规则: ` +\n `${ext.extra_command_patterns?.length ?? 0} cmd patterns, ` +\n `${ext.extra_injection_keywords?.length ?? 0} injection keywords, ` +\n `${ext.extra_sensitive_paths?.length ?? 0} sensitive paths, ` +\n `${ext.builtin_safe_skills?.length ?? 0} builtin safe skills`\n );\n return ext;\n } catch (e) {\n console.error(`[AgentMoss agents] 加载 agent ${agentId} rules.json 失败:`, (e as Error).message);\n cache.set(agentId, null);\n return null;\n }\n}\n\n/**\n * 清空 agent 扩展缓存(用于测试或 rules.json 热加载)。\n */\nexport function clearAgentExtensionsCache(): void {\n cache.clear();\n}\n","import { SecurityJudgment, HeuristicResult } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getCustomRules } from '../config';\nimport { getAgentExtensions } from '../agents';\nimport type { CommandPattern, InjectionKeyword } from '../agents/types';\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)\nexport const 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 专属绕过词(绕过审计/禁用安全检查/关闭防护/bypass audit 等)\n // 已迁至 agent_moss/agents/xiaoo/rules.json 的 extra_injection_keywords,\n // 由 agent_ext 机制注入,不再污染通用层。\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 agent-specific extra command patterns (追加在通用规则之后)\n const agentExt = getAgentExtensions(input.agentId);\n if (agentExt?.extra_command_patterns) {\n for (const rule of agentExt.extra_command_patterns) {\n try {\n const re = new RegExp(rule.pattern, 'i');\n if (re.test(command)) {\n matched.push(`agent 专属规则: ${rule.reason}`);\n if (severityRank(rule.risk_level) > severityRank(highestSeverity)) {\n highestSeverity = rule.risk_level;\n highestRiskType = rule.risk_type;\n }\n }\n } catch { /* invalid regex, skip */ }\n }\n }\n\n // Check prompt injection keywords (通用 + agent_ext.extra_injection_keywords)\n const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ''} ${input.promptSession || ''}`.toLowerCase();\n const injectionHits = checkInjectionKeywords(injectionText, agentExt?.extra_injection_keywords);\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.1'], // 对齐 py coordinator.py:165(L1.1 = 命中高危命令模式/注入关键词)\n };\n }\n\n return null; // No match, pass to next layer\n}\n\nfunction checkInjectionKeywords(\n text: string,\n extraKeywords?: InjectionKeyword[],\n): { 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 // agent 专属注入关键词(追加在后)\n if (extraKeywords) {\n for (const entry of extraKeywords) {\n if (text.includes(entry.keyword.toLowerCase())) {\n hits.push({ keyword: entry.keyword, riskLevel: entry.risk_level, lang: entry.lang });\n }\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","/**\n * 内联脚本静态语义判定 — 区分敏感路径是\"被当作文本\"还是\"被当作读写目标\"。\n *\n * 对内联脚本(python -c / perl -e / ruby -e / php -r / node -e / lua / echo / printf)\n * 里出现非凭据敏感路径的场景,做静态判定(不依赖 LLM):\n *\n * 1. 写入+执行绕过链 → Deny(echo \"cat /etc/shadow\" > x.sh && bash x.sh / printf | bash)\n * 2. 重定向写入敏感路径 → Deny(echo '...' >> /etc/hosts)\n * 3. 含读写调用词 + 敏感路径共存 → Deny(open('/etc/shadow')、os.system('cat /etc/shadow'))\n * 注意:仅对 python -c 等真正的内联脚本代码做读写调用词检测;\n * echo/printf 的字符串参数是自然语言文本,跳过此检测(不可能触发真实读写)。\n * 4. 否则(敏感路径在代码里但无读写调用词,如 print('/etc/shadow')) → Allow\n * 5. 目录遍历 + 文件读写组合 → Deny(os.listdir + open() 动态发现并读写文件,绕过静态路径检测)\n * 注意:仅对 python -c 等真正的内联脚本代码做此检测。\n * 6. 否则(无目录遍历读写组合) → Allow\n *\n * 凭据文件不进此判定(coordinator 层 isCredential 直接 Deny)。\n */\n\nexport interface InlineAnalysisResult {\n /** 是否命中本判定器可处理的内联脚本场景;false 时回退原逻辑 */\n actionable: boolean;\n allowed: boolean;\n reason: string;\n riskLevel: 'low' | 'medium' | 'high' | 'critical';\n riskType: string;\n}\n\n// 内联脚本解释器 + 代码标志:python -c / perl -e / ruby -e / php -r / node -e / lua -e\n// 捕获 -c/-e/-r 后的代码内容(双引号组 1 / 单引号组 2,支持转义)\nconst INLINE_CODE_RE = /(?:python|python3|perl|perl5|ruby|jruby|mruby|node|php|lua)\\s+(?:-[a-zA-Z]*[cera][a-zA-Z]*\\s+)\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/gi;\n\n// echo / printf 的字符串参数(双引号组 1 / 单引号组 2)\nconst ECHO_STRING_RE = /\\b(?:echo|printf)\\s+\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|\\b(?:echo|printf)\\s+'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/gi;\n\n// echo / printf 命令本身(用于 isLiteralTextCommand 门控)\nconst ECHO_CMD_RE = /(?:^|\\s|;|&&|\\|\\|)(?:echo|printf)\\s/gi;\n\n/** 判断命令是否为 echo/printf 等纯文本输出命令(敏感路径可能作为字符串字面量出现)。 */\nexport function isLiteralTextCommand(command: string): boolean {\n ECHO_CMD_RE.lastIndex = 0;\n return ECHO_CMD_RE.test(command);\n}\n\n// 读写调用词:仅用于 python -c 等真正的内联脚本代码(不对 echo/printf 的字符串生效)。\n// 出现这些词 + 敏感路径共存 → 判为真实读写。\n//\n// 全部采用组合/函数调用形态,避免自然语言误触发:\n// - 函数调用形态:open(, read(, write(, system(, exec(, eval( 等(后跟 '(')\n// - 组合关键词:os.system, import os, shell=True 等(自带足够区分度)\n// - 不再包含裸短词(open, read, system, exec 等),因 \\b 无法区分编程调用与自然语言\nconst READ_WRITE_KEYWORDS = [\n // 函数调用形态(关键词后跟 '(')\n 'open(', 'read(', 'write(', 'fopen(', 'system(', 'exec(', 'eval(',\n 'popen(', 'load(', 'dump(',\n // 文件读写(组合形态)\n 'readline', 'readlines', 'writelines', 'getpass',\n 'pickle.load', 'yaml.load', 'json.load', 'json.read', 'configparser',\n 'fread', 'fwrite', 'fgets',\n // 子进程执行(组合形态)\n 'os.system', 'os.popen', 'subprocess', 'os.exec', 'os.spawn',\n 'import os', 'import subprocess',\n 'shell=true', 'check_output', 'check_call', 'run(',\n // 绕过变体检测\n 'getattr(', '__builtins__', 'globals(', 'locals(',\n // PHP\n 'file_get_contents', 'file_put_contents', 'passthru', 'shell_exec', 'proc_open',\n // Perl-Ruby\n '<stdin>', 'open my',\n];\n\n// 写入+执行绕过链\nconst WRITE_EXEC_CHAIN_PATTERNS: RegExp[] = [\n // echo/cat/printf \"...\" > file && bash/sh/python file\n /(?:echo|cat|printf)\\b.*?>\\s*\\S+.*(?:&&|;|\\|)\\s*(?:bash|sh|zsh|python\\d?|perl|ruby|node|php)\\s/gis,\n // ... | bash / | sh / | python(管道喂解释器执行)\n /\\|\\s*(?:bash|sh|zsh|python\\d?|perl|ruby|node|php)\\b/gi,\n // eval \"$(cat ...)\" / eval \"$(echo ...)\"\n /eval\\s+\"\\$\\(/gi,\n // xargs bash / xargs sh\n /\\|\\s*xargs\\s+(?:bash|sh|zsh)/gi,\n];\n\n// 重定向写入敏感路径:> / >> 后跟敏感路径 = 真实写入(不是字符串字面量)\n// 敏感路径片段(非凭据,凭据已在 coordinator 层直接 Deny 不进此判定)\nconst SENSITIVE_PATH_FRAGMENTS = [\n '/etc/shadow', '/etc/gshadow', '/etc/passwd', '/etc/sudoers', '/etc/hosts',\n '/etc/crontab', '/etc/systemd/', '/etc/ssh/sshd_config', '/boot/', '/proc/sys/',\n '/sys/', '/dev/mem', '/dev/kmsg', '.ssh/id_rsa', '.ssh/id_ed25519',\n '.ssh/authorized_keys',\n];\nconst REDIRECT_TO_SENSITIVE_RE = new RegExp(`>{1,2}\\\\s*(${SENSITIVE_PATH_FRAGMENTS.map((p) => p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})`, 'i');\n\nexport function extractInlineCode(command: string): string {\n const parts: string[] = [];\n let m: RegExpExecArray | null;\n INLINE_CODE_RE.lastIndex = 0;\n while ((m = INLINE_CODE_RE.exec(command)) !== null) {\n const code = m[1] ?? m[2];\n if (code) parts.push(code);\n }\n ECHO_STRING_RE.lastIndex = 0;\n while ((m = ECHO_STRING_RE.exec(command)) !== null) {\n const code = m[1] ?? m[2];\n if (code) parts.push(code);\n }\n return parts.join('\\n');\n}\n\nfunction hasWriteExecChain(command: string): boolean {\n return WRITE_EXEC_CHAIN_PATTERNS.some((p) => {\n p.lastIndex = 0;\n return p.test(command);\n });\n}\n\n// 目录遍历关键词:用于检测通过动态发现文件路径绕过静态路径匹配的行为\n// 仅对 python -c 等真正的内联脚本代码生效\nconst DIR_TRAVERSAL_KEYWORDS = [\n // Python 目录遍历\n 'os.listdir', 'os.walk', 'os.scandir',\n 'glob.glob', 'glob.iglob', 'pathlib.', 'iterdir', 'rglob',\n 'scandir(', 'listdir(',\n];\n\nfunction hasDirTraversal(code: string): boolean {\n /** 检测代码中是否含目录遍历函数(用于识别动态文件发现绕过行为)。 */\n const lower = code.toLowerCase();\n return DIR_TRAVERSAL_KEYWORDS.some((kw) => lower.includes(kw));\n}\n\nexport function hasReadWriteKeyword(code: string): boolean {\n /** 检测代码中是否含读写调用词(仅用于 python -c 等真正的内联脚本代码)。\n * 全部关键词为组合/函数调用形态(open(, os.system, import os 等),\n * 不会在自然语言文本里误触发。 */\n const lower = code.toLowerCase();\n return READ_WRITE_KEYWORDS.some((kw) => lower.includes(kw));\n}\n\n/**\n * 对内联脚本做静态语义判定。\n * 调用前提:coordinator 已确认是 inline 脚本 + 命中非凭据敏感路径。\n */\nexport function analyzeInlineScript(command: string): InlineAnalysisResult {\n const code = extractInlineCode(command);\n if (!code) {\n // 提取不到代码(命令结构不匹配已知 inline 模式)→ 不处理,回退保守\n return { actionable: false, allowed: true, reason: '', riskLevel: 'low', riskType: '' };\n }\n\n // 1. 写入+执行绕过链 → Deny\n if (hasWriteExecChain(command)) {\n return {\n actionable: true,\n allowed: false,\n reason: '内联脚本含写入文件后执行的模式,疑似绕过敏感路径检测',\n riskLevel: 'critical',\n riskType: 'script_execution',\n };\n }\n\n // 1.5 重定向写入敏感路径(echo '...' >> /etc/hosts 等)→ 真实写入 → Deny\n const redirMatch = command.match(REDIRECT_TO_SENSITIVE_RE);\n if (redirMatch) {\n return {\n actionable: true,\n allowed: false,\n reason: `重定向写入敏感路径: ${redirMatch[1]}`,\n riskLevel: 'critical',\n riskType: 'file_access',\n };\n }\n\n // 1.6 目录遍历 + 文件读写组合 → 不自行判定,回退 coordinator 走层3 LLM 分析\n // 检测 os.listdir/glob/pathlib 等目录遍历函数 + open()/write()/read() 等读写调用,\n // 用于识别\"通过动态发现文件路径绕过静态路径匹配\"的行为。\n // 仅对 python -c 等真正的内联脚本代码做此检测(echo/printf 无此能力)。\n // 注意:此处返回 actionable: false,让 coordinator 回退到正常逻辑,\n // 由层2 的 _checkIndirectFileAccess 规则触发层3 LLM 语义判断。\n const isEchoOrPrintf1 = isLiteralTextCommand(command);\n if (!isEchoOrPrintf1 && hasDirTraversal(code) && hasReadWriteKeyword(code)) {\n return { actionable: false, allowed: true, reason: '', riskLevel: 'low', riskType: '' };\n }\n\n // 2. 含读写调用词 → 判为真实读写 → Deny\n // 注意:仅对 python -c 等真正的内联脚本代码做此检测。\n // echo/printf 的字符串参数是自然语言文本,不可能触发真实文件读写;\n // 重定向(>> /etc/hosts)和管道执行(| bash)已在步骤 1/1.5 覆盖。\n const isEchoOrPrintf = isLiteralTextCommand(command);\n if (!isEchoOrPrintf && hasReadWriteKeyword(code)) {\n return {\n actionable: true,\n allowed: false,\n reason: '内联脚本含敏感路径且含文件读写/命令执行调用,判为真实访问',\n riskLevel: 'critical',\n riskType: 'file_access',\n };\n }\n\n // 3. 敏感路径在代码里但无读写调用词 → 文本字面量 → Allow\n return {\n actionable: true,\n allowed: true,\n reason: '敏感路径仅作为文本字面量出现,未伴随读写操作',\n riskLevel: 'low',\n riskType: 'file_access',\n };\n}\n","import * as fs from 'fs';\nimport { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { extractInlineCode } from './inline-analyzer.js';\nimport { getAgentExtensions } from '../agents';\nimport type { AgentExtensions } from '../agents';\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)\nexport const ROOT_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string; credential?: boolean }[] = [\n { path: '/etc/shadow', riskLevel: 'critical', desc: '系统密码文件', credential: true },\n { path: '/etc/gshadow', riskLevel: 'critical', desc: '系统组密码文件', credential: true },\n // 注意:/etc/passwd 仅从 L1 启发式规则移除(公开可读),L2 敏感路径仍保留\n { path: '/etc/passwd', riskLevel: 'high', desc: '系统用户文件' },\n { path: '/etc/sudoers', riskLevel: 'critical', desc: 'sudo 配置', credential: true },\n // 系统配置(仅拦截写入)\n { path: '/etc/hosts', riskLevel: 'medium', desc: 'DNS 解析配置' },\n { path: '/etc/crontab', riskLevel: 'high', desc: '系统定时任务' },\n { path: '/etc/cron.d/', riskLevel: 'high', desc: '系统定时任务目录(拆分式 crontab)' },\n { path: '/var/spool/cron/', riskLevel: 'high', desc: '用户级定时任务目录' },\n { path: '/etc/systemd/', riskLevel: 'high', desc: 'systemd 服务配置' },\n { path: '/etc/ssh/sshd_config', riskLevel: 'high', desc: 'SSH 服务配置' },\n { path: '/etc/pam.d/', riskLevel: 'high', desc: 'PAM 可插拔认证模块配置' },\n // 危险目录(仅拦截写入)\n { path: '/boot/', riskLevel: 'critical', desc: '启动引导目录' },\n { path: '/proc/sys/', riskLevel: 'high', desc: '内核参数' },\n { path: '/sys/', riskLevel: 'high', desc: 'sysfs 内核接口' },\n // 设备文件(/dev/null、/dev/zero、/dev/urandom 已移除,误报率极高)\n { path: '/dev/random', riskLevel: 'high', desc: '阻塞式随机数设备(读取耗尽熵池)' },\n { path: '/dev/mem', riskLevel: 'critical', desc: '物理内存访问设备' },\n { path: '/dev/kmsg', riskLevel: 'high', desc: '内核消息缓冲区' },\n // SSH 主机私钥\n { path: '/etc/ssh/ssh_host_rsa_key', riskLevel: 'critical', desc: 'SSH 主机 RSA 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ed25519_key', riskLevel: 'critical', desc: 'SSH 主机 Ed25519 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ecdsa_key', riskLevel: 'critical', desc: 'SSH 主机 ECDSA 私钥', credential: true },\n];\n\nexport const HOME_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string; credential?: boolean }[] = [\n { path: '.ssh/id_rsa', riskLevel: 'critical', desc: 'SSH 私钥', credential: true },\n { path: '.ssh/id_ed25519', riskLevel: 'critical', desc: 'SSH 私钥 (ed25519)', credential: true },\n { path: '.ssh/authorized_keys', riskLevel: 'high', desc: 'SSH 授权密钥' },\n // 持久化与命令劫持(仅拦截写入)\n { path: '.bashrc', riskLevel: 'high', desc: '用户 Shell 初始化脚本' },\n { path: '.bash_profile', riskLevel: 'high', desc: '用户 Shell 登录脚本' },\n { path: '.profile', riskLevel: 'high', desc: '用户通用登录脚本' },\n { path: '.aws/credentials', riskLevel: 'critical', desc: 'AWS 凭证', credential: true },\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)\nexport const 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\nexport const 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\nexport const 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)\nexport const 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 // 非 shell/文件类操作跳过意图一致性和敏感路径检查\n const EXCLUDED_PREFIXES = ['memory-', 'skill-', 'skill-manager-', 'mailbox-', 'app-'];\n const isExcludedType = EXCLUDED_PREFIXES.some(p => actionType.startsWith(p));\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 // 只对 shell/文件类操作执行意图一致性检查\n if (!isExcludedType) {\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\n // Rule 3: Sensitive path access\n // 只对文件/命令类操作执行敏感路径检查\n if (!isExcludedType) {\n // agent_ext 透传:通用规则先匹配,agent 专属敏感路径追加在后\n const agentExt: AgentExtensions | null = getAgentExtensions((input as { agentId?: string }).agentId || '');\n const pathResult = checkSensitivePath(actionDetail, resolvedCwd, agentExt);\n if (pathResult) return pathResult;\n }\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 \n\n// ==================== 只读命令集合(用于重定向写判定与敏感路径读写区分)====================\nvar _READ_ONLY_COMMANDS = new Set([\n 'cat', 'head', 'tail', 'less', 'more', 'grep', 'find', 'awk', 'sed',\n 'sort', 'uniq', 'wc', 'cut', 'strings', 'od', 'xxd', 'hexdump', 'tr',\n 'file', 'stat', 'du', 'df', 'ls', 'dir', 'tree', 'nl', 'tac', 'rev',\n 'lsblk', 'blockdev', 'smartctl', 'udevadm', 'dmidecode', 'lscpu', 'lspci',\n 'lsusb', 'lsmem', 'lsns', 'lsof', 'hwinfo', 'inxi', 'fdisk', 'parted',\n 'dmesg', 'journalctl', 'systemctl', 'hostnamectl', 'localectl', 'timedatectl',\n 'ps', 'top', 'free', 'vmstat', 'iostat', 'mpstat', 'pidof', 'pgrep',\n 'ip', 'ifconfig', 'route', 'ss', 'netstat', 'arp', 'ethtool', 'nmcli',\n 'uname', 'arch', 'nproc', 'getconf', 'getent', 'id', 'whoami', 'who',\n 'w', 'last', 'uptime', 'lsmod', 'modinfo', 'sysctl',\n]);\n\n// 重定向到 /dev/null 的丢弃写法\nvar _DEVNULL_REDIRECT_RE = /(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/;\n\n// 写/删命令词边界正则\nvar _WRITE_COMMAND_RES = [\n /\\brm\\b/, /\\bunlink\\b/, /\\brmdir\\b/, /\\bshred\\b/,\n /\\bcp\\b/, /\\bmv\\b/, /\\binstall\\b/, /\\btee\\b/,\n /\\bdd\\b/, /\\bmkfs\\b/, /\\b(fdisk|parted|cfdisk|sfdisk)\\b/,\n /\\bchmod\\b/, /\\bchown\\b/, /\\btruncate\\b/,\n];\n\n// 综合判定是否为写/删操作\n// Rule 4.5: Indirect file access — inline script with dir traversal + file read/write\n // Uses cwd to list actual files and check against sensitive paths directly\n const indirectResult = checkIndirectFileAccess(actionType, actionDetail, resolvedCwd);\n if (indirectResult) return indirectResult;\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, agentExt?: import('../agents').AgentExtensions | null): SecurityJudgment | null {\n const expandedCwd = cwd.replace(/^~/, process.env.HOME || '/home/user');\n\n // 局部常量(避免引用模块级常量被 esbuild 重命名导致 ReferenceError)\n const _WRITE_CMD_RES = [/\\brm\\b/, /\\bunlink\\b/, /\\brmdir\\b/, /\\bshred\\b/, /\\bcp\\b/, /\\bmv\\b/, /\\binstall\\b/, /\\btee\\b/, /\\bdd\\b/, /\\bmkfs\\b/, /\\b(fdisk|parted|cfdisk|sfdisk)\\b/, /\\bchmod\\b/, /\\bchown\\b/, /\\btruncate\\b/];\n const _DEVNULL_RE = /(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/;\n const _READONLY_CMDS = new Set(['cat','head','tail','less','more','grep','find','awk','sed','sort','uniq','wc','cut','strings','od','xxd','hexdump','tr','file','stat','du','df','ls','dir','tree','nl','tac','rev','lsblk','blockdev','smartctl','udevadm','dmidecode','lscpu','lspci','lsusb','lsmem','lsns','lsof','hwinfo','inxi','fdisk','parted','dmesg','journalctl','systemctl','hostnamectl','localectl','timedatectl','ps','top','free','vmstat','iostat','mpstat','pidof','pgrep','ip','ifconfig','route','ss','netstat','arp','ethtool','nmcli','uname','arch','nproc','getconf','getent','id','whoami','who','w','last','uptime','lsmod','modinfo','sysctl']);\n\n const isWriteOpFlag = _WRITE_CMD_RES.some(rx => rx.test(command)) ||\n /\\bsed\\s+-[a-zA-Z]*i/.test(command) ||\n (command.includes('>') && !command.replace(_DEVNULL_RE, '').includes('>')) ||\n (command.includes('>') && command.replace(_DEVNULL_RE, '').includes('>') &&\n !_READONLY_CMDS.has(command.trim().split(/\\s+/)[0]?.toLowerCase() || '')) ||\n WRITE_KEYWORDS.some(kw => ''.includes(kw) || command.includes(kw));\n\n for (const sp of ROOT_SENSITIVE_PATHS) {\n if (command.includes(sp.path.toLowerCase())) {\n // /dev/random:只拦截读取操作,写入/删除放行(读取可耗尽熵池导致 TLS 阻塞)\n if (sp.path === '/dev/random') {\n if (isWriteOpFlag) {\n continue; // 允许写入操作(投喂熵池)\n }\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 // 凭据路径(sp.credential=true,如 /etc/shadow、SSH 私钥、AWS 凭证):\n // 读写均拦(读取凭据同样危险)。与 py deny_both 一致。\n if (!isWriteOpFlag && !sp.credential) {\n continue;\n }\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 // 非凭据路径:只拦截写入/删除操作,只读访问放行。\n // 凭据路径(sp.credential=true,如 SSH 私钥、AWS 凭证):\n // 读写均拦(读取凭据同样危险)。与 py deny_both 一致。\n if (!isWriteOpFlag && !sp.credential) {\n continue;\n }\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 // agent 专属敏感路径(追加在通用规则之后)\n if (agentExt?.extra_sensitive_paths && agentExt.extra_sensitive_paths.length > 0) {\n for (const sp of agentExt.extra_sensitive_paths) {\n const spPath = sp.path.toLowerCase();\n const expanded = `${expandedCwd}/${spPath}`;\n if (command.includes(spPath) || command.includes(expanded.toLowerCase())) {\n const denyMode = sp.deny_mode || (sp.credential ? 'deny_both' : sp.read_only ? 'deny_read' : 'deny_write');\n if (denyMode === 'deny_read') {\n if (isWriteOpFlag) continue;\n } else if (denyMode === 'deny_write') {\n if (!isWriteOpFlag) continue;\n }\n // deny_both:读写均拦\n return {\n allowed: false,\n reason: `尝试访问 agent 专属敏感路径: ${sp.desc} (${sp.path})`,\n riskLevel: sp.risk_level as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n }\n\n // Credential files: always intercept regardless of read/write // Credential files: always intercept regardless of read/write\n // Files starting with . need special handling since \\b doesn't match before .\n // 边界字符含引号:凭据常出现在 open('.env')、cat \".env\" 等引号上下文里\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 isCredential: true,\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\n// 内联脚本解释器正则\nconst INLINE_SCRIPT_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\n// 目录遍历关键词(用唯一名称避免与 inline-analyzer.ts 的 DIR_TRAVERSAL_KEYWORDS 冲突)\nconst DIR_TRAVERSAL_KW = [\n 'os.listdir', 'os.walk', 'os.scandir',\n 'glob.glob', 'glob.iglob', 'pathlib.', 'iterdir', 'rglob',\n 'scandir(', 'listdir(',\n];\n\n/**\n * Rule 4.5: Indirect file access detection.\n * Detects inline scripts that use directory traversal (os.listdir/glob/pathlib)\n * combined with file read/write operations to dynamically discover and access\n * sensitive files, bypassing static path matching.\n *\n * Returns medium risk so the coordinator forwards to Layer 3 LLM analysis\n * instead of denying immediately.\n */\nfunction checkIndirectFileAccess(actionType: string, actionDetail: string, cwd: string): SecurityJudgment | null {\n // Only check bash tool inline scripts\n if (actionType !== 'bash' && actionType !== 'executebash' && actionType !== 'terminal-executebash') {\n return null;\n }\n\n // Check if it's an inline script command\n INLINE_SCRIPT_RE.lastIndex = 0;\n if (!INLINE_SCRIPT_RE.test(actionDetail)) {\n return null;\n }\n\n // Check for directory traversal keywords\n const lowerDetail = actionDetail.toLowerCase();\n const hasTraversal = DIR_TRAVERSAL_KW.some(kw => lowerDetail.includes(kw));\n if (!hasTraversal) {\n return null;\n }\n\n // Extract code and check for read/write keywords, distinguishing read/write/exec\n const READ_KEYWORDS = ['read(', 'readline', 'readlines', 'fread', 'fgets', 'load(', 'getpass', 'file_get_contents'];\n const WRITE_KEYWORDS = ['write(', 'writelines', 'fwrite', 'file_put_contents'];\n const EXEC_KEYWORDS = ['system(', 'exec(', 'eval(', 'popen(', 'os.system', 'os.popen', 'subprocess', 'os.exec', 'os.spawn', 'shell=true', 'check_output', 'check_call', 'run(', 'passthru', 'shell_exec', 'proc_open'];\n const OPEN_KEYWORDS = ['open(', 'fopen('];\n const code = extractInlineCode(actionDetail);\n if (!code) return null;\n const codeLower = code.toLowerCase();\n const hasAnyOp = READ_KEYWORDS.some(kw => codeLower.includes(kw)) ||\n WRITE_KEYWORDS.some(kw => codeLower.includes(kw)) ||\n EXEC_KEYWORDS.some(kw => codeLower.includes(kw)) ||\n OPEN_KEYWORDS.some(kw => codeLower.includes(kw));\n if (!hasAnyOp) {\n return null;\n }\n\n // Determine operation type\n const hasWrite = WRITE_KEYWORDS.some(kw => codeLower.includes(kw));\n const hasExec = EXEC_KEYWORDS.some(kw => codeLower.includes(kw));\n // Write/exec: block all sensitive files. Read only: block only credential files.\n const blockAllSensitive = hasWrite || hasExec;\n\n // Pattern matched — try to list actual files in cwd and check against sensitive paths\n let actualFiles: string[] = [];\n if (cwd && cwd !== '/') {\n try {\n actualFiles = fs.readdirSync(cwd);\n } catch {\n // cwd invalid or inaccessible, fall through\n }\n }\n\n if (actualFiles.length > 0) {\n // Check credential files\n for (const cp of CREDENTIAL_PATHS) {\n const fname = cp.path.split('/').pop() || cp.path;\n if (actualFiles.some(f => f === fname || f.toLowerCase() === fname.toLowerCase())) {\n return {\n allowed: false,\n reason: `内联脚本使用目录遍历动态发现文件并执行读写操作,cwd (${cwd}) 中包含凭据文件: ${fname}`,\n riskLevel: 'high',\n riskType: 'file_access',\n confidence: 95,\n source: 'logic_rule',\n violatedLayers: ['2'],\n isCredential: true,\n };\n }\n }\n\n // Check other sensitive files (only block on write/exec, read-only is safe for non-credential)\n if (blockAllSensitive) {\n for (const sp of [...ROOT_SENSITIVE_PATHS, ...HOME_SENSITIVE_PATHS]) {\n const fname = sp.path.split('/').pop() || sp.path;\n if (actualFiles.some(f => f === fname || f.toLowerCase() === fname.toLowerCase())) {\n return {\n allowed: false,\n reason: `内联脚本使用目录遍历动态发现文件并执行写操作,cwd (${cwd}) 中包含敏感文件: ${fname}`,\n riskLevel: 'high',\n riskType: 'file_access',\n confidence: 95,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n }\n\n // No sensitive files found in cwd — safe to allow\n return null;\n }\n\n // cwd invalid, can't check actual files — fall back to medium risk (L3)\n return {\n allowed: false,\n reason: '内联脚本使用目录遍历函数动态发现文件并执行读写操作,无法获取 cwd 实际文件列表,转层3 LLM 分析',\n riskLevel: 'medium',\n riskType: 'file_access',\n confidence: 70,\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// 优先用打包内联目录 dist/skills(npm 安装后自包含);\n// dev 模式(vitest 测试时 __dirname=ts/src/engine)回退到仓库根 agent_moss/skills。\n// 注意:从 ts/src/engine 出发,仓库根 agent_moss/skills 在 ../../../agent_moss/skills\n// (不能写 ../../agent_moss/skills,那是 ts/agent_moss/skills,不存在)。\nconst SKILLS_DIR = resolve(__dirname, '../skills');\nconst SKILLS_DIR_FALLBACK = resolve(__dirname, '../../../agent_moss/skills');\n\n// Skill keyword map (synced with Python skill_engine.py SKILL_KEYWORD_MAP)\n// exported for runtime_config seed (generateSourceDefaults)\nexport const 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 // 注意:避免裸 'memory'/'内存'/'dd'——会误命中 memory-addMemory(写记忆工具,\n // 'dd' 是 'addMemory' 的子串)等无害操作。用组合词/命令前缀精准匹配攻击场景。\n 'resource_exhaustion_guard': ['fork', 'bomb', '炸弹', 'memory bomb', 'oom', 'out of memory', '内存溢出', '内存耗尽', '内存泄漏', 'disk', '磁盘', 'cpu', 'process', '进程', 'dd if=', '/dev/zero', '/dev/null', 'yes >', '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 'indirect_access_guard': ['listdir', 'os.walk', 'os.scandir', 'glob.glob', 'glob.iglob', 'pathlib', 'iterdir', 'rglob', 'scandir', 'os.listdir', '目录遍历', 'traversal'],\n};\n\nlet cachedSkills: Record<string, string> | null = null;\n\nfunction loadAllSkills(): Record<string, string> {\n if (cachedSkills) return cachedSkills;\n cachedSkills = {};\n\n const dir = existsSync(SKILLS_DIR) ? SKILLS_DIR : SKILLS_DIR_FALLBACK;\n if (!existsSync(dir)) {\n console.warn('[AgentMoss] Skills directory not found:', SKILLS_DIR, 'and fallback:', SKILLS_DIR_FALLBACK);\n return cachedSkills;\n }\n\n const files = readdirSync(dir).filter(f => f.endsWith('.md'));\n for (const f of files) {\n const name = f.replace('.md', '');\n cachedSkills[name] = readFileSync(resolve(dir, f), 'utf-8');\n }\n\n console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);\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\n// 优先用打包内联目录 dist/templates(npm 安装后自包含);\n// dev 模式(vitest 测试时 __dirname=ts/src/engine)回退到仓库根 agent_moss/templates。\n// 注意:从 ts/src/engine 出发,仓库根 agent_moss/templates 在 ../../../agent_moss/templates\n// (不能写 ../../agent_moss/templates,那是 ts/agent_moss/templates,不存在)。\nconst TEMPLATES_DIR = resolve(__dirname, '../templates');\nconst TEMPLATES_DIR_FALLBACK = 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 const dir = existsSync(TEMPLATES_DIR) ? TEMPLATES_DIR : TEMPLATES_DIR_FALLBACK;\n if (!existsSync(dir)) {\n console.warn('[AgentMoss] Templates directory not found:', TEMPLATES_DIR, 'and fallback:', TEMPLATES_DIR_FALLBACK);\n return cachedTemplates;\n }\n\n for (const file of TEMPLATE_FILES) {\n const filePath = resolve(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 from ${dir}`);\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","/**\n * Script content analyzer — recursive chain tracking + preprocessing + L1/L2 reuse.\n *\n * Mirrors Python agent_moss/engine/script_content_analyzer.py.\n *\n * Core improvements over the old single-file script-analyzer.ts:\n * 1. Preprocessing pipeline: strip comments -> strip echo text -> expand simple vars\n * 2. Broader script path extraction (no .sh restriction; python/node/ruby/...)\n * 3. File-size limit instead of line limit (full read; ms-scale cost)\n * 4. Recursive tracking: A.sh -> B.sh -> C.sh nested calls are caught\n * 5. L1/L2 reuse: preprocessed content scanned via existing runHeuristicCheck /\n * runLogicCheck; high/critical deny directly, skipping L3\n *\n * Difference from Python: AgentMoss-TS heuristic/logic are single entry functions\n * (runHeuristicCheck / runLogicCheck taking AnalysisInput), not reusable scanner\n * objects. So L1/L2 per-node reuse wraps each node's preprocessed content as a\n * virtual AnalysisInput and calls those functions.\n */\n\nimport { readFileSync, statSync, existsSync } from 'fs';\nimport { resolve, join, isAbsolute, dirname } from 'path';\nimport { homedir } from 'os';\nimport type { AnalysisInput } from './coordinator';\nimport type { SecurityJudgment } from './types';\nimport { runHeuristicCheck } from './heuristic';\nimport { runLogicCheck } from './logic-rules';\n\n// ==================== Types ====================\n\nexport interface ScriptNode {\n scriptPath: string;\n rawContent: string;\n preprocessedContent: string;\n lineCount: number;\n fileSize: number;\n depth: number;\n childPaths: string[];\n error: string;\n\n l1Hit: boolean;\n l1RiskLevel: string;\n l1RiskType: string;\n l1Reason: string;\n l1MatchedPatterns: string[];\n\n l2Hit: boolean;\n l2ViolatedRule: string;\n l2RiskLevel: string;\n l2RiskType: string;\n l2Reason: string;\n\n matchedKeywords: string[];\n isSuspicious: boolean;\n keywordRiskLevel: string;\n keywordRiskReason: string;\n}\n\nexport interface ScriptChainAnalysisResult {\n nodes: ScriptNode[];\n entryPath: string;\n maxDepthReached: boolean;\n maxSizeReached: boolean;\n totalSize: number;\n totalLines: number;\n hasCritical: boolean;\n hasHigh: boolean;\n firstHitNode: ScriptNode | null;\n error: string;\n}\n\nfunction emptyChain(): ScriptChainAnalysisResult {\n return {\n nodes: [], entryPath: '', maxDepthReached: false, maxSizeReached: false,\n totalSize: 0, totalLines: 0, hasCritical: false, hasHigh: false,\n firstHitNode: null, error: '',\n };\n}\n\nfunction newNode(path: string, depth: number): ScriptNode {\n return {\n scriptPath: path, rawContent: '', preprocessedContent: '', lineCount: 0,\n fileSize: 0, depth, childPaths: [], error: '',\n l1Hit: false, l1RiskLevel: '', l1RiskType: '', l1Reason: '', l1MatchedPatterns: [],\n l2Hit: false, l2ViolatedRule: '', l2RiskLevel: '', l2RiskType: '', l2Reason: '',\n matchedKeywords: [], isSuspicious: false, keywordRiskLevel: '', keywordRiskReason: '',\n };\n}\n\n// ==================== Preprocessing pipeline ====================\n\nfunction stripComments(content: string): string {\n return content.split('\\n').filter(line => !line.trimStart().startsWith('#')).join('\\n');\n}\n\nfunction stripOutputText(content: string): string {\n let result = content.replace(/echo\\s+\".*?\"/gs, 'echo \"\"');\n result = result.replace(/echo\\s+'.*?'/gs, \"echo ''\");\n result = result.replace(/printf\\s+\".*?\"[^\\n]*/gs, 'printf \"\"');\n result = result.replace(/printf\\s+'.*?'[^\\n]*/gs, \"printf ''\");\n return result;\n}\n\nfunction expandSimpleVariables(content: string): string {\n const varMap: Record<string, string> = {};\n const assignmentRe = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.+)$/;\n\n const collectAssignments = (text: string) => {\n for (const line of text.split('\\n')) {\n const m = line.match(assignmentRe);\n if (m) {\n const varName = m[1];\n let varVal = m[2].trim();\n if (varVal && !varVal.includes('$') && !varVal.includes('`')) {\n if ((varVal.startsWith('\"') && varVal.endsWith('\"')) ||\n (varVal.startsWith(\"'\") && varVal.endsWith(\"'\"))) {\n varVal = varVal.slice(1, -1);\n }\n varMap[varName] = varVal;\n }\n }\n }\n };\n\n collectAssignments(content);\n let expanded = content;\n\n for (let round = 0; round < 3; round++) {\n const sortedVars = Object.keys(varMap).sort((a, b) => b.length - a.length);\n let newExpanded = expanded;\n for (const v of sortedVars) {\n const val = varMap[v];\n newExpanded = newExpanded.split('${' + v + '}').join(val);\n newExpanded = newExpanded.split('$' + v).join(val);\n }\n if (newExpanded === expanded) break;\n expanded = newExpanded;\n collectAssignments(expanded);\n }\n return expanded;\n}\n\nfunction preprocessScriptContent(content: string): string {\n let result = stripComments(content);\n result = stripOutputText(result);\n result = expandSimpleVariables(result);\n return result;\n}\n\n\n// ==================== High-risk keyword patterns (L3 compatible) ====================\n\nconst SUSPICIOUS_PATTERNS: { name: string; pattern: RegExp }[] = [\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 { 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 { name: '$(base64', pattern: /\\$\\(\\s*base64/ },\n { name: '`base64', pattern: /`\\s*base64/ },\n { name: 'base64 decode pipe', pattern: /base64\\s+(-d|--decode)\\s*\\|/ },\n { name: '/etc/shadow', pattern: /\\/etc\\/shadow/ },\n { name: 'id_rsa', pattern: /\\bid_rsa\\b/ },\n { name: 'id_ed25519', pattern: /\\bid_ed25519\\b/ },\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\n// ==================== Script execution patterns ====================\n\nconst SCRIPT_EXEC_PATTERNS: RegExp[] = [\n /(?:^|\\s|&&|\\|\\|)\\s*bash\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*\\/bin\\/bash\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*sh\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*zsh\\s+(\\S+)/i,\n /\\.\\/(\\S+)/,\n /(?:^|\\s|&&|\\|\\|)\\s*source\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*\\.\\s+(\\S+)/,\n /(?:^|\\s|&&|\\|\\|)\\s*python3?\\s+(\\S+\\.py)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*node\\s+(\\S+\\.js)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*ruby\\s+(\\S+\\.rb)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*perl\\s+(\\S+\\.pl)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*php\\s+(\\S+\\.php)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*lua\\s+(\\S+\\.lua)/i,\n];\n\n\n// ==================== Keyword combination risk rules ====================\n\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\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 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 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 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 return { level: bestLevel, reason: bestReason };\n}\n\n\n// ==================== Script path extraction ====================\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 extractInlineScriptPath(actionDetail: string): string | null {\n const re = /open\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(actionDetail)) !== null) {\n const p = m[1];\n let resolved: string;\n try {\n resolved = resolvePath(p);\n if (existsSync(resolved)) {\n const stat = statSync(resolved);\n if (stat.isFile()) return resolved;\n }\n } catch { /* ignore */ }\n }\n return null;\n}\n\n/** Resolve a path: expand ~, resolve relative against cwd. */\nfunction resolvePath(p: string): string {\n let expanded = p;\n if (expanded.startsWith('~/') || expanded === '~') {\n expanded = join(homedir(), expanded.slice(1));\n }\n return resolve(expanded);\n}\n\n\n// ==================== Script content reading ====================\n\nfunction readScriptContent(\n scriptPath: string,\n maxFileSize: number = 2 * 1024 * 1024,\n): { content: string; lineCount: number; fileSize: number; error: string } {\n try {\n const path = resolvePath(scriptPath);\n if (!existsSync(path)) return { content: '', lineCount: 0, fileSize: 0, error: `脚本不存在: ${scriptPath}` };\n\n const stat = statSync(path);\n if (!stat.isFile()) return { content: '', lineCount: 0, fileSize: 0, error: `不是文件: ${scriptPath}` };\n if (stat.size > maxFileSize) {\n return { content: '', lineCount: 0, fileSize: stat.size, error: `脚本文件过大 (${stat.size} bytes),跳过读取` };\n }\n\n const content = readFileSync(path, 'utf-8');\n const lineCount = content ? content.split('\\n').length : 0;\n return { content, lineCount, fileSize: stat.size, error: '' };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n return { content: '', lineCount: 0, fileSize: 0, error: `读取脚本失败: ${msg}` };\n }\n}\n\n\n// ==================== Recursive tracking ====================\n\nfunction extractChildScriptPaths(content: string, baseDir: string): string[] {\n const paths: string[] = [];\n for (const pattern of CHILD_SCRIPT_PATTERNS) {\n pattern.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = pattern.exec(content)) !== null) {\n const pathStr = m[1];\n if (pathStr.startsWith('-') || pathStr.startsWith('$')) continue;\n if (pathStr.includes('/dev/') || pathStr.startsWith('|') || pathStr.startsWith(';')) continue;\n const full = isAbsolute(pathStr) ? pathStr : join(baseDir, pathStr);\n const resolved = resolvePath(full);\n if (existsSync(resolved)) {\n try {\n if (statSync(resolved).isFile() && !paths.includes(resolved)) paths.push(resolved);\n } catch { /* ignore */ }\n }\n }\n }\n return paths;\n}\n\n/**\n * Recursive script chain tracking. Reads + preprocesses each node.\n *\n * @param entryPath entry script path\n * @param input original AnalysisInput (used to build virtual per-node inputs for\n * L1/L2 reuse — carries promptSession/actionHistory/cwd for intent + path checks)\n * @param maxDepth max recursion depth (0=entry, 1=entry's children, ...)\n * @param maxFileSize per-file size cap (default 2MB)\n * @param maxTotalSize cumulative size cap (default 6MB)\n */\nfunction resolveScriptChain(\n entryPath: string,\n input: AnalysisInput,\n maxDepth: number = 3,\n maxFileSize: number = 2 * 1024 * 1024,\n maxTotalSize: number = 6 * 1024 * 1024,\n): ScriptChainAnalysisResult {\n const visited = new Set<string>();\n const result = emptyChain();\n result.entryPath = entryPath;\n\n const entry = resolvePath(entryPath);\n const baseDir = existsSync(entry) ? dirname(entry) : (input.cwd || process.cwd());\n\n resolveRecursive({\n path: entry, depth: 0, maxDepth, maxFileSize, maxTotalSize,\n visited, result, baseDir, input,\n });\n\n result.hasCritical = result.nodes.some(n =>\n n.l1RiskLevel === 'critical' || n.l2RiskLevel === 'critical' || n.keywordRiskLevel === 'critical');\n result.hasHigh = result.nodes.some(n =>\n ['high', 'critical'].includes(n.l1RiskLevel) ||\n ['high', 'critical'].includes(n.l2RiskLevel) ||\n ['high', 'critical'].includes(n.keywordRiskLevel));\n result.firstHitNode = result.nodes.find(n => n.l1Hit || n.l2Hit || n.isSuspicious) || null;\n\n return result;\n}\n\ninterface ResolveCtx {\n path: string;\n depth: number;\n maxDepth: number;\n maxFileSize: number;\n maxTotalSize: number;\n visited: Set<string>;\n result: ScriptChainAnalysisResult;\n baseDir: string;\n input: AnalysisInput;\n}\n\nfunction resolveRecursive(ctx: ResolveCtx): void {\n const { path, depth, maxDepth, maxFileSize, maxTotalSize, visited, result, baseDir, input } = ctx;\n\n if (visited.has(path)) return;\n if (depth > maxDepth) {\n result.maxDepthReached = true;\n return;\n }\n if (result.totalSize >= maxTotalSize) {\n result.maxSizeReached = true;\n return;\n }\n\n visited.add(path);\n\n const { content, lineCount, fileSize, error } = readScriptContent(path, maxFileSize);\n if (error) {\n const node = newNode(path, depth);\n node.error = error;\n node.fileSize = fileSize;\n node.lineCount = lineCount;\n result.nodes.push(node);\n return;\n }\n\n result.totalSize += fileSize;\n result.totalLines += lineCount;\n\n const preprocessed = preprocessScriptContent(content);\n const node = newNode(path, depth);\n node.rawContent = content;\n node.preprocessedContent = preprocessed;\n node.lineCount = lineCount;\n node.fileSize = fileSize;\n result.nodes.push(node);\n\n // Inline L1 + L2 scan during recursion (virtual input = preprocessed content)\n const virtualInput: AnalysisInput = {\n ...input,\n aNext: { actionType: 'bash', actionDetail: preprocessed },\n };\n const l1 = runHeuristicCheck(virtualInput);\n if (l1 && !l1.allowed) {\n node.l1Hit = true;\n node.l1RiskLevel = l1.riskLevel;\n node.l1RiskType = l1.riskType;\n node.l1Reason = l1.reason;\n node.l1MatchedPatterns = [];\n if (l1.riskLevel === 'critical') {\n result.hasCritical = true;\n result.firstHitNode = node;\n return;\n }\n }\n\n const childPaths = extractChildScriptPaths(preprocessed, baseDir);\n node.childPaths = childPaths;\n\n for (const childPath of childPaths) {\n resolveRecursive({\n path: resolvePath(childPath), depth: depth + 1, maxDepth, maxFileSize, maxTotalSize,\n visited, result, baseDir: dirname(resolvePath(childPath)), input,\n });\n if (result.hasCritical) return;\n }\n}\n\n\n// ==================== L1/L2 fallback chain scan ====================\n\n/** L1 fallback: scan nodes that weren't inline-scanned during recursion. */\nfunction scanScriptChainWithL1(chain: ScriptChainAnalysisResult, input: AnalysisInput): ScriptChainAnalysisResult {\n for (const node of chain.nodes) {\n if (node.error || !node.preprocessedContent || node.l1Hit) continue;\n const virtualInput: AnalysisInput = {\n ...input,\n aNext: { actionType: 'bash', actionDetail: node.preprocessedContent },\n };\n const l1 = runHeuristicCheck(virtualInput);\n if (l1 && !l1.allowed) {\n node.l1Hit = true;\n node.l1RiskLevel = l1.riskLevel;\n node.l1RiskType = l1.riskType;\n node.l1Reason = l1.reason;\n if (l1.riskLevel === 'critical') {\n chain.hasCritical = true;\n chain.firstHitNode = node;\n break;\n }\n }\n }\n return chain;\n}\n\n/**\n * L2 fallback: scan each node's preprocessed content via runLogicCheck.\n * Only reuses action-history-independent rules (sensitive path / dangerous\n * patterns / intent). runLogicCheck runs all L2 rules; we accept its verdict\n * per node (matching Python's per-rule reuse behaviorally).\n */\nfunction scanScriptChainWithL2(chain: ScriptChainAnalysisResult, input: AnalysisInput): ScriptChainAnalysisResult {\n for (const node of chain.nodes) {\n if (node.error || !node.preprocessedContent) continue;\n if (node.l1RiskLevel === 'critical') break;\n\n const virtualInput: AnalysisInput = {\n ...input,\n aNext: { actionType: 'bash', actionDetail: node.preprocessedContent },\n };\n const l2 = runLogicCheck(virtualInput);\n if (l2 && !l2.allowed) {\n node.l2Hit = true;\n node.l2ViolatedRule = `script_logic:${node.scriptPath}`;\n node.l2RiskLevel = l2.riskLevel;\n node.l2RiskType = l2.riskType;\n node.l2Reason = `脚本 ${node.scriptPath} (深度 ${node.depth}) 中: ${l2.reason}`;\n if (l2.riskLevel === 'critical') {\n chain.hasCritical = true;\n chain.firstHitNode = node;\n break;\n }\n }\n }\n if (!chain.hasHigh) {\n chain.hasHigh = chain.nodes.some(n => ['high', 'critical'].includes(n.l2RiskLevel));\n }\n return chain;\n}\n\n/** Keyword scan per node (L3-compatible). Only nodes not hit by L1/L2. */\nfunction scanScriptChainKeywords(chain: ScriptChainAnalysisResult): ScriptChainAnalysisResult {\n for (const node of chain.nodes) {\n if (node.error || !node.preprocessedContent) continue;\n if (node.l1Hit || node.l2Hit) continue;\n\n const matched = scanScriptForKeywords(node.preprocessedContent);\n node.matchedKeywords = matched;\n node.isSuspicious = matched.length > 0;\n\n if (matched.length > 0) {\n const risk = assessKeywordCombinationRisk(matched, node.preprocessedContent);\n node.keywordRiskLevel = risk.level;\n node.keywordRiskReason = risk.reason;\n }\n }\n return chain;\n}\n\n\n// ==================== Entry function ====================\n\n/**\n * Analyze script content: recursive tracking + preprocessing + L1/L2/keyword scan.\n * Only runs when actionType is 'bash' and the command invokes a script.\n *\n * Mirrors Python analyze_script_content. L1/L2 reuse wraps each node's\n * preprocessed content as a virtual AnalysisInput.\n */\nexport function analyzeScriptContent(input: AnalysisInput): ScriptChainAnalysisResult {\n const actionType = input.aNext.actionType.toLowerCase();\n if (actionType !== 'bash') return emptyChain();\n\n const scriptPath = extractScriptPath(input.aNext.actionDetail);\n let resolvedPath = scriptPath;\n if (!resolvedPath) {\n const inline = extractInlineScriptPath(input.aNext.actionDetail);\n if (!inline) return emptyChain();\n resolvedPath = inline;\n }\n\n const chain = resolveScriptChain(resolvedPath, input);\n if (chain.nodes.length === 0) return chain;\n\n // L1 fallback + L2 + keyword scans\n scanScriptChainWithL1(chain, input);\n scanScriptChainWithL2(chain, input);\n scanScriptChainKeywords(chain);\n\n return chain;\n}\n\n\n// ==================== L3 prompt formatting ====================\n\nexport function formatScriptChainForPrompt(chain: ScriptChainAnalysisResult): string {\n if (chain.nodes.length === 0) return '';\n\n const errorNodes = chain.nodes.filter(n => n.error);\n if (errorNodes.length > 0 && chain.nodes.length === 1) {\n return `⚠️ 脚本内容分析失败: ${errorNodes[0].error}`;\n }\n\n const suspiciousNodes = chain.nodes.filter(n => n.isSuspicious && !n.l1Hit && !n.l2Hit);\n if (suspiciousNodes.length === 0) {\n const safeNodes = chain.nodes.filter(n => !n.error);\n if (safeNodes.length === 0) return '';\n const parts: string[] = ['✓ 脚本内容已分析,未发现危险/可疑操作(L1/L2/关键词扫描均未命中):'];\n for (const node of safeNodes) {\n const pre = node.preprocessedContent || '';\n let preview = pre.slice(0, 600);\n if (pre.length > 600) preview += `\\n... (截断,完整内容 ${pre.length} 字符)`;\n parts.push(\n ` 脚本路径: ${node.scriptPath}(递归深度 ${node.depth},${node.lineCount} 行)\\n` +\n ` 内容(预处理后):\\n\\`\\`\\`\\n${preview}\\n\\`\\`\\``\n );\n }\n return parts.join('\\n');\n }\n\n const parts: string[] = [];\n for (const node of suspiciousNodes) {\n const keywordsStr = node.matchedKeywords.join(', ');\n let riskHint = '';\n if (node.keywordRiskLevel && node.keywordRiskReason) {\n riskHint =\n `\\n\\n🔴 **风险评估**: ${node.keywordRiskLevel.toUpperCase()} 级别\\n` +\n `**风险原因**: ${node.keywordRiskReason}\\n` +\n `**建议**: 此脚本应被拒绝(Deny),除非有明确的业务需求且已确认目标服务器可信。`;\n }\n const pre = node.preprocessedContent;\n let contentPreview = pre.slice(0, 2000);\n if (pre.length > 2000) contentPreview += `\\n... (截断,完整内容 ${pre.length} 字符)`;\n parts.push(\n `⚠️ 脚本内容包含可疑关键词:\\n` +\n ` 脚本路径: ${node.scriptPath}\\n` +\n ` 递归深度: ${node.depth}\\n` +\n ` 可疑关键词: ${keywordsStr}\\n` +\n ` 脚本行数: ${node.lineCount}${riskHint}\\n\\n` +\n `### 脚本内容(预处理后)###\\n\\`\\`\\`\\n${contentPreview}\\n\\`\\`\\`\\n`\n );\n }\n\n let header = `⚠️ 检测到脚本执行链(共 ${chain.nodes.length} 个脚本),其中 ${suspiciousNodes.length} 个包含可疑关键词:\\n`;\n if (chain.maxDepthReached) header += '⚠️ 注意:递归追踪触达深度上限,可能存在更深层的脚本调用未被扫描。\\n';\n if (chain.maxSizeReached) header += '⚠️ 注意:累计文件大小触达上限,部分脚本可能未被完整读取。\\n';\n\n return header + parts.join('\\n---\\n\\n');\n}\n\n/** [deprecated] Use formatScriptChainForPrompt. */\nexport function formatScriptAnalysisForPrompt(chain: ScriptChainAnalysisResult): string {\n return formatScriptChainForPrompt(chain);\n}\n\nconst CHILD_SCRIPT_PATTERNS: RegExp[] = [\n /(?:^|\\s|&&|\\|\\|)\\s*bash\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*sh\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*source\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*\\.\\s+(\\S+)/,\n /(?:^|\\s|&&|\\|\\|)\\s*python3?\\s+(\\S+\\.py)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*node\\s+(\\S+\\.js)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*ruby\\s+(\\S+\\.rb)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*perl\\s+(\\S+\\.pl)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*php\\s+(\\S+\\.php)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*lua\\s+(\\S+\\.lua)/i,\n];\n","/**\n * Token usage statistics — record and query LLM token consumption.\n *\n * Mirrors Python agent_moss/infra/token_stats.py.\n *\n * Storage: JSON file at ~/.config/agentmoss/agent_moss_token_stats.json\n * (env override AGENT_MOSS_TOKEN_STATS_PATH). Whole-file rewrite per record\n * (not append). Max 10000 records, oldest trimmed.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nconst STATS_DIR = join(homedir(), '.config', 'agentmoss');\nconst STATS_FILE = join(STATS_DIR, 'agent_moss_token_stats.json');\nconst ENV_STATS_PATH = 'AGENT_MOSS_TOKEN_STATS_PATH';\nconst MAX_RECORDS = 10000;\n\nexport interface TokenUsageRecord {\n timestamp?: string; // ISO with milliseconds; auto-filled if omitted\n sessionId: string;\n step: string; // \"L3_security_judge\" | \"step2_policy_gen\"\n model: string;\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\ninterface RawRecord {\n timestamp: string;\n session_id: string;\n step: string;\n model: string;\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n}\n\ninterface Aggregated {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n calls: number;\n}\n\nexport interface TokenStatsSummary {\n total_prompt_tokens: number;\n total_completion_tokens: number;\n total_tokens: number;\n total_calls: number;\n by_step: Record<string, Aggregated>;\n by_model: Record<string, Aggregated>;\n by_date: Record<string, Aggregated>;\n}\n\nexport interface TokenTrend {\n dates: string[];\n models: string[];\n series: Record<string, Record<string, number>>;\n}\n\nfunction getStatsPath(): string {\n const envPath = process.env[ENV_STATS_PATH];\n return envPath || STATS_FILE;\n}\n\nfunction loadAllRecords(statsPath: string): RawRecord[] {\n if (!existsSync(statsPath)) return [];\n try {\n const data = JSON.parse(readFileSync(statsPath, 'utf-8'));\n if (Array.isArray(data)) return data;\n if (data && Array.isArray(data.records)) return data.records;\n return [];\n } catch (e) {\n return [];\n }\n}\n\nfunction saveRecords(statsPath: string, records: RawRecord[]): void {\n try {\n const dir = statsPath.substring(0, statsPath.lastIndexOf('/'));\n if (dir && !existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(statsPath, JSON.stringify(records, null, 2), 'utf-8');\n } catch (e) {\n // best-effort\n }\n}\n\n/** Record a single LLM call's token usage. */\nexport function recordTokenUsage(record: TokenUsageRecord): void {\n const statsPath = getStatsPath();\n const records = loadAllRecords(statsPath);\n records.push({\n timestamp: record.timestamp || new Date().toISOString(),\n session_id: record.sessionId,\n step: record.step,\n model: record.model,\n prompt_tokens: record.promptTokens,\n completion_tokens: record.completionTokens,\n total_tokens: record.totalTokens,\n });\n if (records.length > MAX_RECORDS) {\n records.splice(0, records.length - MAX_RECORDS);\n }\n saveRecords(statsPath, records);\n}\n\nfunction filterByDate(\n records: RawRecord[],\n days: number = 0,\n startDate?: string | null,\n endDate?: string | null,\n): RawRecord[] {\n if (startDate || endDate) {\n let startDt = startDate ? new Date(startDate) : new Date(-8640000000000000);\n let endDt = endDate ? new Date(endDate) : undefined;\n if (endDate) {\n const e = new Date(endDate);\n e.setHours(23, 59, 59, 999);\n endDt = e;\n }\n const endMs = endDt ? endDt.getTime() : Number.MAX_SAFE_INTEGER;\n return records.filter(r => {\n try {\n const ts = new Date(r.timestamp).getTime();\n return ts >= startDt.getTime() && ts <= endMs;\n } catch { return true; }\n });\n } else if (days > 0) {\n const cutoff = Date.now() - days * 86400000;\n return records.filter(r => {\n try { return new Date(r.timestamp).getTime() >= cutoff; }\n catch { return true; }\n });\n }\n return records;\n}\n\nfunction aggregate(records: RawRecord[]): {\n totalPrompt: number; totalCompletion: number; totalTotal: number;\n byStep: Record<string, Aggregated>; byModel: Record<string, Aggregated>; byDate: Record<string, Aggregated>;\n} {\n let totalPrompt = 0, totalCompletion = 0, totalTotal = 0;\n const byStep: Record<string, Aggregated> = {};\n const byModel: Record<string, Aggregated> = {};\n const byDate: Record<string, Aggregated> = {};\n\n const bucket = (b: Record<string, Aggregated>, key: string, r: RawRecord) => {\n const e = b[key] || (b[key] = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0, calls: 0 });\n e.prompt_tokens += r.prompt_tokens || 0;\n e.completion_tokens += r.completion_tokens || 0;\n e.total_tokens += r.total_tokens || 0;\n e.calls += 1;\n };\n\n for (const r of records) {\n totalPrompt += r.prompt_tokens || 0;\n totalCompletion += r.completion_tokens || 0;\n totalTotal += r.total_tokens || 0;\n bucket(byStep, r.step || 'unknown', r);\n bucket(byModel, r.model || 'unknown', r);\n let dateKey = 'unknown';\n try {\n dateKey = new Date(r.timestamp).toISOString().slice(0, 10);\n } catch { /* keep unknown */ }\n bucket(byDate, dateKey, r);\n }\n\n // by_date sorted desc by date\n const sortedDate = Object.keys(byDate).sort((a, b) => (a < b ? 1 : a > b ? -1 : 0));\n const sortedByDate: Record<string, Aggregated> = {};\n for (const k of sortedDate) sortedByDate[k] = byDate[k];\n\n return { totalPrompt, totalCompletion, totalTotal, byStep, byModel, byDate: sortedByDate };\n}\n\nexport function getTokenStats(\n days: number = 0,\n startDate?: string | null,\n endDate?: string | null,\n): TokenStatsSummary {\n const records = filterByDate(loadAllRecords(getStatsPath()), days, startDate, endDate);\n const a = aggregate(records);\n return {\n total_prompt_tokens: a.totalPrompt,\n total_completion_tokens: a.totalCompletion,\n total_tokens: a.totalTotal,\n total_calls: records.length,\n by_step: a.byStep,\n by_model: a.byModel,\n by_date: a.byDate,\n };\n}\n\nexport function getRecentRecords(limit: number = 20): RawRecord[] {\n const records = loadAllRecords(getStatsPath());\n return records.slice(-limit);\n}\n\nexport function getTokenTrend(\n days: number = 0,\n startDate?: string | null,\n endDate?: string | null,\n): TokenTrend {\n const records = filterByDate(loadAllRecords(getStatsPath()), days, startDate, endDate);\n const series: Record<string, Record<string, number>> = {};\n const datesSet = new Set<string>();\n for (const r of records) {\n let dateKey: string;\n try { dateKey = new Date(r.timestamp).toISOString().slice(0, 10); }\n catch { continue; }\n const model = r.model || 'unknown';\n const tokens = r.total_tokens || 0;\n datesSet.add(dateKey);\n series[model] = series[model] || {};\n series[model][dateKey] = (series[model][dateKey] || 0) + tokens;\n }\n const dates = Array.from(datesSet).sort();\n const models = Object.keys(series).sort();\n return { dates, models, series };\n}\n\nexport function resetTokenStats(): void {\n const statsPath = getStatsPath();\n if (existsSync(statsPath)) {\n try { unlinkSync(statsPath); } catch { /* ignore */ }\n }\n}\n","import { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getLLMConfig, isLLMAvailable, detectProvider, getProviderHeaders, getTimeoutConfig, getRetryConfig } from '../config';\nimport { matchSkills, formatSkillsForPrompt } from './skill-loader';\nimport { loadTemplates } from './template-loader';\nimport { analyzeScriptContent, formatScriptAnalysisForPrompt } from './script-analyzer';\nimport { formatScriptChainForPrompt } from './script-content-analyzer';\nimport { appendFileSync } from 'fs';\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 skipL3Hints?: string;\n scriptChain?: import('./script-content-analyzer').ScriptChainAnalysisResult;\n /** per-request LLM prompt 日志路径(来自调用方 metadata.llm_log_path) */\n llmLogPath?: string;\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 // 优先使用 per-request 的 LLM 配置(OpenDesk 按当前会话模型传入)\n const globalConfig = getLLMConfig();\n const config = input.llmConfig?.apiKey\n ? { ...globalConfig, ...input.llmConfig }\n : globalConfig;\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. Prefer the script chain from coordinator\n // (L1.5/L2.5 already did recursive tracking); fall back to single-file scan.\n let scriptAnalysis: import('./script-analyzer').ScriptAnalysisResult | undefined;\n let scriptChainText = '';\n if (previous.scriptChain) {\n scriptChainText = formatScriptChainForPrompt(previous.scriptChain);\n } else {\n scriptAnalysis = analyzeScriptContent(input.aNext.actionType, input.aNext.actionDetail);\n }\n const prompt = buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis, previous.skipL3Hints ?? '', scriptChainText);\n\n // 写 LLM prompt 到日志(per-request logPath 优先,对齐 py _log_prompt)。\n // 与 bridge.ts 写 HOOK_INPUT/HOOK_OUTPUT 同一个文件,对齐 audit_agent AUDIT_LOG_PATH。\n logPrompt(prompt, input.aNext, previous.llmLogPath);\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\n/**\n * 写 LLM prompt 到日志文件(对齐 Python _log_prompt)。\n * logPath 来自 per-request metadata.llm_log_path(调用方 env 注入)。\n * 与 bridge.ts 的 HOOK_INPUT/HOOK_OUTPUT 写同一个文件,对齐 audit_agent AUDIT_LOG_PATH。\n */\nfunction logPrompt(prompt: string, aNext: { actionType: string; actionDetail: string }, logPath?: string): void {\n if (!logPath) return;\n try {\n const actionType = aNext.actionType || 'unknown';\n const actionDetail = (aNext.actionDetail || '').slice(0, 100);\n const line =\n `[${new Date().toISOString()}] ` +\n `[LLM_PROMPT] action_type=${actionType}, action_detail=${actionDetail}... ` +\n `prompt_length=${prompt.length}\\n` +\n `${prompt}\\n` +\n `--- END PROMPT ---\\n`;\n appendFileSync(logPath, line, 'utf-8');\n } catch (e) {\n console.warn('[AgentMoss] Failed to write LLM prompt to log:', e);\n }\n}\n\nexport function 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 skipL3Hints: string = '',\n scriptChainText: string = '',\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 // Prefer coordinator-provided script chain text (recursive tracking result);\n // fall back to single-file keyword prescan; else empty.\n const scriptAnalysisText = scriptChainText\n ? scriptChainText\n : (scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : '');\n\n // Format L1/L2 hints (mirrors Python LLMAnalyzer._format_hints)\n const hintsText = formatHints(previous);\n\n // Layer 3 安全判断用 security_judge_template(对齐 Python get_security_judge_prompt)。\n // prompt1/prompt2 是 Cerberus 沙箱策略模板,不适用于此处的 Allow/Deny 裁决。\n const securityJudgeTemplate = templates['security_judge'];\n if (securityJudgeTemplate) {\n // 占位符逐个替换(不能用全局 {x} 正则:模板 JSON 示例里的 {{ }} 会误伤)。\n // security_judge_template.txt 用 {{ }} 转义 JSON 大括号,替换完后还原为单括号。\n return securityJudgeTemplate\n .replaceAll('{prompt_session}', input.promptSession || '(未提供)')\n .replaceAll('{action_history}', historyStr)\n .replaceAll('{action_type}', input.aNext.actionType)\n .replaceAll('{action_detail}', input.aNext.actionDetail)\n .replaceAll('{reason}', input.reason || '未说明')\n .replaceAll('{skills_text}', skillsText)\n .replaceAll('{hints_text}', hintsText)\n .replaceAll('{script_analysis_text}', scriptAnalysisText)\n .replaceAll('{skip_l3_hints}', skipL3Hints)\n .replaceAll('{{', '{')\n .replaceAll('}}', '}');\n }\n\n // Fallback:security_judge 模板缺失时(旧包/加载异常),退回稀疏 prompt,避免崩溃。\n // 这种情况下 LLM 裸跑,判断质量下降,但不阻断流程。\n console.warn('[AgentMoss] security_judge template missing, using sparse fallback prompt');\n return `## 当前操作上下文\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请根据以上信息,对即将执行的操作进行安全判断。前置检测为 low/medium 且有合理执行理由时应当允许。你必须输出严格的 JSON 格式,不要包含任何其他文字、注释或 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 timeoutCfg = getTimeoutConfig();\n const retryCfg = getRetryConfig();\n const client = new OpenAI({\n baseURL: config.baseUrl,\n apiKey: config.apiKey,\n // 单次 LLM 调用超时用 prompt1Timeout(对齐 py);env 覆盖的 config.timeout 仍向后兼容\n timeout: (config.timeout || timeoutCfg.prompt1Timeout) * 1000,\n defaultHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined,\n });\n\n // maxRetries 优先 env,否则用 retry 配置(默认 2,对齐 py)\n const maxRetries = parseInt(process.env.AGENT_MOSS_LLM_RETRIES || String(retryCfg.maxRetries), 10);\n\n // totalTimeout 强制执行:用 AbortController 确保整个 LLM 分析(含所有重试)\n // 在 totalTimeout(默认 90s)后强制中断,防止最坏情况 ~372s 超时。\n const totalTimeoutMs = timeoutCfg.totalTimeout * 1000;\n const abortController = new AbortController();\n const totalTimeoutTimer = setTimeout(() => {\n console.error(`[AgentMoss] totalTimeout (${timeoutCfg.totalTimeout}s) exceeded, aborting all LLM calls`);\n abortController.abort();\n }, totalTimeoutMs);\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (abortController.signal.aborted) {\n break;\n }\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: '只输出纯 JSON,不要包含 markdown 标记、代码块或任何其他文字。' },\n { role: 'user', content: prompt },\n ],\n signal: abortController.signal,\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 // 记录 token 用量(step=\"L3_security_judge\")\n try {\n const usage = response.usage;\n const { recordTokenUsage } = await import('./token-stats');\n recordTokenUsage({\n sessionId: 'audit',\n step: 'L3_security_judge',\n model: response.model || config.model,\n promptTokens: usage?.prompt_tokens || 0,\n completionTokens: usage?.completion_tokens || 0,\n totalTokens: usage?.total_tokens || 0,\n });\n } catch { /* token stats optional */ }\n\n clearTimeout(totalTimeoutTimer);\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 // totalTimeout 触发的 AbortError:直接跳出循环,不再重试\n if (abortController.signal.aborted) {\n console.error(`[AgentMoss] LLM analysis aborted by totalTimeout (${timeoutCfg.totalTimeout}s)`);\n break;\n }\n if (attempt < maxRetries) {\n console.error(`[AgentMoss] LLM call failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${retryCfg.retryInterval}s:`, (err as Error).message);\n await new Promise(resolve => setTimeout(resolve, retryCfg.retryInterval * 1000));\n } else {\n clearTimeout(totalTimeoutTimer);\n console.error('[AgentMoss] LLM call failed after all retries:', (err as Error).message);\n throw new Error(`LLM 分析失败 (${maxRetries + 1} 次尝试): ${(err as Error).message}`);\n }\n }\n }\n\n // totalTimeout 超时或 AbortError 导致循环中断\n clearTimeout(totalTimeoutTimer);\n throw new Error(`LLM 分析超时(totalTimeout ${timeoutCfg.totalTimeout}s)`);\n}\n","/**\n * Runtime config — full implementation (mirrors Python runtime_config.py).\n *\n * Runtime JSON: ~/.config/agentmoss/agent_moss_runtime.json\n * (env AGENT_MOSS_RUNTIME_CONFIG_PATH override). Seed from OSProfile +\n * module consts + SKILL_KEYWORD_MAP. mergeConfig on load (preserve user\n * toggles, append builtins, mark removed).\n *\n * Priority: env > runtime JSON > agent_moss_settings > default.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n// 静态 import(非 require):package.json type=module,require 在 ESM 不可用。\n// 这三个模块不反向 import runtime-config,无循环依赖。\nimport { DANGEROUS_PATTERNS, INJECTION_KEYWORDS } from '../engine/heuristic';\nimport {\n ROOT_SENSITIVE_PATHS, HOME_SENSITIVE_PATHS, CREDENTIAL_PATHS,\n PASSWORD_MODIFY_PATTERNS, USER_DELETION_PATTERNS, INTENT_DEVIATION_PATTERNS,\n} from '../engine/logic-rules';\nimport { SKILL_KEYWORD_MAP } from '../engine/skill-loader';\n\nconst RUNTIME_CONFIG_DIR = join(homedir(), '.config', 'agentmoss');\nconst RUNTIME_CONFIG_PATH = join(RUNTIME_CONFIG_DIR, 'agent_moss_runtime.json');\nconst ENV_RUNTIME_CONFIG_PATH = 'AGENT_MOSS_RUNTIME_CONFIG_PATH';\n\nconst LAYER_DISABLE_ENV: Record<string, string> = {\n L1_heuristic: 'AGENT_MOSS_DISABLE_HEURISTIC',\n L2_logic_rules: 'AGENT_MOSS_DISABLE_LOGIC_RULES',\n L3_llm_analysis: 'AGENT_MOSS_DISABLE_LLM',\n};\n\nexport const DENY_MODE_LABELS: Record<string, string> = {\n deny_write: '仅拦截写入',\n deny_read: '仅拦截读取',\n deny_both: '读写均拦截',\n};\n\n// ==================== Types ====================\n\nexport interface Rule {\n id: string;\n enabled: boolean;\n builtin: boolean;\n source_removed?: boolean;\n pattern?: string;\n risk_level?: string;\n risk_type?: string;\n reason?: string;\n keyword?: string;\n lang?: string;\n path?: string;\n desc?: string;\n deny_mode?: string;\n source_deny_mode?: string;\n credential?: boolean;\n read_only?: boolean;\n skip_l3_on_disabled?: boolean;\n intent_keywords?: string[];\n dangerous_actions?: string[];\n}\n\nexport interface Skill {\n id: string;\n keywords: string[];\n enabled: boolean;\n builtin: boolean;\n}\n\ninterface Category {\n category_enabled?: boolean;\n category_desc?: string;\n rules?: Rule[];\n skills?: Skill[];\n}\n\nexport interface RuntimeConfig {\n version: number;\n layers: { L1_heuristic: boolean; L2_logic_rules: boolean; L3_llm_analysis: boolean };\n L1_rules: Record<string, Category>;\n L2_rules: Record<string, Category>;\n L3_skills: Record<string, Category>;\n}\n\n// ==================== Path / load / save ====================\n\nexport function getRuntimeConfigPath(): string {\n const envPath = process.env[ENV_RUNTIME_CONFIG_PATH];\n if (envPath) return envPath;\n // agent_moss_settings.json fallback omitted in TS (env-only); default path.\n return RUNTIME_CONFIG_PATH;\n}\n\nexport function saveRuntimeConfig(config: RuntimeConfig): void {\n const p = getRuntimeConfigPath();\n const dir = p.substring(0, p.lastIndexOf('/'));\n if (dir && !existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(p, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n/** Minimal default (all layers on, empty rule categories). The full\n * profile-driven seed generator (generate_source_defaults equivalent)\n * is deferred to Stage 4 (console backend); for now a missing runtime\n * file yields this minimal config — coordinator's getDisabledL2RulesWithSkipL3\n * returns {} (safe default, no skip_l3 hard constraint). */\nfunction emptyRuntimeConfig(): RuntimeConfig {\n return {\n version: 1,\n layers: { L1_heuristic: true, L2_logic_rules: true, L3_llm_analysis: true },\n L1_rules: {},\n L2_rules: {},\n L3_skills: {},\n };\n}\n\nexport function loadRuntimeConfig(): RuntimeConfig {\n const p = getRuntimeConfigPath();\n if (!existsSync(p)) {\n // 首次:seed + save,与 py load_runtime_config 的 fallback seed 对齐。\n // 不 seed 时 getDisabledL2RulesWithSkipL3 返回 {}(无 skip_l3 约束),\n // 但 Console 需要全量规则展示,所以必须 seed。\n const seeded = mergeConfig({}, generateSourceDefaults());\n try { saveRuntimeConfig(seeded); } catch { /* 只读 fs 时忽略 */ }\n return seeded;\n }\n try {\n const data = JSON.parse(readFileSync(p, 'utf-8'));\n const merged = mergeConfig(data, generateSourceDefaults());\n return {\n version: data.version || 1,\n layers: {\n L1_heuristic: data.layers?.L1_heuristic ?? true,\n L2_logic_rules: data.layers?.L2_logic_rules ?? true,\n L3_llm_analysis: data.layers?.L3_llm_analysis ?? true,\n },\n L1_rules: merged.L1_rules || {},\n L2_rules: merged.L2_rules || {},\n L3_skills: merged.L3_skills || {},\n };\n } catch {\n return emptyRuntimeConfig();\n }\n}\n\n// ==================== Layer toggles ====================\n\n/**\n * Is a layer enabled? Priority: env > runtime JSON > default true.\n *\n * Note: the agent_moss_settings.json fallback (used in Python) is not\n * consulted here — env vars are the primary TS-side override. The runtime\n * JSON is authoritative when env is unset.\n */\nexport function isLayerEnabled(layerKey: string): boolean {\n const disableKey = LAYER_DISABLE_ENV[layerKey];\n if (disableKey && process.env[disableKey] === '1') return false;\n const runtime = loadRuntimeConfig();\n const layers = runtime.layers || {} as RuntimeConfig['layers'];\n if (layerKey in layers) return !!layers[layerKey as keyof typeof layers];\n return true;\n}\n\nexport function getEnvOverrides(): Record<string, {\n env_var: string; env_value: string; overridden: boolean; effect: string;\n}> {\n const overrides: Record<string, any> = {};\n for (const [layerKey, envKey] of Object.entries(LAYER_DISABLE_ENV)) {\n const val = process.env[envKey];\n if (val !== undefined) {\n overrides[layerKey] = {\n env_var: envKey,\n env_value: val,\n overridden: val === '1',\n effect: val === '1' ? 'disabled' : 'no_override',\n };\n }\n }\n return overrides;\n}\n\n// ==================== Rule filtering / queries ====================\n\nexport function filterEnabledRules(rules: Rule[], categoryEnabled: boolean = true): Rule[] {\n if (!categoryEnabled) return [];\n return rules.filter(r => r.enabled !== false);\n}\n\nexport function getEnabledL1CommandPatterns(runtime: RuntimeConfig): { pattern: string; risk_level: string; risk_type: string; reason: string }[] {\n const cat = runtime.L1_rules?.dangerous_commands || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => ({\n pattern: r.pattern || '', risk_level: r.risk_level || '', risk_type: r.risk_type || '', reason: r.reason || '',\n }));\n}\n\nexport function getEnabledL2SensitivePaths(runtime: RuntimeConfig): { path: string; risk_level: string; desc: string; deny_mode: string; credential?: boolean; read_only?: boolean }[] {\n const cat = runtime.L2_rules?.sensitive_path_access || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => {\n const out: any = { path: r.path || '', risk_level: r.risk_level || '', desc: r.desc || '', deny_mode: r.deny_mode || 'deny_write' };\n if (r.credential) out.credential = true;\n if (r.read_only) out.read_only = true;\n return out;\n });\n}\n\nexport function hasRuntimeConfig(): boolean {\n const p = getRuntimeConfigPath();\n if (!existsSync(p)) return false;\n try {\n JSON.parse(readFileSync(p, 'utf-8'));\n return true;\n } catch { return false; }\n}\n\n// ==================== skip_l3 hard constraint ====================\n\n/**\n * L2 rules with enabled=false AND skip_l3_on_disabled=true, grouped by\n * category, returning their key content (path / intent_keywords / pattern).\n * Consumed by coordinator to build skip_l3_hints for the L3 prompt.\n */\nexport function getDisabledL2RulesWithSkipL3(): Record<string, string[]> {\n let runtime: RuntimeConfig;\n try { runtime = loadRuntimeConfig(); }\n catch { return {}; }\n const result: Record<string, string[]> = {};\n const l2 = runtime.L2_rules || {};\n for (const [catName, cat] of Object.entries(l2)) {\n if (!cat.category_enabled) continue;\n const items: string[] = [];\n for (const r of cat.rules || []) {\n if (r.enabled === false && r.skip_l3_on_disabled) {\n if (catName === 'sensitive_path_access') {\n if (r.path) items.push(r.path);\n } else if (catName === 'intent_consistency') {\n items.push(...(r.intent_keywords || []));\n } else if (r.pattern) {\n items.push(r.pattern);\n }\n }\n }\n if (items.length > 0) result[catName] = items;\n }\n return result;\n}\n\n// ==================== Helpers ====================\n\nfunction _slugify(text: string): string {\n return text.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '') || 'x';\n}\n\nfunction _generatePatternId(pattern: string): string {\n return `pat_${_slugify(pattern)}`;\n}\n\n/** 从 credential / read_only 推导 deny_mode(向后兼容)。优先用已有 deny_mode。 */\nfunction _deriveDenyMode(rule: Partial<Rule>): string {\n if (rule.deny_mode) return rule.deny_mode;\n if (rule.credential) return 'deny_both';\n if (rule.read_only) return 'deny_read';\n return 'deny_write';\n}\n\n/** 根据 deny_mode 同步 credential / read_only(保持底层检测逻辑兼容) */\nfunction _syncDenyModeFields(rule: Rule): void {\n const dm = rule.deny_mode || 'deny_write';\n if (dm === 'deny_both') {\n rule.credential = true;\n delete rule.read_only;\n } else if (dm === 'deny_read') {\n delete rule.credential;\n rule.read_only = true;\n } else {\n delete rule.credential;\n delete rule.read_only;\n }\n}\n\n// ==================== Seed (generateSourceDefaults) ====================\n//\n// py 的 generate_source_defaults 从 OSProfile 拿 dangerous_commands / sensitive_paths\n// / intent_deviation_patterns / injection_keywords(运行时按 OS 类型分叉)。\n// TS 不分 OS profile(只 win/linux 用于 os_type 字段,不影响规则集),规则集硬编码\n// 在 heuristic.ts / logic-rules.ts 常量里。所以 TS seed 直接从常量生成,不走 profile。\n\nfunction _l1CommandPatternsToRules(): Rule[] {\n // DANGEROUS_PATTERNS 是 RegExp,seed 时存 source 字符串。\n return DANGEROUS_PATTERNS.map((p) => ({\n id: _generatePatternId(p.pattern instanceof RegExp ? p.pattern.source : p.pattern),\n pattern: p.pattern instanceof RegExp ? p.pattern.source : p.pattern,\n risk_level: p.severity,\n risk_type: p.riskType,\n reason: p.description,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l1InjectionKeywordsToRules(): Rule[] {\n return INJECTION_KEYWORDS.map((kw) => ({\n id: `inj_${_slugify(kw.keyword)}`,\n keyword: kw.keyword,\n risk_level: kw.riskLevel,\n lang: kw.lang || 'en',\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l2SensitivePathsToRules(): Rule[] {\n const all = [...ROOT_SENSITIVE_PATHS, ...HOME_SENSITIVE_PATHS, ...CREDENTIAL_PATHS] as any[];\n return all.map((sp) => {\n const denyMode = _deriveDenyMode({\n deny_mode: sp.deny_mode,\n credential: sp.credential,\n read_only: sp.read_only,\n });\n const rule: Rule = {\n id: `path_${_slugify(sp.path)}`,\n path: sp.path,\n risk_level: sp.riskLevel,\n desc: sp.desc,\n deny_mode: denyMode,\n source_deny_mode: denyMode,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n };\n _syncDenyModeFields(rule);\n return rule;\n });\n}\n\nfunction _l2IntentPatternsToRules(): Rule[] {\n return INTENT_DEVIATION_PATTERNS.map((pat, i) => ({\n id: `intent_${i + 1}_${_slugify(pat.reason.slice(0, 30))}`,\n intent_keywords: pat.intentKeywords,\n dangerous_actions: pat.dangerousActions,\n reason: pat.reason,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l2PasswordPatternsToRules(): Rule[] {\n return PASSWORD_MODIFY_PATTERNS.map((p) => ({\n id: `pw_${_slugify(p.source)}`,\n pattern: p.source,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l2UserDeletionPatternsToRules(): Rule[] {\n return USER_DELETION_PATTERNS.map((p) => ({\n id: `ud_${_slugify(p.source)}`,\n pattern: p.source,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l3SkillsToRules(): Record<string, Category> {\n const skillCategories: Record<string, string[]> = {\n file_operations: ['file_access_guard', 'script_execution_guard', 'indirect_access_guard'],\n network_security: ['data_exfiltration_guard', 'browser_web_access_guard',\n 'lateral_movement_guard', 'email_operation_guard'],\n persistence_supply_chain: ['persistence_backdoor_guard', 'supply_chain_guard',\n 'skill_installation_guard'],\n intent_and_general: ['intent_deviation_guard', 'general_tool_risk_guard'],\n resource: ['resource_exhaustion_guard'],\n };\n const out: Record<string, Category> = {};\n for (const [cat, ids] of Object.entries(skillCategories)) {\n out[cat] = {\n category_enabled: true,\n category_desc: '',\n skills: ids.map((s: string) => ({\n id: s,\n keywords: SKILL_KEYWORD_MAP[s] || [],\n enabled: true,\n builtin: true,\n })),\n };\n }\n const categorized = new Set<string>(Object.values(skillCategories).flat());\n for (const s of Object.keys(SKILL_KEYWORD_MAP)) {\n if (!categorized.has(s)) {\n (out.intent_and_general ??= { category_enabled: true, category_desc: '', skills: [] })\n .skills!.push({\n id: s, keywords: SKILL_KEYWORD_MAP[s], enabled: true, builtin: true,\n });\n }\n }\n out.user_custom = { category_enabled: true, category_desc: '', skills: [] };\n return out;\n}\n\n/** 从 TS 常量生成 runtime 默认结构(出厂种子)。TS 不走 profile,直接从常量。 */\nexport function generateSourceDefaults(): RuntimeConfig {\n return {\n version: 1,\n layers: { L1_heuristic: true, L2_logic_rules: true, L3_llm_analysis: true },\n L1_rules: {\n dangerous_commands: {\n category_enabled: true,\n category_desc: '危险命令检测(递归删除、全权限设置、提权执行等)',\n rules: _l1CommandPatternsToRules(),\n },\n injection_detection: {\n category_enabled: true,\n category_desc: 'Prompt 注入攻击检测',\n rules: _l1InjectionKeywordsToRules(),\n },\n user_sensitive_actions: { category_enabled: true, category_desc: '用户自定义敏感动作/工具规则', rules: [] },\n user_custom: { category_enabled: true, category_desc: '用户自定义命令规则', rules: [] },\n },\n L2_rules: {\n sensitive_path_access: {\n category_enabled: true,\n category_desc: '敏感路径访问检测',\n rules: _l2SensitivePathsToRules(),\n },\n intent_consistency: {\n category_enabled: true,\n category_desc: '意图一致性检测',\n rules: _l2IntentPatternsToRules(),\n },\n password_modify_consent: {\n category_enabled: true,\n category_desc: '非交互式密码修改授权检测',\n rules: _l2PasswordPatternsToRules(),\n },\n user_deletion_consent: {\n category_enabled: true,\n category_desc: '用户/组删除操作授权检测',\n rules: _l2UserDeletionPatternsToRules(),\n },\n read_before_write: { category_enabled: true, category_desc: 'read_before_write 安全原则检测', rules: [] },\n dangerous_patterns: { category_enabled: true, category_desc: '危险操作模式检测', rules: [] },\n },\n L3_skills: _l3SkillsToRules(),\n };\n}\n\n// ==================== Merge (preserve user toggles) ====================\n\n/** 规则内容指纹(跨 id 变更识别同一规则)。 */\nfunction _ruleFingerprint(rule: Partial<Rule>): string {\n if ((rule.intent_keywords && rule.intent_keywords.length) || (rule.dangerous_actions && rule.dangerous_actions.length)) {\n return JSON.stringify([\n [...(rule.intent_keywords || [])].sort(),\n [...(rule.dangerous_actions || [])].sort(),\n ]);\n }\n if (rule.path) return JSON.stringify([rule.path]);\n if (rule.pattern) return JSON.stringify([rule.pattern]);\n if (rule.keyword) return JSON.stringify([rule.keyword, rule.lang || '']);\n return JSON.stringify([rule.id || '']);\n}\n\n/** 合并 L1/L2 分类与规则(保留用户 enabled/skip_l3/deny_mode,补入新 builtin,标记删除)。 */\nfunction _mergeRuleCategories(userCfg: RuntimeConfig, srcDefaults: RuntimeConfig, layerKey: 'L1_rules' | 'L2_rules'): void {\n const userLayer = (userCfg[layerKey] || (userCfg[layerKey] = {})) as Record<string, Category>;\n const srcLayer = srcDefaults[layerKey] || {};\n for (const [catName, srcCat] of Object.entries(srcLayer)) {\n if (!(catName in userLayer)) {\n userLayer[catName] = srcCat;\n continue;\n }\n const userCat: Category = userLayer[catName];\n if (userCat.category_desc === undefined) userCat.category_desc = srcCat.category_desc || '';\n if (userCat.category_enabled === undefined) userCat.category_enabled = srcCat.category_enabled ?? true;\n const srcRules = srcCat.rules || [];\n const userRules = (userCat.rules || (userCat.rules = []));\n const userByFp = new Map<string, Rule>();\n for (const r of userRules) userByFp.set(_ruleFingerprint(r), r);\n const srcFps = new Set<string>();\n for (const srcR of srcRules) {\n const fp = _ruleFingerprint(srcR);\n srcFps.add(fp);\n if (userByFp.has(fp)) {\n const existing = userByFp.get(fp)!;\n const userEnabled = existing.enabled;\n const userSkipL3 = existing.skip_l3_on_disabled;\n const userDenyMode = existing.deny_mode;\n const userSourceDeny = existing.source_deny_mode;\n Object.keys(existing).forEach(k => delete (existing as any)[k]);\n Object.assign(existing, srcR);\n existing.enabled = userEnabled;\n if (userSkipL3 !== undefined) existing.skip_l3_on_disabled = userSkipL3;\n if (userDenyMode && userSourceDeny && userDenyMode !== userSourceDeny) {\n existing.deny_mode = userDenyMode;\n }\n if (existing.deny_mode) _syncDenyModeFields(existing);\n } else {\n const newR: Rule = { ...srcR, enabled: true };\n userRules.push(newR);\n }\n }\n for (const r of userRules) {\n // builtin 且指纹不在 src 集合 → 源码已删除该规则\n if (r.builtin && !srcFps.has(_ruleFingerprint(r))) {\n r.source_removed = true;\n r.enabled = false;\n }\n }\n if (catName === 'sensitive_path_access') {\n for (const r of userRules) {\n if (!r.deny_mode) r.deny_mode = _deriveDenyMode(r);\n _syncDenyModeFields(r);\n }\n }\n }\n}\n\n/** 合并 L3_skills 分类。新分类整体加入;已有分类补全元字段 + 追加新 builtin skill。 */\nfunction _mergeSkillCategories(userCfg: RuntimeConfig, srcDefaults: RuntimeConfig, layerKey: 'L3_skills'): void {\n const userLayer = (userCfg[layerKey] || (userCfg[layerKey] = {})) as Record<string, Category>;\n const srcLayer = srcDefaults[layerKey] || {};\n for (const [catName, srcCat] of Object.entries(srcLayer)) {\n if (!(catName in userLayer)) {\n userLayer[catName] = srcCat;\n continue;\n }\n const userCat: Category = userLayer[catName];\n if (userCat.category_desc === undefined) userCat.category_desc = srcCat.category_desc || '';\n if (userCat.category_enabled === undefined) userCat.category_enabled = srcCat.category_enabled ?? true;\n const userSkills = (userCat.skills || (userCat.skills = []));\n const existingIds = new Set(userSkills.map(s => s.id));\n for (const srcS of (srcCat.skills || [])) {\n if (!existingIds.has(srcS.id)) userSkills.push({ ...srcS });\n }\n }\n}\n\n/** 合并用户配置与源码默认值。保留用户开关;新增 builtin 补入;源码删除的标记。 */\nexport function mergeConfig(userCfg: Partial<RuntimeConfig>, srcDefaults: RuntimeConfig): RuntimeConfig {\n const cfg = userCfg as RuntimeConfig;\n if (cfg.version === undefined) cfg.version = srcDefaults.version || 1;\n if (!cfg.layers) cfg.layers = {} as RuntimeConfig['layers'];\n for (const [layerKey, defaultVal] of Object.entries(srcDefaults.layers)) {\n if (!(layerKey in cfg.layers)) (cfg.layers as any)[layerKey] = defaultVal;\n }\n _mergeRuleCategories(cfg, srcDefaults, 'L1_rules');\n _mergeRuleCategories(cfg, srcDefaults, 'L2_rules');\n _mergeSkillCategories(cfg, srcDefaults, 'L3_skills');\n return cfg;\n}\n\n// ==================== Query 补齐 ====================\n\nexport function getEnabledL1InjectionKeywords(runtime: RuntimeConfig): { keyword: string; risk_level: string; lang: string }[] {\n const cat = runtime.L1_rules?.injection_detection || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => ({\n keyword: r.keyword || '', risk_level: r.risk_level || '', lang: r.lang || 'en',\n }));\n}\n\nexport function getEnabledL2IntentPatterns(runtime: RuntimeConfig): { intent_keywords: string[]; dangerous_actions: string[]; reason: string }[] {\n const cat = runtime.L2_rules?.intent_consistency || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => ({\n intent_keywords: r.intent_keywords || [], dangerous_actions: r.dangerous_actions || [], reason: r.reason || '',\n }));\n}\n\nexport function getEnabledL2PasswordPatterns(runtime: RuntimeConfig): string[] {\n const cat = runtime.L2_rules?.password_modify_consent || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => r.pattern || '');\n}\n\nexport function getEnabledL2UserDeletionPatterns(runtime: RuntimeConfig): string[] {\n const cat = runtime.L2_rules?.user_deletion_consent || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => r.pattern || '');\n}\n\nexport function isL2CategoryEnabled(runtime: RuntimeConfig, categoryKey: string): boolean {\n const cat = runtime.L2_rules?.[categoryKey as keyof typeof runtime.L2_rules] as Category | undefined;\n return cat?.category_enabled ?? true;\n}\n\n/** 所有被禁用的 skill id(整分类禁用→该分类所有 skill,或单条 enabled=false) */\nexport function getDisabledSkillIds(runtime: RuntimeConfig): Set<string> {\n const disabled = new Set<string>();\n for (const catData of Object.values(runtime.L3_skills || {})) {\n if (!catData.category_enabled) {\n for (const s of (catData.skills || [])) disabled.add(s.id);\n } else {\n for (const s of (catData.skills || [])) {\n if (s.enabled === false) disabled.add(s.id);\n }\n }\n }\n return disabled;\n}\n\n// ==================== _or_default 回退系列 ====================\n// runtime 规则非空→用 runtime;为空且文件不存在→回退 source defaults;\n// 为空但文件存在(用户主动禁用)→返回空。与 py 语义对齐。\n\nexport function getEnabledL1CommandPatternsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL1CommandPatterns(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l1CommandPatternsToRules();\n return [];\n}\nexport function getEnabledL1InjectionKeywordsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL1InjectionKeywords(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l1InjectionKeywordsToRules();\n return [];\n}\nexport function getEnabledL2SensitivePathsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL2SensitivePaths(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l2SensitivePathsToRules();\n return [];\n}\nexport function getEnabledL2IntentPatternsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL2IntentPatterns(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l2IntentPatternsToRules();\n return [];\n}\nexport function getEnabledL2PasswordPatternsOrDefault(runtime: RuntimeConfig): string[] {\n const enabled = getEnabledL2PasswordPatterns(runtime);\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) {\n return PASSWORD_MODIFY_PATTERNS.map((p) => p.source);\n }\n return [];\n}\nexport function getEnabledL2UserDeletionPatternsOrDefault(runtime: RuntimeConfig): string[] {\n const enabled = getEnabledL2UserDeletionPatterns(runtime);\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) {\n return USER_DELETION_PATTERNS.map((p) => p.source);\n }\n return [];\n}\n\n// ==================== CRUD / update ====================\n\nconst SKILL_ID_RE = /^[A-Za-z0-9_-]+$/;\nfunction _validateSkillId(skillId: string): void {\n if (!skillId || !SKILL_ID_RE.test(skillId)) {\n throw new Error(`skill_id '${skillId}' 不合法:只允许字母、数字、下划线和连字符`);\n }\n}\n\nexport function updateLayerEnabled(layerKey: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n (runtime.layers as any)[layerKey] = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateRuleEnabled(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const r of (runtime[layer]?.[category]?.rules || [])) {\n if (r.id === ruleId) { r.enabled = enabled; break; }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateRuleDenyMode(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string, denyMode: string): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const r of (runtime[layer]?.[category]?.rules || [])) {\n if (r.id === ruleId) { r.deny_mode = denyMode; _syncDenyModeFields(r); break; }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateRuleSkipL3(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string, skipL3: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const r of (runtime[layer]?.[category]?.rules || [])) {\n if (r.id === ruleId) { r.skip_l3_on_disabled = skipL3; break; }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateCategoryEnabled(layer: 'L1_rules' | 'L2_rules', category: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime[layer]?.[category];\n if (cat) cat.category_enabled = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function addCustomRule(layer: 'L1_rules' | 'L2_rules', category: string, rule: Partial<Rule>): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const layerObj = runtime[layer] || (runtime[layer] = {} as Record<string, Category>);\n const cat = layerObj[category] || (layerObj[category] = { category_enabled: true, category_desc: '', rules: [] });\n const rules = cat.rules || (cat.rules = []);\n const newRule: Rule = { ...rule, builtin: false, enabled: true } as Rule;\n if (!newRule.id) {\n newRule.id = `custom_${Date.now()}_${_slugify(JSON.stringify(rule).slice(0, 30))}`;\n }\n if (newRule.deny_mode) _syncDenyModeFields(newRule);\n rules.push(newRule);\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function deleteCustomRule(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string): RuntimeConfig | null {\n const runtime = loadRuntimeConfig();\n const rules = runtime[layer]?.[category]?.rules || [];\n const idx = rules.findIndex(r => r.id === ruleId);\n if (idx >= 0) {\n if (rules[idx].builtin) return null; // builtin 不允许删\n rules.splice(idx, 1);\n saveRuntimeConfig(runtime);\n }\n return runtime;\n}\n\nexport function addCustomSkill(skillId: string, category: string, keywords: string[], content: string): RuntimeConfig {\n _validateSkillId(skillId);\n const runtime = loadRuntimeConfig();\n const skillsDir = join(RUNTIME_CONFIG_DIR, 'agent_moss_skills');\n try { mkdirSync(skillsDir, { recursive: true }); } catch { /* 已存在 */ }\n writeFileSync(join(skillsDir, `${skillId}.md`), content, 'utf-8');\n const l3 = runtime.L3_skills || (runtime.L3_skills = {});\n const cat = l3[category] || (l3[category] = { category_enabled: true, category_desc: '', skills: [] });\n (cat.skills || (cat.skills = [])).push({ id: skillId, keywords, enabled: true, builtin: false });\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function deleteCustomSkill(skillId: string, category: string): RuntimeConfig | null {\n _validateSkillId(skillId);\n const runtime = loadRuntimeConfig();\n const skills = runtime.L3_skills?.[category]?.skills || [];\n const idx = skills.findIndex(s => s.id === skillId);\n if (idx >= 0) {\n if (skills[idx].builtin) return null;\n skills.splice(idx, 1);\n const skillPath = join(RUNTIME_CONFIG_DIR, 'agent_moss_skills', `${skillId}.md`);\n try { if (existsSync(skillPath)) unlinkSync(skillPath); } catch { /* ignore */ }\n saveRuntimeConfig(runtime);\n }\n return runtime;\n}\n\nexport function updateSkillEnabled(skillId: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const catData of Object.values(runtime.L3_skills || {})) {\n for (const s of (catData.skills || [])) {\n if (s.id === skillId) { s.enabled = enabled; break; }\n }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateSkillCategoryEnabled(category: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.L3_skills?.[category];\n if (cat) cat.category_enabled = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function getProfileOrDetect(): null {\n // TS 不走 OSProfile(规则集硬编码常量),此函数仅为 py API 对齐保留,返回 null。\n return null;\n}\n","import { SecurityJudgment } from './types';\nimport { runHeuristicCheck, isInlineScriptCommand, DANGEROUS_PATTERNS } from './heuristic';\nimport { runLogicCheck } from './logic-rules';\nimport { analyzeInlineScript, isLiteralTextCommand } from './inline-analyzer';\nimport { runLLMAnalysis } from './llm-analyzer';\nimport { analyzeScriptContent as analyzeScriptChain, formatScriptChainForPrompt } from './script-content-analyzer';\nimport { isHeuristicEnabled, isLogicRulesEnabled, isLLMAvailable } from '../config';\nimport { getAgentExtensions } from '../agents';\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 /** 调用方 agent 标识(如 'xiaoo' / 'opencode' / 'opendesk')。空 = 通用模式。 */\n agentId: string;\n /** 可选的 per-request LLM 配置覆盖(由 OpenDesk 按当前会话模型传入) */\n llmConfig?: { baseUrl: string; apiKey: string; model: string; provider?: string };\n /** 可选的 per-request LLM prompt 日志路径(来自调用方 env,per-request 注入。\n * 跟 llmConfig 同理:调用方子进程有 AGENT_MOSS_LOG_PATH env 但服务进程不一定有,\n * 通过 metadata 注入让服务端写 [LLM_PROMPT] 日志,对齐 py _log_prompt) */\n llmLogPath?: 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 白名单(通用 baseline,agent_ext.builtin_safe_skills 会追加)。\n * 测试可 import 此常量直接断言\"无 agentId 时白名单不含某 skill\",避免走 L3\n * LLM 调用导致测试脆弱(依赖 LLM 401 fail_open 兜底)。 */\nexport const TRUSTED_SKILLS_BASE = new Set<string>([]);\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 假阳性防护:不立即拦截,交 inline_analyzer 静态判定\n // 因为字符串字面量中的敏感路径(如 '/etc/shadow')不应被正则误拦截\n const isInlineScriptCmd = isInlineScriptCommand(input.aNext.actionDetail.toLowerCase());\n const isLiteralTextCmd = isLiteralTextCommand(input.aNext.actionDetail.toLowerCase());\n if (heuristicResult && !heuristicResult.allowed) {\n const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && heuristicResult.riskType === 'file_access';\n if (!skipInlineFileAccess) {\n return heuristicResult;\n }\n }\n\n // ===== L1.5: Script content pre-scan (recursive chain + L1 reuse) =====\n // For bash actions invoking a script, recursively track the call chain,\n // preprocess, and scan each node with runHeuristicCheck (L1). high/critical\n // deny directly (layer \"1.1-script\"). Catches \"rm -rf /\" inside a script\n // whose entry command is just \"bash deploy.sh\". Reduces L3 token use.\n let scriptChain: ReturnType<typeof analyzeScriptChain> | null = null;\n if (input.aNext.actionType.toLowerCase() === 'bash') {\n scriptChain = analyzeScriptChain(input);\n if (scriptChain.nodes.length > 0) {\n for (const node of scriptChain.nodes) {\n if (node.l1Hit && (node.l1RiskLevel === 'high' || node.l1RiskLevel === 'critical')) {\n return {\n allowed: false,\n reason: `脚本内容包含危险操作: ${node.l1Reason} (文件: ${node.scriptPath}, 深度: ${node.depth})`,\n riskLevel: node.l1RiskLevel as SecurityJudgment['riskLevel'],\n riskType: node.l1RiskType,\n confidence: 90,\n source: 'heuristic_script_scan',\n violatedLayers: ['1.1-script'],\n };\n }\n }\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 直接放行(通用 baseline + agent_ext.builtin_safe_skills)\n const agentExt = getAgentExtensions(input.agentId);\n const trustedSkills = new Set<string>(TRUSTED_SKILLS_BASE);\n if (agentExt?.builtin_safe_skills) {\n for (const s of agentExt.builtin_safe_skills) trustedSkills.add(s);\n }\n if (actionType === 'skill' && trustedSkills.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 // 凭据文件:无论读写、无论是否 inline,都直接拒绝(isCredential 来自 profile 标记)\n const isCredentialPath = !!logicResult.isCredential;\n // 内联脚本/文本输出命令:走静态语义判定,区分\"文本字面量\"vs\"真实读写\"。\n // 即使是凭据路径(如 deny_both 的 /etc/shadow),只要它是字符串字面量\n // (python -c \"print('/etc/shadow')\"),inline_analyzer 判 Allow 时应放行——\n // 因为并未真实读取该文件。actionable=false(提取不到代码)时才回退到\n // 凭据/敏感路径的硬拒绝。\n const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && logicResult.riskType === 'sensitive_path_access';\n if (skipInlineFileAccess) {\n const inlineJudgment = analyzeInlineScript(input.aNext.actionDetail);\n if (inlineJudgment.actionable) {\n if (!inlineJudgment.allowed) {\n return {\n allowed: false,\n reason: inlineJudgment.reason,\n riskLevel: inlineJudgment.riskLevel as SecurityJudgment['riskLevel'],\n riskType: inlineJudgment.riskType,\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['1.2'],\n };\n }\n // 字面量 → Allow,不再走 Layer 3\n return {\n allowed: true,\n reason: inlineJudgment.reason,\n riskLevel: inlineJudgment.riskLevel as SecurityJudgment['riskLevel'],\n riskType: inlineJudgment.riskType,\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: [],\n };\n }\n // actionable=false(提取不到代码)→ 回退原逻辑:high/critical 直接 Deny\n }\n if ((logicResult.riskLevel === 'high' || logicResult.riskLevel === 'critical') && (!skipInlineFileAccess || isCredentialPath)) {\n return logicResult;\n }\n // medium/low 风险:不直接拦截,走层3 LLM 语义判断\n }\n\n // ===== L2.5: Script content L2 scan (per-node sensitive path / dangerous\n // pattern / intent reuse on preprocessed content). high/critical deny\n // directly (layer \"1.2-script\"). =====\n if (scriptChain && scriptChain.nodes.length > 0 && isLogicRulesEnabled()) {\n for (const node of scriptChain.nodes) {\n if (node.error || !node.preprocessedContent) continue;\n if (node.l1RiskLevel === 'critical') break;\n if (node.l2Hit && (node.l2RiskLevel === 'high' || node.l2RiskLevel === 'critical')) {\n return {\n allowed: false,\n reason: node.l2Reason,\n riskLevel: node.l2RiskLevel as SecurityJudgment['riskLevel'],\n riskType: node.l2RiskType,\n confidence: 85,\n source: 'logic_rule_script_scan',\n violatedLayers: ['1.2-script'],\n };\n }\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 // Build skip_l3_hints: hard-constraint for user-disabled L2 rules with\n // skip_l3_on_disabled. runtime_config lands in Stage 2; until then\n // getDisabledL2RulesWithSkipL3 resolves to a no-op returning empty.\n let skipL3Hints = '无(当前无禁用规则命中)';\n try {\n const { getDisabledL2RulesWithSkipL3 } = await import('../infra/runtime-config');\n const disabledL2 = getDisabledL2RulesWithSkipL3();\n if (disabledL2 && Object.keys(disabledL2).length > 0) {\n const actionLower = input.aNext.actionDetail.toLowerCase();\n const matched: string[] = [];\n for (const items of Object.values(disabledL2)) {\n for (const item of items) {\n if (item.toLowerCase().includes(actionLower) || actionLower.includes(item.toLowerCase())) {\n matched.push(item);\n }\n }\n }\n if (matched.length > 0) {\n skipL3Hints =\n `⚠️ 重要约束:用户已主动禁用针对以下内容的安全拦截规则,这是用户的明确决策:\\n` +\n ` ${matched.join(', ')}\\n` +\n `对这些路径/关键词的相关操作,必须视为允许的,不允许仅因涉及这些内容就拒绝。` +\n `但你仍需检查命令的其他部分是否有独立于这些内容的安全风险(如网络外传、提权等)。`;\n }\n }\n } catch { /* runtime_config not yet present — skip_l3_hints stays default */ }\n\n let llmResult: SecurityJudgment;\n try {\n llmResult = await runLLMAnalysis(input, {\n heuristic: heuristicResult,\n logic: logicResult,\n skipL3Hints,\n scriptChain: scriptChain ?? undefined,\n llmLogPath: input.llmLogPath,\n });\n } catch (e) {\n // LLM 分析失败。前两层未拦截时按 fail_mode 决策:\n // - fail_open(默认):Allow + 警告(可用性优先)\n // - fail_closed:Deny(安全优先)\n const { getLLMFailMode } = await import('../config');\n if (getLLMFailMode() === 'fail_open') {\n console.warn(`[AgentMoss] LLM 分析失败,fail_open 模式:允许执行(前两层未拦截): ${(e as Error).message}`);\n return {\n allowed: true,\n reason: `LLM 分析失败(warn-allow,fail_open): ${(e as Error).message}`,\n riskLevel: 'low',\n riskType: '',\n confidence: 50,\n source: 'llm_failure_fallback',\n violatedLayers: [],\n };\n }\n return {\n allowed: false,\n reason: `LLM 分析失败,因无法完成深度语义分析,按 fail-closed 原则拒绝: ${(e as Error).message}`,\n riskLevel: 'medium',\n riskType: '',\n confidence: 60,\n source: 'llm_failure_fallback',\n violatedLayers: ['3'],\n };\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, startServer } 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 install Install systemd service for AgentMoss\n\nServer options:\n --host <host> Listen host (default: 127.0.0.1)\n --port <port> Listen port (default: 9090, 0=auto assign)\n\nInstall options:\n --enable Enable service on boot (systemctl enable)\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 agentId: data.agent_id || '',\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 // startServer 内部 findFreePort:port 被占自动找空闲端口。\n const server = await startServer(host, port);\n console.log(`Listening on http://${host}:${server.port}`);\n server.serve();\n break;\n }\n\n case 'install': {\n const enable = args.includes('--enable');\n const { execSync } = await import('child_process');\n const fs = await import('fs');\n const path = await import('path');\n const { fileURLToPath } = await import('url');\n\n // 检查 root 权限\n if (process.getuid?.() !== 0) {\n const sudoArgs = ['sudo', process.execPath, ...process.argv.slice(1)];\n if (enable) sudoArgs.push('--enable');\n console.log('需要 root 权限安装 systemd service,正在通过 sudo 重新执行...');\n execSync(sudoArgs.join(' '), { stdio: 'inherit' });\n process.exit(0);\n }\n\n // 找到 service 文件(dist/data/ 或 src/data/)\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n let srcPath = path.join(__dirname, 'data', 'agent_moss.service');\n if (!fs.existsSync(srcPath)) {\n // 开发模式回退\n srcPath = path.join(__dirname, '..', 'src', 'data', 'agent_moss.service');\n }\n if (!fs.existsSync(srcPath)) {\n console.error('错误:找不到 agent_moss.service 模板文件');\n process.exit(1);\n }\n\n // 找到 agent-moss 命令路径\n const which = execSync('which agent-moss 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n const binPath = which || `${process.execPath} ${path.join(__dirname, 'cli.js')}`;\n\n // 读取模板,替换 ExecStart\n let content = fs.readFileSync(srcPath, 'utf-8');\n content = content.replace('__AGENT_MOSS_BIN__', binPath);\n\n // 写入 /etc/systemd/system/\n const dst = '/etc/systemd/system/agent_moss.service';\n fs.writeFileSync(dst, content, 'utf-8');\n fs.chmodSync(dst, 0o644);\n console.log(`✅ 已安装 systemd service: ${dst}`);\n\n // daemon-reload\n execSync('systemctl daemon-reload', { stdio: 'inherit' });\n console.log('✅ systemctl daemon-reload 完成');\n\n // 可选 enable\n if (enable) {\n execSync('systemctl enable agent_moss', { stdio: 'inherit' });\n console.log('✅ systemctl enable agent_moss 完成');\n }\n\n console.log('\\n启动服务: sudo systemctl start agent_moss');\n console.log('查看状态: sudo systemctl status agent_moss');\n console.log('查看日志: journalctl -u agent_moss -f');\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 net from 'node:net';\nimport { analyzeRoute, healthRoute } from './routes';\nimport { createConsoleRouter } from './console';\n\nexport function createApp(): Hono {\n const app = new Hono();\n\n // Middleware\n app.use('*', cors({ origin: '*', allowMethods: ['GET', 'POST', 'PUT', 'DELETE', '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 // Policy Console(浏览器策略管控台,挂载在 /console 前缀)\n app.route('/console', createConsoleRouter());\n // /console/ → /console(hono route 挂载后带尾斜杠匹配行为不一致,加重定向兼容)\n app.get('/console/', (c) => c.redirect('/console'));\n\n return app;\n}\n\n/**\n * 从 startPort 开始找第一个可用端口(照搬 OpenDesk findFreePort 策略)。\n * 用 net.createServer().listen 试端口,成功立刻 close 返回该端口;全占 fallback\n * 到 startPort(让 hono 自己报错,不静默换到离谱端口)。\n *\n * 为什么需要:默认 9090 被占时服务起不来、xiaoO 全 fail-closed。预探测找空闲端口,\n * 配合消费方探测兜底(bridge.ts probeAgentMossUrl),保证服务总能起、消费方能连上。\n */\nexport async function findFreePort(\n startPort: number,\n host: string = '127.0.0.1',\n scan: number = 100,\n): Promise<number> {\n for (let port = startPort; port < startPort + scan; port++) {\n const free = await new Promise<boolean>((resolve) => {\n const server = net.createServer();\n server.listen(port, host, () => {\n server.close(() => resolve(true));\n });\n server.on('error', () => resolve(false));\n });\n if (free) {\n if (port !== startPort) {\n console.warn(`[AgentMoss] Port ${startPort} in use, using ${port} instead`);\n }\n return port;\n }\n }\n return startPort; // fallback\n}\n\nexport async function startServer(\n host = '127.0.0.1',\n port = 9090,\n): Promise<{ serve: () => void; port: number }> {\n const actualPort = await findFreePort(port, host);\n const app = createApp();\n return {\n port: actualPort,\n serve: () => {\n console.log(`AgentMoss HTTP server on ${host}:${actualPort}`);\n // @hono/node-server 动态 import(ESM 下 require 不可用)\n import('@hono/node-server').then(({ serve: honoServe }) => {\n honoServe({ fetch: app.fetch, hostname: host, port: actualPort });\n });\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 agentId: req.agent_id,\n llmConfig: (req.metadata as any)?.llm_config,\n llmLogPath: (req.metadata as any)?.llm_log_path,\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 agent_id: z.string().default('').describe(\"Caller agent identifier, e.g. 'xiaoo' / 'opencode' / 'opendesk'. Empty = generic mode (no agent-specific rules).\"),\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","/** Policy Console 子应用(挂载到主 app 的 /console 前缀)。 */\nexport { createConsoleRouter } from './router';\n","/**\n * Policy Console Hono 路由 — 挂载到主 app 的 /console 前缀下。\n * 1:1 对齐 Python console/router.py 的 23 路由契约(前端 SPA 共用)。\n *\n * 复用 infra.runtime-config + engine.token-stats。Bearer 认证\n * (AGENT_MOSS_CONSOLE_TOKEN 未设则本机免认证,iframe 嵌入场景)。\n */\nimport { Hono } from 'hono';\nimport { readFileSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport {\n loadRuntimeConfig, saveRuntimeConfig, updateLayerEnabled,\n updateRuleEnabled, updateRuleDenyMode, updateRuleSkipL3,\n updateCategoryEnabled, addCustomRule, deleteCustomRule,\n addCustomSkill, deleteCustomSkill, updateSkillEnabled,\n updateSkillCategoryEnabled, getEnvOverrides, generateSourceDefaults,\n getRuntimeConfigPath,\n} from '../infra/runtime-config';\nimport {\n getTokenStats, getRecentRecords, getTokenTrend, resetTokenStats,\n} from '../engine/token-stats';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst STATIC_DIR = join(__dirname, 'static');\n\nconst CONSOLE_TOKEN_ENV = 'AGENT_MOSS_CONSOLE_TOKEN';\n\nfunction getConsoleToken(): string {\n return process.env[CONSOLE_TOKEN_ENV] || '';\n}\n\n/** 验证 Bearer token。未配置 token 时本机访问免认证(iframe 嵌入场景)。 */\nfunction verifyAuth(req: Request): boolean {\n const token = getConsoleToken();\n if (!token) return true;\n const auth = req.headers.get('Authorization') || '';\n if (auth.startsWith('Bearer ')) return auth.slice(7) === token;\n return false;\n}\n\n/** 鉴权中间件:失败返 401。 */\nfunction authMiddleware() {\n return async (c: any, next: any) => {\n if (!verifyAuth(c.req.raw)) {\n return c.json({ error: 'Unauthorized: invalid or missing Bearer token' }, 401);\n }\n await next();\n };\n}\n\nexport function createConsoleRouter(): Hono {\n const console = new Hono();\n console.use('/api/*', authMiddleware());\n\n // ==================== SPA ====================\n // /console 和 /console/ 都返回 SPA(hono route 挂载后两者匹配行为不同,都兜住)\n const serveIndex = (c: any) => {\n const indexFile = join(STATIC_DIR, 'index.html');\n if (existsSync(indexFile)) {\n return c.html(readFileSync(indexFile, 'utf-8'));\n }\n return c.html('<h1>AgentMoss Policy Console</h1><p>Frontend not built. Use /console/api/* endpoints.</p>');\n };\n console.get('/', serveIndex);\n console.get('', serveIndex);\n\n // ==================== 层级管理 ====================\n console.get('/api/layers', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ layers: rc.layers });\n });\n\n console.put('/api/layers', async (c) => {\n const body = await c.req.json();\n const rc = updateLayerEnabled(body.layer_key, body.enabled);\n return c.json({ layers: rc.layers });\n });\n\n // ==================== 规则管理 ====================\n console.get('/api/rules', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/rules/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateRuleEnabled(b.layer, b.category, b.rule_id, b.enabled);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/rules/deny_mode', async (c) => {\n const b = await c.req.json();\n const rc = updateRuleDenyMode(b.layer, b.category, b.rule_id, b.deny_mode);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/rules/skip_l3', async (c) => {\n const b = await c.req.json();\n const rc = updateRuleSkipL3(b.layer, b.category, b.rule_id, b.skip_l3_on_disabled);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/categories/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateCategoryEnabled(b.layer, b.category, b.enabled);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.post('/api/rules', async (c) => {\n const b = await c.req.json();\n const rc = addCustomRule(b.layer, b.category, {\n pattern: b.pattern, risk_level: b.risk_level, risk_type: b.risk_type,\n reason: b.reason, keyword: b.keyword, lang: b.lang,\n path: b.path, desc: b.desc, credential: b.credential, deny_mode: b.deny_mode,\n });\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.delete('/api/rules', async (c) => {\n const b = await c.req.json();\n deleteCustomRule(b.layer, b.category, b.rule_id);\n const rc = loadRuntimeConfig();\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n // ==================== Skill 管理 ====================\n console.get('/api/skills', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.put('/api/skills/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateSkillEnabled(b.skill_id, b.enabled);\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.put('/api/skill-categories/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateSkillCategoryEnabled(b.category, b.enabled);\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.post('/api/skills', async (c) => {\n const b = await c.req.json();\n const rc = addCustomSkill(b.skill_id, b.category || 'user_custom', b.keywords || [], b.content);\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.delete('/api/skills', async (c) => {\n const b = await c.req.json();\n deleteCustomSkill(b.skill_id, b.category);\n const rc = loadRuntimeConfig();\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.get('/api/skills/:skill_id/content', async (c) => {\n const skillId = c.req.param('skill_id');\n if (!/^[A-Za-z0-9_-]+$/.test(skillId)) {\n return c.json({ error: 'invalid skill_id' }, 400);\n }\n const skillPath = join(dirname(getRuntimeConfigPath()), 'agent_moss_skills', `${skillId}.md`);\n if (!existsSync(skillPath)) {\n // fallback 到 builtin skill 目录\n const builtinPath = join(__dirname, '..', '..', 'agent_moss', 'skills', `${skillId}.md`);\n if (existsSync(builtinPath)) return c.text(readFileSync(builtinPath, 'utf-8'));\n return c.json({ error: 'skill not found' }, 404);\n }\n return c.text(readFileSync(skillPath, 'utf-8'));\n });\n\n // ==================== 配置 / env / reset ====================\n console.get('/api/config', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ config: rc, config_path: getRuntimeConfigPath() });\n });\n\n console.get('/api/env-overrides', (c) => {\n return c.json({ overrides: getEnvOverrides() });\n });\n\n console.post('/api/reset', (c) => {\n const defaults = generateSourceDefaults();\n saveRuntimeConfig(defaults);\n return c.json({ config: defaults });\n });\n\n // ==================== Token stats ====================\n console.get('/api/token-stats', (c) => {\n const days = parseInt(c.req.query('days') || '7', 10);\n return c.json(getTokenStats(days));\n });\n\n console.get('/api/token-stats/recent', (c) => {\n const limit = parseInt(c.req.query('limit') || '20', 10);\n return c.json({ records: getRecentRecords(limit) });\n });\n\n console.get('/api/token-stats/trend', (c) => {\n const days = parseInt(c.req.query('days') || '7', 10);\n return c.json(getTokenTrend(days));\n });\n\n console.post('/api/token-stats/reset', (c) => {\n resetTokenStats();\n return c.json({ reset: true });\n });\n\n return console;\n}\n"],"mappings":"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","names":["path","fileURLToPath","__filename","__dirname","fs","path","READ_KEYWORDS","WRITE_KEYWORDS","readFileSync","readdirSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","readFileSync","existsSync","resolve","join","dirname","path","scanScriptForKeywords","SUSPICIOUS_PATTERNS","assessKeywordCombinationRisk","KEYWORD_COMBINATION_RISKS","SINGLE_KEYWORD_RISKS","LEVEL_ORDER","extractScriptPath","SCRIPT_EXEC_PATTERNS","readScriptContent","node","analyzeScriptContent","parts","readFileSync","existsSync","join","homedir","recordTokenUsage","resolve","readFileSync","writeFileSync","existsSync","mkdirSync","unlinkSync","join","homedir","main","analyzeScriptContent","getDisabledL2RulesWithSkipL3","getLLMFailMode","Hono","require","fs","readFileSync","existsSync","join","dirname","fileURLToPath","__dirname","console","Hono","resolve","fs","path","runAnalysis","fileURLToPath","__filename","__dirname"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/config.ts","../src/agents/index.ts","../src/engine/heuristic.ts","../src/engine/inline-analyzer.ts","../src/engine/logic-rules.ts","../src/engine/skill-loader.ts","../src/engine/template-loader.ts","../src/engine/script-analyzer.ts","../src/engine/script-content-analyzer.ts","../src/engine/token-stats.ts","../src/engine/llm-analyzer.ts","../src/infra/runtime-config.ts","../src/engine/coordinator.ts","../src/cli.ts","../src/server.ts","../src/routes.ts","../src/models.ts","../src/package-json.ts","../src/actrail.ts","../src/console/index.ts","../src/console/router.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, TimeoutConfig, RetryConfig } 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 ?? 40,\n };\n}\n\n/** Load timeout/retry config from file (对齐 Python TimeoutConfig / RetryConfig) */\nfunction loadTimeoutRetryFromFile(configPath: string): { timeout: TimeoutConfig; retry: RetryConfig } {\n const data = loadConfigFile(configPath);\n const t = data?.timeout ?? {};\n const r = data?.retry ?? {};\n return {\n timeout: {\n totalTimeout: Number(t.total_timeout ?? 90),\n prompt1Timeout: Number(t.prompt1_timeout ?? 40),\n prompt2Timeout: Number(t.prompt2_timeout ?? 20),\n stepInterval: Number(t.step_interval ?? 0),\n },\n retry: {\n maxRetries: Number(r.max_retries ?? 2),\n retryInterval: Number(r.retry_interval ?? 2),\n },\n };\n}\n\n/** Global timeout/retry configuration (对齐 Python TimeoutConfig / RetryConfig) */\nlet timeoutConfig: TimeoutConfig;\nlet retryConfig: RetryConfig;\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 const tr = loadTimeoutRetryFromFile(configPath);\n timeoutConfig = tr.timeout;\n retryConfig = tr.retry;\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 // 优先用 env,否则用 timeout 块的 prompt1Timeout(对齐 py)\n timeout: parseInt(process.env.AGENT_MOSS_LLM_TIMEOUT || String(fileConfig.timeout ?? String(tr.timeout.prompt1Timeout)), 10),\n };\n})();\n\nexport function getTimeoutConfig(): Readonly<TimeoutConfig> {\n return timeoutConfig;\n}\n\nexport function getRetryConfig(): Readonly<RetryConfig> {\n return retryConfig;\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/**\n * LLM analysis failure mode (mirrors Python get_llm_fail_mode).\n *\n * - \"fail_open\" (default): when L3 LLM fails and prior layers did NOT block,\n * Allow + warning log (availability-first)\n * - \"fail_closed\": LLM failure -> Deny (safety-first)\n *\n * Priority: env AGENT_MOSS_LLM_FAIL_MODE > default fail_open.\n */\nexport function getLLMFailMode(): 'fail_open' | 'fail_closed' {\n const val = (process.env.AGENT_MOSS_LLM_FAIL_MODE || 'fail_open').toLowerCase();\n return val === 'fail_closed' ? 'fail_closed' : 'fail_open';\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","/**\n * 三方 agent 定制化注册中心 — TypeScript 加载器\n *\n * 按 `agentId` 加载该 agent 的专属规则集(JSON 单一事实源)。\n * 规则文件位置:`agent_moss/agents/<agentId>/rules.json`\n *\n * 与 Python `agent_moss/agents/__init__.py:get_agent_extensions` 一一对应。\n * 两端共享同一份 rules.json。\n *\n * 路径解析:\n * - prod(dist/cli.js):copy-assets.cjs 复制 rules.json 到 dist/agents/<id>/rules.json\n * - dev(tsx src/cli.ts):从 ts/src/agents/ 出发,回退到 ../../../agent_moss/agents\n *\n * 缓存:首次加载后缓存在 Map 中,clearAgentExtensionsCache 清空(测试用)。\n */\n\nimport { readFileSync, existsSync } from 'fs';\nimport { resolve, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport type { AgentExtensions } from './types';\n\nexport type { AgentExtensions } from './types';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// 优先用 dist 内联目录(prod,copy-assets.cjs 复制后);\n// 缺失时回退到仓库根 agent_moss/agents(dev)。\n// 注意:从 ts/src/agents/ 出发,仓库根 agent_moss/agents 在 ../../../agent_moss/agents。\nconst AGENTS_DIR_PROD = resolve(__dirname, 'agents');\nconst AGENTS_DIR_DEV_FALLBACK = resolve(__dirname, '../../../agent_moss/agents');\n\nconst cache = new Map<string, AgentExtensions | null>();\n\nfunction resolveAgentsDir(): string {\n if (existsSync(AGENTS_DIR_PROD)) return AGENTS_DIR_PROD;\n if (existsSync(AGENTS_DIR_DEV_FALLBACK)) return AGENTS_DIR_DEV_FALLBACK;\n return AGENTS_DIR_PROD; // 不存在时也返回 prod 路径,让后续 existsSync 检查返回 false\n}\n\n/**\n * 按 agentId 加载该 agent 的专属规则集。\n *\n * @param agentId 调用方 agent 标识,如 \"xiaoo\" / \"opencode\" / \"opendesk\"。\n * 空字符串返回 null(通用模式)。\n * @returns AgentExtensions 实例,或 null(无 agent 专属规则 / rules.json 不存在 / 解析失败)\n */\nexport function getAgentExtensions(agentId: string): AgentExtensions | null {\n if (!agentId) return null;\n if (cache.has(agentId)) return cache.get(agentId) ?? null;\n\n const agentsDir = resolveAgentsDir();\n const rulesFile = resolve(agentsDir, agentId, 'rules.json');\n\n if (!existsSync(rulesFile)) {\n cache.set(agentId, null);\n return null;\n }\n\n try {\n const raw = readFileSync(rulesFile, 'utf-8');\n const ext = JSON.parse(raw) as AgentExtensions;\n if (!ext.agent_id) {\n console.warn(`[AgentMoss agents] rules.json 缺少 agent_id 字段: ${rulesFile}`);\n cache.set(agentId, null);\n return null;\n }\n cache.set(agentId, ext);\n console.log(\n `[AgentMoss agents] 加载 agent ${agentId} 定制规则: ` +\n `${ext.extra_command_patterns?.length ?? 0} cmd patterns, ` +\n `${ext.extra_injection_keywords?.length ?? 0} injection keywords, ` +\n `${ext.extra_sensitive_paths?.length ?? 0} sensitive paths, ` +\n `${ext.builtin_safe_skills?.length ?? 0} builtin safe skills`\n );\n return ext;\n } catch (e) {\n console.error(`[AgentMoss agents] 加载 agent ${agentId} rules.json 失败:`, (e as Error).message);\n cache.set(agentId, null);\n return null;\n }\n}\n\n/**\n * 清空 agent 扩展缓存(用于测试或 rules.json 热加载)。\n */\nexport function clearAgentExtensionsCache(): void {\n cache.clear();\n}\n","import { SecurityJudgment, HeuristicResult } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getCustomRules } from '../config';\nimport { getAgentExtensions } from '../agents';\nimport type { CommandPattern, InjectionKeyword } from '../agents/types';\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)\nexport const 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 专属绕过词(绕过审计/禁用安全检查/关闭防护/bypass audit 等)\n // 已迁至 agent_moss/agents/xiaoo/rules.json 的 extra_injection_keywords,\n // 由 agent_ext 机制注入,不再污染通用层。\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 agent-specific extra command patterns (追加在通用规则之后)\n const agentExt = getAgentExtensions(input.agentId);\n if (agentExt?.extra_command_patterns) {\n for (const rule of agentExt.extra_command_patterns) {\n try {\n const re = new RegExp(rule.pattern, 'i');\n if (re.test(command)) {\n matched.push(`agent 专属规则: ${rule.reason}`);\n if (severityRank(rule.risk_level) > severityRank(highestSeverity)) {\n highestSeverity = rule.risk_level;\n highestRiskType = rule.risk_type;\n }\n }\n } catch { /* invalid regex, skip */ }\n }\n }\n\n // Check prompt injection keywords (通用 + agent_ext.extra_injection_keywords)\n const injectionText = `${input.aNext.actionType} ${input.aNext.actionDetail} ${input.reason || ''} ${input.promptSession || ''}`.toLowerCase();\n const injectionHits = checkInjectionKeywords(injectionText, agentExt?.extra_injection_keywords);\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.1'], // 对齐 py coordinator.py:165(L1.1 = 命中高危命令模式/注入关键词)\n };\n }\n\n return null; // No match, pass to next layer\n}\n\nfunction checkInjectionKeywords(\n text: string,\n extraKeywords?: InjectionKeyword[],\n): { 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 // agent 专属注入关键词(追加在后)\n if (extraKeywords) {\n for (const entry of extraKeywords) {\n if (text.includes(entry.keyword.toLowerCase())) {\n hits.push({ keyword: entry.keyword, riskLevel: entry.risk_level, lang: entry.lang });\n }\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","/**\n * 内联脚本静态语义判定 — 区分敏感路径是\"被当作文本\"还是\"被当作读写目标\"。\n *\n * 对内联脚本(python -c / perl -e / ruby -e / php -r / node -e / lua / echo / printf)\n * 里出现非凭据敏感路径的场景,做静态判定(不依赖 LLM):\n *\n * 1. 写入+执行绕过链 → Deny(echo \"cat /etc/shadow\" > x.sh && bash x.sh / printf | bash)\n * 2. 重定向写入敏感路径 → Deny(echo '...' >> /etc/hosts)\n * 3. 含读写调用词 + 敏感路径共存 → Deny(open('/etc/shadow')、os.system('cat /etc/shadow'))\n * 注意:仅对 python -c 等真正的内联脚本代码做读写调用词检测;\n * echo/printf 的字符串参数是自然语言文本,跳过此检测(不可能触发真实读写)。\n * 4. 否则(敏感路径在代码里但无读写调用词,如 print('/etc/shadow')) → Allow\n * 5. 目录遍历 + 文件读写组合 → Deny(os.listdir + open() 动态发现并读写文件,绕过静态路径检测)\n * 注意:仅对 python -c 等真正的内联脚本代码做此检测。\n * 6. 否则(无目录遍历读写组合) → Allow\n *\n * 凭据文件不进此判定(coordinator 层 isCredential 直接 Deny)。\n */\n\nexport interface InlineAnalysisResult {\n /** 是否命中本判定器可处理的内联脚本场景;false 时回退原逻辑 */\n actionable: boolean;\n allowed: boolean;\n reason: string;\n riskLevel: 'low' | 'medium' | 'high' | 'critical';\n riskType: string;\n}\n\n// 内联脚本解释器 + 代码标志:python -c / perl -e / ruby -e / php -r / node -e / lua -e\n// 捕获 -c/-e/-r 后的代码内容(双引号组 1 / 单引号组 2,支持转义)\nconst INLINE_CODE_RE = /(?:python|python3|perl|perl5|ruby|jruby|mruby|node|php|lua)\\s+(?:-[a-zA-Z]*[cera][a-zA-Z]*\\s+)\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/gi;\n\n// echo / printf 的字符串参数(双引号组 1 / 单引号组 2)\nconst ECHO_STRING_RE = /\\b(?:echo|printf)\\s+\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|\\b(?:echo|printf)\\s+'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'/gi;\n\n// echo / printf 命令本身(用于 isLiteralTextCommand 门控)\nconst ECHO_CMD_RE = /(?:^|\\s|;|&&|\\|\\|)(?:echo|printf)\\s/gi;\n\n/** 判断命令是否为 echo/printf 等纯文本输出命令(敏感路径可能作为字符串字面量出现)。 */\nexport function isLiteralTextCommand(command: string): boolean {\n ECHO_CMD_RE.lastIndex = 0;\n return ECHO_CMD_RE.test(command);\n}\n\n// 读写调用词:仅用于 python -c 等真正的内联脚本代码(不对 echo/printf 的字符串生效)。\n// 出现这些词 + 敏感路径共存 → 判为真实读写。\n//\n// 全部采用组合/函数调用形态,避免自然语言误触发:\n// - 函数调用形态:open(, read(, write(, system(, exec(, eval( 等(后跟 '(')\n// - 组合关键词:os.system, import os, shell=True 等(自带足够区分度)\n// - 不再包含裸短词(open, read, system, exec 等),因 \\b 无法区分编程调用与自然语言\nconst READ_WRITE_KEYWORDS = [\n // 函数调用形态(关键词后跟 '(')\n 'open(', 'read(', 'write(', 'fopen(', 'system(', 'exec(', 'eval(',\n 'popen(', 'load(', 'dump(',\n // 文件读写(组合形态)\n 'readline', 'readlines', 'writelines', 'getpass',\n 'pickle.load', 'yaml.load', 'json.load', 'json.read', 'configparser',\n 'fread', 'fwrite', 'fgets',\n // 子进程执行(组合形态)\n 'os.system', 'os.popen', 'subprocess', 'os.exec', 'os.spawn',\n 'import os', 'import subprocess',\n 'shell=true', 'check_output', 'check_call', 'run(',\n // 绕过变体检测\n 'getattr(', '__builtins__', 'globals(', 'locals(',\n // PHP\n 'file_get_contents', 'file_put_contents', 'passthru', 'shell_exec', 'proc_open',\n // Perl-Ruby\n '<stdin>', 'open my',\n];\n\n// 写入+执行绕过链\nconst WRITE_EXEC_CHAIN_PATTERNS: RegExp[] = [\n // echo/cat/printf \"...\" > file && bash/sh/python file\n /(?:echo|cat|printf)\\b.*?>\\s*\\S+.*(?:&&|;|\\|)\\s*(?:bash|sh|zsh|python\\d?|perl|ruby|node|php)\\s/gis,\n // ... | bash / | sh / | python(管道喂解释器执行)\n /\\|\\s*(?:bash|sh|zsh|python\\d?|perl|ruby|node|php)\\b/gi,\n // eval \"$(cat ...)\" / eval \"$(echo ...)\"\n /eval\\s+\"\\$\\(/gi,\n // xargs bash / xargs sh\n /\\|\\s*xargs\\s+(?:bash|sh|zsh)/gi,\n];\n\n// 重定向写入敏感路径:> / >> 后跟敏感路径 = 真实写入(不是字符串字面量)\n// 敏感路径片段(非凭据,凭据已在 coordinator 层直接 Deny 不进此判定)\nconst SENSITIVE_PATH_FRAGMENTS = [\n '/etc/shadow', '/etc/gshadow', '/etc/passwd', '/etc/sudoers', '/etc/hosts',\n '/etc/crontab', '/etc/systemd/', '/etc/ssh/sshd_config', '/boot/', '/proc/sys/',\n '/sys/', '/dev/mem', '/dev/kmsg', '.ssh/id_rsa', '.ssh/id_ed25519',\n '.ssh/authorized_keys',\n];\nconst REDIRECT_TO_SENSITIVE_RE = new RegExp(`>{1,2}\\\\s*(${SENSITIVE_PATH_FRAGMENTS.map((p) => p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})`, 'i');\n\nexport function extractInlineCode(command: string): string {\n const parts: string[] = [];\n let m: RegExpExecArray | null;\n INLINE_CODE_RE.lastIndex = 0;\n while ((m = INLINE_CODE_RE.exec(command)) !== null) {\n const code = m[1] ?? m[2];\n if (code) parts.push(code);\n }\n ECHO_STRING_RE.lastIndex = 0;\n while ((m = ECHO_STRING_RE.exec(command)) !== null) {\n const code = m[1] ?? m[2];\n if (code) parts.push(code);\n }\n return parts.join('\\n');\n}\n\nfunction hasWriteExecChain(command: string): boolean {\n return WRITE_EXEC_CHAIN_PATTERNS.some((p) => {\n p.lastIndex = 0;\n return p.test(command);\n });\n}\n\n// 目录遍历关键词:用于检测通过动态发现文件路径绕过静态路径匹配的行为\n// 仅对 python -c 等真正的内联脚本代码生效\nconst DIR_TRAVERSAL_KEYWORDS = [\n // Python 目录遍历\n 'os.listdir', 'os.walk', 'os.scandir',\n 'glob.glob', 'glob.iglob', 'pathlib.', 'iterdir', 'rglob',\n 'scandir(', 'listdir(',\n];\n\nfunction hasDirTraversal(code: string): boolean {\n /** 检测代码中是否含目录遍历函数(用于识别动态文件发现绕过行为)。 */\n const lower = code.toLowerCase();\n return DIR_TRAVERSAL_KEYWORDS.some((kw) => lower.includes(kw));\n}\n\nexport function hasReadWriteKeyword(code: string): boolean {\n /** 检测代码中是否含读写调用词(仅用于 python -c 等真正的内联脚本代码)。\n * 全部关键词为组合/函数调用形态(open(, os.system, import os 等),\n * 不会在自然语言文本里误触发。 */\n const lower = code.toLowerCase();\n return READ_WRITE_KEYWORDS.some((kw) => lower.includes(kw));\n}\n\n/**\n * 对内联脚本做静态语义判定。\n * 调用前提:coordinator 已确认是 inline 脚本 + 命中非凭据敏感路径。\n */\nexport function analyzeInlineScript(command: string): InlineAnalysisResult {\n const code = extractInlineCode(command);\n if (!code) {\n // 提取不到代码(命令结构不匹配已知 inline 模式)→ 不处理,回退保守\n return { actionable: false, allowed: true, reason: '', riskLevel: 'low', riskType: '' };\n }\n\n // 1. 写入+执行绕过链 → Deny\n if (hasWriteExecChain(command)) {\n return {\n actionable: true,\n allowed: false,\n reason: '内联脚本含写入文件后执行的模式,疑似绕过敏感路径检测',\n riskLevel: 'critical',\n riskType: 'script_execution',\n };\n }\n\n // 1.5 重定向写入敏感路径(echo '...' >> /etc/hosts 等)→ 真实写入 → Deny\n const redirMatch = command.match(REDIRECT_TO_SENSITIVE_RE);\n if (redirMatch) {\n return {\n actionable: true,\n allowed: false,\n reason: `重定向写入敏感路径: ${redirMatch[1]}`,\n riskLevel: 'critical',\n riskType: 'file_access',\n };\n }\n\n // 1.6 目录遍历 + 文件读写组合 → 不自行判定,回退 coordinator 走层3 LLM 分析\n // 检测 os.listdir/glob/pathlib 等目录遍历函数 + open()/write()/read() 等读写调用,\n // 用于识别\"通过动态发现文件路径绕过静态路径匹配\"的行为。\n // 仅对 python -c 等真正的内联脚本代码做此检测(echo/printf 无此能力)。\n // 注意:此处返回 actionable: false,让 coordinator 回退到正常逻辑,\n // 由层2 的 _checkIndirectFileAccess 规则触发层3 LLM 语义判断。\n const isEchoOrPrintf1 = isLiteralTextCommand(command);\n if (!isEchoOrPrintf1 && hasDirTraversal(code) && hasReadWriteKeyword(code)) {\n return { actionable: false, allowed: true, reason: '', riskLevel: 'low', riskType: '' };\n }\n\n // 2. 含读写调用词 → 判为真实读写 → Deny\n // 注意:仅对 python -c 等真正的内联脚本代码做此检测。\n // echo/printf 的字符串参数是自然语言文本,不可能触发真实文件读写;\n // 重定向(>> /etc/hosts)和管道执行(| bash)已在步骤 1/1.5 覆盖。\n const isEchoOrPrintf = isLiteralTextCommand(command);\n if (!isEchoOrPrintf && hasReadWriteKeyword(code)) {\n return {\n actionable: true,\n allowed: false,\n reason: '内联脚本含敏感路径且含文件读写/命令执行调用,判为真实访问',\n riskLevel: 'critical',\n riskType: 'file_access',\n };\n }\n\n // 3. 敏感路径在代码里但无读写调用词 → 文本字面量 → Allow\n return {\n actionable: true,\n allowed: true,\n reason: '敏感路径仅作为文本字面量出现,未伴随读写操作',\n riskLevel: 'low',\n riskType: 'file_access',\n };\n}\n","import * as fs from 'fs';\nimport { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { extractInlineCode } from './inline-analyzer.js';\nimport { getAgentExtensions } from '../agents';\nimport type { AgentExtensions } from '../agents';\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)\nexport const ROOT_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string; credential?: boolean }[] = [\n { path: '/etc/shadow', riskLevel: 'critical', desc: '系统密码文件', credential: true },\n { path: '/etc/gshadow', riskLevel: 'critical', desc: '系统组密码文件', credential: true },\n // 注意:/etc/passwd 仅从 L1 启发式规则移除(公开可读),L2 敏感路径仍保留\n { path: '/etc/passwd', riskLevel: 'high', desc: '系统用户文件' },\n { path: '/etc/sudoers', riskLevel: 'critical', desc: 'sudo 配置', credential: true },\n // 系统配置(仅拦截写入)\n { path: '/etc/hosts', riskLevel: 'medium', desc: 'DNS 解析配置' },\n { path: '/etc/crontab', riskLevel: 'high', desc: '系统定时任务' },\n { path: '/etc/cron.d/', riskLevel: 'high', desc: '系统定时任务目录(拆分式 crontab)' },\n { path: '/var/spool/cron/', riskLevel: 'high', desc: '用户级定时任务目录' },\n { path: '/etc/systemd/', riskLevel: 'high', desc: 'systemd 服务配置' },\n { path: '/etc/ssh/sshd_config', riskLevel: 'high', desc: 'SSH 服务配置' },\n { path: '/etc/pam.d/', riskLevel: 'high', desc: 'PAM 可插拔认证模块配置' },\n // 危险目录(仅拦截写入)\n { path: '/boot/', riskLevel: 'critical', desc: '启动引导目录' },\n { path: '/proc/sys/', riskLevel: 'high', desc: '内核参数' },\n { path: '/sys/', riskLevel: 'high', desc: 'sysfs 内核接口' },\n // 设备文件(/dev/null、/dev/zero、/dev/urandom 已移除,误报率极高)\n { path: '/dev/random', riskLevel: 'high', desc: '阻塞式随机数设备(读取耗尽熵池)' },\n { path: '/dev/mem', riskLevel: 'critical', desc: '物理内存访问设备' },\n { path: '/dev/kmsg', riskLevel: 'high', desc: '内核消息缓冲区' },\n // SSH 主机私钥\n { path: '/etc/ssh/ssh_host_rsa_key', riskLevel: 'critical', desc: 'SSH 主机 RSA 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ed25519_key', riskLevel: 'critical', desc: 'SSH 主机 Ed25519 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ecdsa_key', riskLevel: 'critical', desc: 'SSH 主机 ECDSA 私钥', credential: true },\n];\n\nexport const HOME_SENSITIVE_PATHS: { path: string; riskLevel: string; desc: string; credential?: boolean }[] = [\n { path: '.ssh/id_rsa', riskLevel: 'critical', desc: 'SSH 私钥', credential: true },\n { path: '.ssh/id_ed25519', riskLevel: 'critical', desc: 'SSH 私钥 (ed25519)', credential: true },\n { path: '.ssh/authorized_keys', riskLevel: 'high', desc: 'SSH 授权密钥' },\n // 持久化与命令劫持(仅拦截写入)\n { path: '.bashrc', riskLevel: 'high', desc: '用户 Shell 初始化脚本' },\n { path: '.bash_profile', riskLevel: 'high', desc: '用户 Shell 登录脚本' },\n { path: '.profile', riskLevel: 'high', desc: '用户通用登录脚本' },\n { path: '.aws/credentials', riskLevel: 'critical', desc: 'AWS 凭证', credential: true },\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)\nexport const 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\nexport const 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\nexport const 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)\nexport const 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 // 非 shell/文件类操作跳过意图一致性和敏感路径检查\n const EXCLUDED_PREFIXES = ['memory-', 'skill-', 'skill-manager-', 'mailbox-', 'app-'];\n const isExcludedType = EXCLUDED_PREFIXES.some(p => actionType.startsWith(p));\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 // 只对 shell/文件类操作执行意图一致性检查\n if (!isExcludedType) {\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\n // Rule 3: Sensitive path access\n // 只对文件/命令类操作执行敏感路径检查\n if (!isExcludedType) {\n // agent_ext 透传:通用规则先匹配,agent 专属敏感路径追加在后\n const agentExt: AgentExtensions | null = getAgentExtensions((input as { agentId?: string }).agentId || '');\n const pathResult = checkSensitivePath(actionDetail, resolvedCwd, agentExt);\n if (pathResult) return pathResult;\n }\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 \n\n// ==================== 只读命令集合(用于重定向写判定与敏感路径读写区分)====================\nvar _READ_ONLY_COMMANDS = new Set([\n 'cat', 'head', 'tail', 'less', 'more', 'grep', 'find', 'awk', 'sed',\n 'sort', 'uniq', 'wc', 'cut', 'strings', 'od', 'xxd', 'hexdump', 'tr',\n 'file', 'stat', 'du', 'df', 'ls', 'dir', 'tree', 'nl', 'tac', 'rev',\n 'lsblk', 'blockdev', 'smartctl', 'udevadm', 'dmidecode', 'lscpu', 'lspci',\n 'lsusb', 'lsmem', 'lsns', 'lsof', 'hwinfo', 'inxi', 'fdisk', 'parted',\n 'dmesg', 'journalctl', 'systemctl', 'hostnamectl', 'localectl', 'timedatectl',\n 'ps', 'top', 'free', 'vmstat', 'iostat', 'mpstat', 'pidof', 'pgrep',\n 'ip', 'ifconfig', 'route', 'ss', 'netstat', 'arp', 'ethtool', 'nmcli',\n 'uname', 'arch', 'nproc', 'getconf', 'getent', 'id', 'whoami', 'who',\n 'w', 'last', 'uptime', 'lsmod', 'modinfo', 'sysctl',\n]);\n\n// 重定向到 /dev/null 的丢弃写法\nvar _DEVNULL_REDIRECT_RE = /(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/;\n\n// 写/删命令词边界正则\nvar _WRITE_COMMAND_RES = [\n /\\brm\\b/, /\\bunlink\\b/, /\\brmdir\\b/, /\\bshred\\b/,\n /\\bcp\\b/, /\\bmv\\b/, /\\binstall\\b/, /\\btee\\b/,\n /\\bdd\\b/, /\\bmkfs\\b/, /\\b(fdisk|parted|cfdisk|sfdisk)\\b/,\n /\\bchmod\\b/, /\\bchown\\b/, /\\btruncate\\b/,\n];\n\n// 综合判定是否为写/删操作\n// Rule 4.5: Indirect file access — inline script with dir traversal + file read/write\n // Uses cwd to list actual files and check against sensitive paths directly\n const indirectResult = checkIndirectFileAccess(actionType, actionDetail, resolvedCwd);\n if (indirectResult) return indirectResult;\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, agentExt?: import('../agents').AgentExtensions | null): SecurityJudgment | null {\n const expandedCwd = cwd.replace(/^~/, process.env.HOME || '/home/user');\n\n // 局部常量(避免引用模块级常量被 esbuild 重命名导致 ReferenceError)\n const _WRITE_CMD_RES = [/\\brm\\b/, /\\bunlink\\b/, /\\brmdir\\b/, /\\bshred\\b/, /\\bcp\\b/, /\\bmv\\b/, /\\binstall\\b/, /\\btee\\b/, /\\bdd\\b/, /\\bmkfs\\b/, /\\b(fdisk|parted|cfdisk|sfdisk)\\b/, /\\bchmod\\b/, /\\bchown\\b/, /\\btruncate\\b/];\n const _DEVNULL_RE = /(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/;\n const _READONLY_CMDS = new Set(['cat','head','tail','less','more','grep','find','awk','sed','sort','uniq','wc','cut','strings','od','xxd','hexdump','tr','file','stat','du','df','ls','dir','tree','nl','tac','rev','lsblk','blockdev','smartctl','udevadm','dmidecode','lscpu','lspci','lsusb','lsmem','lsns','lsof','hwinfo','inxi','fdisk','parted','dmesg','journalctl','systemctl','hostnamectl','localectl','timedatectl','ps','top','free','vmstat','iostat','mpstat','pidof','pgrep','ip','ifconfig','route','ss','netstat','arp','ethtool','nmcli','uname','arch','nproc','getconf','getent','id','whoami','who','w','last','uptime','lsmod','modinfo','sysctl']);\n\n const isWriteOpFlag = _WRITE_CMD_RES.some(rx => rx.test(command)) ||\n /\\bsed\\s+-[a-zA-Z]*i/.test(command) ||\n (command.includes('>') && !command.replace(_DEVNULL_RE, '').includes('>')) ||\n (command.includes('>') && command.replace(_DEVNULL_RE, '').includes('>') &&\n !_READONLY_CMDS.has(command.trim().split(/\\s+/)[0]?.toLowerCase() || '')) ||\n WRITE_KEYWORDS.some(kw => ''.includes(kw) || command.includes(kw));\n\n for (const sp of ROOT_SENSITIVE_PATHS) {\n if (command.includes(sp.path.toLowerCase())) {\n // /dev/random:只拦截读取操作,写入/删除放行(读取可耗尽熵池导致 TLS 阻塞)\n if (sp.path === '/dev/random') {\n if (isWriteOpFlag) {\n continue; // 允许写入操作(投喂熵池)\n }\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 // 凭据路径(sp.credential=true,如 /etc/shadow、SSH 私钥、AWS 凭证):\n // 读写均拦(读取凭据同样危险)。与 py deny_both 一致。\n if (!isWriteOpFlag && !sp.credential) {\n continue;\n }\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 // 非凭据路径:只拦截写入/删除操作,只读访问放行。\n // 凭据路径(sp.credential=true,如 SSH 私钥、AWS 凭证):\n // 读写均拦(读取凭据同样危险)。与 py deny_both 一致。\n if (!isWriteOpFlag && !sp.credential) {\n continue;\n }\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 // agent 专属敏感路径(追加在通用规则之后)\n if (agentExt?.extra_sensitive_paths && agentExt.extra_sensitive_paths.length > 0) {\n for (const sp of agentExt.extra_sensitive_paths) {\n const spPath = sp.path.toLowerCase();\n const expanded = `${expandedCwd}/${spPath}`;\n if (command.includes(spPath) || command.includes(expanded.toLowerCase())) {\n const denyMode = sp.deny_mode || (sp.credential ? 'deny_both' : sp.read_only ? 'deny_read' : 'deny_write');\n if (denyMode === 'deny_read') {\n if (isWriteOpFlag) continue;\n } else if (denyMode === 'deny_write') {\n if (!isWriteOpFlag) continue;\n }\n // deny_both:读写均拦\n return {\n allowed: false,\n reason: `尝试访问 agent 专属敏感路径: ${sp.desc} (${sp.path})`,\n riskLevel: sp.risk_level as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_path_access',\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n }\n\n // Credential files: always intercept regardless of read/write // Credential files: always intercept regardless of read/write\n // Files starting with . need special handling since \\b doesn't match before .\n // 边界字符含引号:凭据常出现在 open('.env')、cat \".env\" 等引号上下文里\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 isCredential: true,\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\n// 内联脚本解释器正则\nconst INLINE_SCRIPT_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\n// 目录遍历关键词(用唯一名称避免与 inline-analyzer.ts 的 DIR_TRAVERSAL_KEYWORDS 冲突)\nconst DIR_TRAVERSAL_KW = [\n 'os.listdir', 'os.walk', 'os.scandir',\n 'glob.glob', 'glob.iglob', 'pathlib.', 'iterdir', 'rglob',\n 'scandir(', 'listdir(',\n];\n\n/**\n * Rule 4.5: Indirect file access detection.\n * Detects inline scripts that use directory traversal (os.listdir/glob/pathlib)\n * combined with file read/write operations to dynamically discover and access\n * sensitive files, bypassing static path matching.\n *\n * Returns medium risk so the coordinator forwards to Layer 3 LLM analysis\n * instead of denying immediately.\n */\nfunction checkIndirectFileAccess(actionType: string, actionDetail: string, cwd: string): SecurityJudgment | null {\n // Only check bash tool inline scripts\n if (actionType !== 'bash' && actionType !== 'executebash' && actionType !== 'terminal-executebash') {\n return null;\n }\n\n // Check if it's an inline script command\n INLINE_SCRIPT_RE.lastIndex = 0;\n if (!INLINE_SCRIPT_RE.test(actionDetail)) {\n return null;\n }\n\n // Check for directory traversal keywords\n const lowerDetail = actionDetail.toLowerCase();\n const hasTraversal = DIR_TRAVERSAL_KW.some(kw => lowerDetail.includes(kw));\n if (!hasTraversal) {\n return null;\n }\n\n // Extract code and check for read/write keywords, distinguishing read/write/exec\n const READ_KEYWORDS = ['read(', 'readline', 'readlines', 'fread', 'fgets', 'load(', 'getpass', 'file_get_contents'];\n const WRITE_KEYWORDS = ['write(', 'writelines', 'fwrite', 'file_put_contents'];\n const EXEC_KEYWORDS = ['system(', 'exec(', 'eval(', 'popen(', 'os.system', 'os.popen', 'subprocess', 'os.exec', 'os.spawn', 'shell=true', 'check_output', 'check_call', 'run(', 'passthru', 'shell_exec', 'proc_open'];\n const OPEN_KEYWORDS = ['open(', 'fopen('];\n const code = extractInlineCode(actionDetail);\n if (!code) return null;\n const codeLower = code.toLowerCase();\n const hasAnyOp = READ_KEYWORDS.some(kw => codeLower.includes(kw)) ||\n WRITE_KEYWORDS.some(kw => codeLower.includes(kw)) ||\n EXEC_KEYWORDS.some(kw => codeLower.includes(kw)) ||\n OPEN_KEYWORDS.some(kw => codeLower.includes(kw));\n if (!hasAnyOp) {\n return null;\n }\n\n // Determine operation type\n const hasWrite = WRITE_KEYWORDS.some(kw => codeLower.includes(kw));\n const hasExec = EXEC_KEYWORDS.some(kw => codeLower.includes(kw));\n // Write/exec: block all sensitive files. Read only: block only credential files.\n const blockAllSensitive = hasWrite || hasExec;\n\n // Pattern matched — try to list actual files in cwd and check against sensitive paths\n let actualFiles: string[] = [];\n if (cwd && cwd !== '/') {\n try {\n actualFiles = fs.readdirSync(cwd);\n } catch {\n // cwd invalid or inaccessible, fall through\n }\n }\n\n if (actualFiles.length > 0) {\n // Check credential files\n for (const cp of CREDENTIAL_PATHS) {\n const fname = cp.path.split('/').pop() || cp.path;\n if (actualFiles.some(f => f === fname || f.toLowerCase() === fname.toLowerCase())) {\n return {\n allowed: false,\n reason: `内联脚本使用目录遍历动态发现文件并执行读写操作,cwd (${cwd}) 中包含凭据文件: ${fname}`,\n riskLevel: 'high',\n riskType: 'file_access',\n confidence: 95,\n source: 'logic_rule',\n violatedLayers: ['2'],\n isCredential: true,\n };\n }\n }\n\n // Check other sensitive files (only block on write/exec, read-only is safe for non-credential)\n if (blockAllSensitive) {\n for (const sp of [...ROOT_SENSITIVE_PATHS, ...HOME_SENSITIVE_PATHS]) {\n const fname = sp.path.split('/').pop() || sp.path;\n if (actualFiles.some(f => f === fname || f.toLowerCase() === fname.toLowerCase())) {\n return {\n allowed: false,\n reason: `内联脚本使用目录遍历动态发现文件并执行写操作,cwd (${cwd}) 中包含敏感文件: ${fname}`,\n riskLevel: 'high',\n riskType: 'file_access',\n confidence: 95,\n source: 'logic_rule',\n violatedLayers: ['2'],\n };\n }\n }\n }\n\n // No sensitive files found in cwd — safe to allow\n return null;\n }\n\n // cwd invalid, can't check actual files — fall back to medium risk (L3)\n return {\n allowed: false,\n reason: '内联脚本使用目录遍历函数动态发现文件并执行读写操作,无法获取 cwd 实际文件列表,转层3 LLM 分析',\n riskLevel: 'medium',\n riskType: 'file_access',\n confidence: 70,\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// 优先用打包内联目录 dist/skills(npm 安装后自包含);\n// dev 模式(vitest 测试时 __dirname=ts/src/engine)回退到仓库根 agent_moss/skills。\n// 注意:从 ts/src/engine 出发,仓库根 agent_moss/skills 在 ../../../agent_moss/skills\n// (不能写 ../../agent_moss/skills,那是 ts/agent_moss/skills,不存在)。\nconst SKILLS_DIR = resolve(__dirname, '../skills');\nconst SKILLS_DIR_FALLBACK = resolve(__dirname, '../../../agent_moss/skills');\n\n// Skill keyword map (synced with Python skill_engine.py SKILL_KEYWORD_MAP)\n// exported for runtime_config seed (generateSourceDefaults)\nexport const 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 // 注意:避免裸 'memory'/'内存'/'dd'——会误命中 memory-addMemory(写记忆工具,\n // 'dd' 是 'addMemory' 的子串)等无害操作。用组合词/命令前缀精准匹配攻击场景。\n 'resource_exhaustion_guard': ['fork', 'bomb', '炸弹', 'memory bomb', 'oom', 'out of memory', '内存溢出', '内存耗尽', '内存泄漏', 'disk', '磁盘', 'cpu', 'process', '进程', 'dd if=', '/dev/zero', '/dev/null', 'yes >', '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 'indirect_access_guard': ['listdir', 'os.walk', 'os.scandir', 'glob.glob', 'glob.iglob', 'pathlib', 'iterdir', 'rglob', 'scandir', 'os.listdir', '目录遍历', 'traversal'],\n};\n\nlet cachedSkills: Record<string, string> | null = null;\n\nfunction loadAllSkills(): Record<string, string> {\n if (cachedSkills) return cachedSkills;\n cachedSkills = {};\n\n const dir = existsSync(SKILLS_DIR) ? SKILLS_DIR : SKILLS_DIR_FALLBACK;\n if (!existsSync(dir)) {\n console.warn('[AgentMoss] Skills directory not found:', SKILLS_DIR, 'and fallback:', SKILLS_DIR_FALLBACK);\n return cachedSkills;\n }\n\n const files = readdirSync(dir).filter(f => f.endsWith('.md'));\n for (const f of files) {\n const name = f.replace('.md', '');\n cachedSkills[name] = readFileSync(resolve(dir, f), 'utf-8');\n }\n\n console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);\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\n// 优先用打包内联目录 dist/templates(npm 安装后自包含);\n// dev 模式(vitest 测试时 __dirname=ts/src/engine)回退到仓库根 agent_moss/templates。\n// 注意:从 ts/src/engine 出发,仓库根 agent_moss/templates 在 ../../../agent_moss/templates\n// (不能写 ../../agent_moss/templates,那是 ts/agent_moss/templates,不存在)。\nconst TEMPLATES_DIR = resolve(__dirname, '../templates');\nconst TEMPLATES_DIR_FALLBACK = 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 const dir = existsSync(TEMPLATES_DIR) ? TEMPLATES_DIR : TEMPLATES_DIR_FALLBACK;\n if (!existsSync(dir)) {\n console.warn('[AgentMoss] Templates directory not found:', TEMPLATES_DIR, 'and fallback:', TEMPLATES_DIR_FALLBACK);\n return cachedTemplates;\n }\n\n for (const file of TEMPLATE_FILES) {\n const filePath = resolve(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 from ${dir}`);\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","/**\n * Script content analyzer — recursive chain tracking + preprocessing + L1/L2 reuse.\n *\n * Mirrors Python agent_moss/engine/script_content_analyzer.py.\n *\n * Core improvements over the old single-file script-analyzer.ts:\n * 1. Preprocessing pipeline: strip comments -> strip echo text -> expand simple vars\n * 2. Broader script path extraction (no .sh restriction; python/node/ruby/...)\n * 3. File-size limit instead of line limit (full read; ms-scale cost)\n * 4. Recursive tracking: A.sh -> B.sh -> C.sh nested calls are caught\n * 5. L1/L2 reuse: preprocessed content scanned via existing runHeuristicCheck /\n * runLogicCheck; high/critical deny directly, skipping L3\n *\n * Difference from Python: AgentMoss-TS heuristic/logic are single entry functions\n * (runHeuristicCheck / runLogicCheck taking AnalysisInput), not reusable scanner\n * objects. So L1/L2 per-node reuse wraps each node's preprocessed content as a\n * virtual AnalysisInput and calls those functions.\n */\n\nimport { readFileSync, statSync, existsSync } from 'fs';\nimport { resolve, join, isAbsolute, dirname } from 'path';\nimport { homedir } from 'os';\nimport type { AnalysisInput } from './coordinator';\nimport type { SecurityJudgment } from './types';\nimport { runHeuristicCheck } from './heuristic';\nimport { runLogicCheck } from './logic-rules';\n\n// ==================== Types ====================\n\nexport interface ScriptNode {\n scriptPath: string;\n rawContent: string;\n preprocessedContent: string;\n lineCount: number;\n fileSize: number;\n depth: number;\n childPaths: string[];\n error: string;\n\n l1Hit: boolean;\n l1RiskLevel: string;\n l1RiskType: string;\n l1Reason: string;\n l1MatchedPatterns: string[];\n\n l2Hit: boolean;\n l2ViolatedRule: string;\n l2RiskLevel: string;\n l2RiskType: string;\n l2Reason: string;\n\n matchedKeywords: string[];\n isSuspicious: boolean;\n keywordRiskLevel: string;\n keywordRiskReason: string;\n}\n\nexport interface ScriptChainAnalysisResult {\n nodes: ScriptNode[];\n entryPath: string;\n maxDepthReached: boolean;\n maxSizeReached: boolean;\n totalSize: number;\n totalLines: number;\n hasCritical: boolean;\n hasHigh: boolean;\n firstHitNode: ScriptNode | null;\n error: string;\n}\n\nfunction emptyChain(): ScriptChainAnalysisResult {\n return {\n nodes: [], entryPath: '', maxDepthReached: false, maxSizeReached: false,\n totalSize: 0, totalLines: 0, hasCritical: false, hasHigh: false,\n firstHitNode: null, error: '',\n };\n}\n\nfunction newNode(path: string, depth: number): ScriptNode {\n return {\n scriptPath: path, rawContent: '', preprocessedContent: '', lineCount: 0,\n fileSize: 0, depth, childPaths: [], error: '',\n l1Hit: false, l1RiskLevel: '', l1RiskType: '', l1Reason: '', l1MatchedPatterns: [],\n l2Hit: false, l2ViolatedRule: '', l2RiskLevel: '', l2RiskType: '', l2Reason: '',\n matchedKeywords: [], isSuspicious: false, keywordRiskLevel: '', keywordRiskReason: '',\n };\n}\n\n// ==================== Preprocessing pipeline ====================\n\nfunction stripComments(content: string): string {\n return content.split('\\n').filter(line => !line.trimStart().startsWith('#')).join('\\n');\n}\n\nfunction stripOutputText(content: string): string {\n let result = content.replace(/echo\\s+\".*?\"/gs, 'echo \"\"');\n result = result.replace(/echo\\s+'.*?'/gs, \"echo ''\");\n result = result.replace(/printf\\s+\".*?\"[^\\n]*/gs, 'printf \"\"');\n result = result.replace(/printf\\s+'.*?'[^\\n]*/gs, \"printf ''\");\n return result;\n}\n\nfunction expandSimpleVariables(content: string): string {\n const varMap: Record<string, string> = {};\n const assignmentRe = /^\\s*(?:export\\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.+)$/;\n\n const collectAssignments = (text: string) => {\n for (const line of text.split('\\n')) {\n const m = line.match(assignmentRe);\n if (m) {\n const varName = m[1];\n let varVal = m[2].trim();\n if (varVal && !varVal.includes('$') && !varVal.includes('`')) {\n if ((varVal.startsWith('\"') && varVal.endsWith('\"')) ||\n (varVal.startsWith(\"'\") && varVal.endsWith(\"'\"))) {\n varVal = varVal.slice(1, -1);\n }\n varMap[varName] = varVal;\n }\n }\n }\n };\n\n collectAssignments(content);\n let expanded = content;\n\n for (let round = 0; round < 3; round++) {\n const sortedVars = Object.keys(varMap).sort((a, b) => b.length - a.length);\n let newExpanded = expanded;\n for (const v of sortedVars) {\n const val = varMap[v];\n newExpanded = newExpanded.split('${' + v + '}').join(val);\n newExpanded = newExpanded.split('$' + v).join(val);\n }\n if (newExpanded === expanded) break;\n expanded = newExpanded;\n collectAssignments(expanded);\n }\n return expanded;\n}\n\nfunction preprocessScriptContent(content: string): string {\n let result = stripComments(content);\n result = stripOutputText(result);\n result = expandSimpleVariables(result);\n return result;\n}\n\n\n// ==================== High-risk keyword patterns (L3 compatible) ====================\n\nconst SUSPICIOUS_PATTERNS: { name: string; pattern: RegExp }[] = [\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 { 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 { name: '$(base64', pattern: /\\$\\(\\s*base64/ },\n { name: '`base64', pattern: /`\\s*base64/ },\n { name: 'base64 decode pipe', pattern: /base64\\s+(-d|--decode)\\s*\\|/ },\n { name: '/etc/shadow', pattern: /\\/etc\\/shadow/ },\n { name: 'id_rsa', pattern: /\\bid_rsa\\b/ },\n { name: 'id_ed25519', pattern: /\\bid_ed25519\\b/ },\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\n// ==================== Script execution patterns ====================\n\nconst SCRIPT_EXEC_PATTERNS: RegExp[] = [\n /(?:^|\\s|&&|\\|\\|)\\s*bash\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*\\/bin\\/bash\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*sh\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*zsh\\s+(\\S+)/i,\n /\\.\\/(\\S+)/,\n /(?:^|\\s|&&|\\|\\|)\\s*source\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*\\.\\s+(\\S+)/,\n /(?:^|\\s|&&|\\|\\|)\\s*python3?\\s+(\\S+\\.py)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*node\\s+(\\S+\\.js)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*ruby\\s+(\\S+\\.rb)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*perl\\s+(\\S+\\.pl)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*php\\s+(\\S+\\.php)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*lua\\s+(\\S+\\.lua)/i,\n];\n\n\n// ==================== Keyword combination risk rules ====================\n\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\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 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 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 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 return { level: bestLevel, reason: bestReason };\n}\n\n\n// ==================== Script path extraction ====================\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 extractInlineScriptPath(actionDetail: string): string | null {\n const re = /open\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(actionDetail)) !== null) {\n const p = m[1];\n let resolved: string;\n try {\n resolved = resolvePath(p);\n if (existsSync(resolved)) {\n const stat = statSync(resolved);\n if (stat.isFile()) return resolved;\n }\n } catch { /* ignore */ }\n }\n return null;\n}\n\n/** Resolve a path: expand ~, resolve relative against cwd. */\nfunction resolvePath(p: string): string {\n let expanded = p;\n if (expanded.startsWith('~/') || expanded === '~') {\n expanded = join(homedir(), expanded.slice(1));\n }\n return resolve(expanded);\n}\n\n\n// ==================== Script content reading ====================\n\nfunction readScriptContent(\n scriptPath: string,\n maxFileSize: number = 2 * 1024 * 1024,\n): { content: string; lineCount: number; fileSize: number; error: string } {\n try {\n const path = resolvePath(scriptPath);\n if (!existsSync(path)) return { content: '', lineCount: 0, fileSize: 0, error: `脚本不存在: ${scriptPath}` };\n\n const stat = statSync(path);\n if (!stat.isFile()) return { content: '', lineCount: 0, fileSize: 0, error: `不是文件: ${scriptPath}` };\n if (stat.size > maxFileSize) {\n return { content: '', lineCount: 0, fileSize: stat.size, error: `脚本文件过大 (${stat.size} bytes),跳过读取` };\n }\n\n const content = readFileSync(path, 'utf-8');\n const lineCount = content ? content.split('\\n').length : 0;\n return { content, lineCount, fileSize: stat.size, error: '' };\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n return { content: '', lineCount: 0, fileSize: 0, error: `读取脚本失败: ${msg}` };\n }\n}\n\n\n// ==================== Recursive tracking ====================\n\nfunction extractChildScriptPaths(content: string, baseDir: string): string[] {\n const paths: string[] = [];\n for (const pattern of CHILD_SCRIPT_PATTERNS) {\n pattern.lastIndex = 0;\n let m: RegExpExecArray | null;\n while ((m = pattern.exec(content)) !== null) {\n const pathStr = m[1];\n if (pathStr.startsWith('-') || pathStr.startsWith('$')) continue;\n if (pathStr.includes('/dev/') || pathStr.startsWith('|') || pathStr.startsWith(';')) continue;\n const full = isAbsolute(pathStr) ? pathStr : join(baseDir, pathStr);\n const resolved = resolvePath(full);\n if (existsSync(resolved)) {\n try {\n if (statSync(resolved).isFile() && !paths.includes(resolved)) paths.push(resolved);\n } catch { /* ignore */ }\n }\n }\n }\n return paths;\n}\n\n/**\n * Recursive script chain tracking. Reads + preprocesses each node.\n *\n * @param entryPath entry script path\n * @param input original AnalysisInput (used to build virtual per-node inputs for\n * L1/L2 reuse — carries promptSession/actionHistory/cwd for intent + path checks)\n * @param maxDepth max recursion depth (0=entry, 1=entry's children, ...)\n * @param maxFileSize per-file size cap (default 2MB)\n * @param maxTotalSize cumulative size cap (default 6MB)\n */\nfunction resolveScriptChain(\n entryPath: string,\n input: AnalysisInput,\n maxDepth: number = 3,\n maxFileSize: number = 2 * 1024 * 1024,\n maxTotalSize: number = 6 * 1024 * 1024,\n): ScriptChainAnalysisResult {\n const visited = new Set<string>();\n const result = emptyChain();\n result.entryPath = entryPath;\n\n const entry = resolvePath(entryPath);\n const baseDir = existsSync(entry) ? dirname(entry) : (input.cwd || process.cwd());\n\n resolveRecursive({\n path: entry, depth: 0, maxDepth, maxFileSize, maxTotalSize,\n visited, result, baseDir, input,\n });\n\n result.hasCritical = result.nodes.some(n =>\n n.l1RiskLevel === 'critical' || n.l2RiskLevel === 'critical' || n.keywordRiskLevel === 'critical');\n result.hasHigh = result.nodes.some(n =>\n ['high', 'critical'].includes(n.l1RiskLevel) ||\n ['high', 'critical'].includes(n.l2RiskLevel) ||\n ['high', 'critical'].includes(n.keywordRiskLevel));\n result.firstHitNode = result.nodes.find(n => n.l1Hit || n.l2Hit || n.isSuspicious) || null;\n\n return result;\n}\n\ninterface ResolveCtx {\n path: string;\n depth: number;\n maxDepth: number;\n maxFileSize: number;\n maxTotalSize: number;\n visited: Set<string>;\n result: ScriptChainAnalysisResult;\n baseDir: string;\n input: AnalysisInput;\n}\n\nfunction resolveRecursive(ctx: ResolveCtx): void {\n const { path, depth, maxDepth, maxFileSize, maxTotalSize, visited, result, baseDir, input } = ctx;\n\n if (visited.has(path)) return;\n if (depth > maxDepth) {\n result.maxDepthReached = true;\n return;\n }\n if (result.totalSize >= maxTotalSize) {\n result.maxSizeReached = true;\n return;\n }\n\n visited.add(path);\n\n const { content, lineCount, fileSize, error } = readScriptContent(path, maxFileSize);\n if (error) {\n const node = newNode(path, depth);\n node.error = error;\n node.fileSize = fileSize;\n node.lineCount = lineCount;\n result.nodes.push(node);\n return;\n }\n\n result.totalSize += fileSize;\n result.totalLines += lineCount;\n\n const preprocessed = preprocessScriptContent(content);\n const node = newNode(path, depth);\n node.rawContent = content;\n node.preprocessedContent = preprocessed;\n node.lineCount = lineCount;\n node.fileSize = fileSize;\n result.nodes.push(node);\n\n // Inline L1 + L2 scan during recursion (virtual input = preprocessed content)\n const virtualInput: AnalysisInput = {\n ...input,\n aNext: { actionType: 'bash', actionDetail: preprocessed },\n };\n const l1 = runHeuristicCheck(virtualInput);\n if (l1 && !l1.allowed) {\n node.l1Hit = true;\n node.l1RiskLevel = l1.riskLevel;\n node.l1RiskType = l1.riskType;\n node.l1Reason = l1.reason;\n node.l1MatchedPatterns = [];\n if (l1.riskLevel === 'critical') {\n result.hasCritical = true;\n result.firstHitNode = node;\n return;\n }\n }\n\n const childPaths = extractChildScriptPaths(preprocessed, baseDir);\n node.childPaths = childPaths;\n\n for (const childPath of childPaths) {\n resolveRecursive({\n path: resolvePath(childPath), depth: depth + 1, maxDepth, maxFileSize, maxTotalSize,\n visited, result, baseDir: dirname(resolvePath(childPath)), input,\n });\n if (result.hasCritical) return;\n }\n}\n\n\n// ==================== L1/L2 fallback chain scan ====================\n\n/** L1 fallback: scan nodes that weren't inline-scanned during recursion. */\nfunction scanScriptChainWithL1(chain: ScriptChainAnalysisResult, input: AnalysisInput): ScriptChainAnalysisResult {\n for (const node of chain.nodes) {\n if (node.error || !node.preprocessedContent || node.l1Hit) continue;\n const virtualInput: AnalysisInput = {\n ...input,\n aNext: { actionType: 'bash', actionDetail: node.preprocessedContent },\n };\n const l1 = runHeuristicCheck(virtualInput);\n if (l1 && !l1.allowed) {\n node.l1Hit = true;\n node.l1RiskLevel = l1.riskLevel;\n node.l1RiskType = l1.riskType;\n node.l1Reason = l1.reason;\n if (l1.riskLevel === 'critical') {\n chain.hasCritical = true;\n chain.firstHitNode = node;\n break;\n }\n }\n }\n return chain;\n}\n\n/**\n * L2 fallback: scan each node's preprocessed content via runLogicCheck.\n * Only reuses action-history-independent rules (sensitive path / dangerous\n * patterns / intent). runLogicCheck runs all L2 rules; we accept its verdict\n * per node (matching Python's per-rule reuse behaviorally).\n */\nfunction scanScriptChainWithL2(chain: ScriptChainAnalysisResult, input: AnalysisInput): ScriptChainAnalysisResult {\n for (const node of chain.nodes) {\n if (node.error || !node.preprocessedContent) continue;\n if (node.l1RiskLevel === 'critical') break;\n\n const virtualInput: AnalysisInput = {\n ...input,\n aNext: { actionType: 'bash', actionDetail: node.preprocessedContent },\n };\n const l2 = runLogicCheck(virtualInput);\n if (l2 && !l2.allowed) {\n node.l2Hit = true;\n node.l2ViolatedRule = `script_logic:${node.scriptPath}`;\n node.l2RiskLevel = l2.riskLevel;\n node.l2RiskType = l2.riskType;\n node.l2Reason = `脚本 ${node.scriptPath} (深度 ${node.depth}) 中: ${l2.reason}`;\n if (l2.riskLevel === 'critical') {\n chain.hasCritical = true;\n chain.firstHitNode = node;\n break;\n }\n }\n }\n if (!chain.hasHigh) {\n chain.hasHigh = chain.nodes.some(n => ['high', 'critical'].includes(n.l2RiskLevel));\n }\n return chain;\n}\n\n/** Keyword scan per node (L3-compatible). Only nodes not hit by L1/L2. */\nfunction scanScriptChainKeywords(chain: ScriptChainAnalysisResult): ScriptChainAnalysisResult {\n for (const node of chain.nodes) {\n if (node.error || !node.preprocessedContent) continue;\n if (node.l1Hit || node.l2Hit) continue;\n\n const matched = scanScriptForKeywords(node.preprocessedContent);\n node.matchedKeywords = matched;\n node.isSuspicious = matched.length > 0;\n\n if (matched.length > 0) {\n const risk = assessKeywordCombinationRisk(matched, node.preprocessedContent);\n node.keywordRiskLevel = risk.level;\n node.keywordRiskReason = risk.reason;\n }\n }\n return chain;\n}\n\n\n// ==================== Entry function ====================\n\n/**\n * Analyze script content: recursive tracking + preprocessing + L1/L2/keyword scan.\n * Only runs when actionType is 'bash' and the command invokes a script.\n *\n * Mirrors Python analyze_script_content. L1/L2 reuse wraps each node's\n * preprocessed content as a virtual AnalysisInput.\n */\nexport function analyzeScriptContent(input: AnalysisInput): ScriptChainAnalysisResult {\n const actionType = input.aNext.actionType.toLowerCase();\n if (actionType !== 'bash') return emptyChain();\n\n const scriptPath = extractScriptPath(input.aNext.actionDetail);\n let resolvedPath = scriptPath;\n if (!resolvedPath) {\n const inline = extractInlineScriptPath(input.aNext.actionDetail);\n if (!inline) return emptyChain();\n resolvedPath = inline;\n }\n\n const chain = resolveScriptChain(resolvedPath, input);\n if (chain.nodes.length === 0) return chain;\n\n // L1 fallback + L2 + keyword scans\n scanScriptChainWithL1(chain, input);\n scanScriptChainWithL2(chain, input);\n scanScriptChainKeywords(chain);\n\n return chain;\n}\n\n\n// ==================== L3 prompt formatting ====================\n\nexport function formatScriptChainForPrompt(chain: ScriptChainAnalysisResult): string {\n if (chain.nodes.length === 0) return '';\n\n const errorNodes = chain.nodes.filter(n => n.error);\n if (errorNodes.length > 0 && chain.nodes.length === 1) {\n return `⚠️ 脚本内容分析失败: ${errorNodes[0].error}`;\n }\n\n const suspiciousNodes = chain.nodes.filter(n => n.isSuspicious && !n.l1Hit && !n.l2Hit);\n if (suspiciousNodes.length === 0) {\n const safeNodes = chain.nodes.filter(n => !n.error);\n if (safeNodes.length === 0) return '';\n const parts: string[] = ['✓ 脚本内容已分析,未发现危险/可疑操作(L1/L2/关键词扫描均未命中):'];\n for (const node of safeNodes) {\n const pre = node.preprocessedContent || '';\n let preview = pre.slice(0, 600);\n if (pre.length > 600) preview += `\\n... (截断,完整内容 ${pre.length} 字符)`;\n parts.push(\n ` 脚本路径: ${node.scriptPath}(递归深度 ${node.depth},${node.lineCount} 行)\\n` +\n ` 内容(预处理后):\\n\\`\\`\\`\\n${preview}\\n\\`\\`\\``\n );\n }\n return parts.join('\\n');\n }\n\n const parts: string[] = [];\n for (const node of suspiciousNodes) {\n const keywordsStr = node.matchedKeywords.join(', ');\n let riskHint = '';\n if (node.keywordRiskLevel && node.keywordRiskReason) {\n riskHint =\n `\\n\\n🔴 **风险评估**: ${node.keywordRiskLevel.toUpperCase()} 级别\\n` +\n `**风险原因**: ${node.keywordRiskReason}\\n` +\n `**建议**: 此脚本应被拒绝(Deny),除非有明确的业务需求且已确认目标服务器可信。`;\n }\n const pre = node.preprocessedContent;\n let contentPreview = pre.slice(0, 2000);\n if (pre.length > 2000) contentPreview += `\\n... (截断,完整内容 ${pre.length} 字符)`;\n parts.push(\n `⚠️ 脚本内容包含可疑关键词:\\n` +\n ` 脚本路径: ${node.scriptPath}\\n` +\n ` 递归深度: ${node.depth}\\n` +\n ` 可疑关键词: ${keywordsStr}\\n` +\n ` 脚本行数: ${node.lineCount}${riskHint}\\n\\n` +\n `### 脚本内容(预处理后)###\\n\\`\\`\\`\\n${contentPreview}\\n\\`\\`\\`\\n`\n );\n }\n\n let header = `⚠️ 检测到脚本执行链(共 ${chain.nodes.length} 个脚本),其中 ${suspiciousNodes.length} 个包含可疑关键词:\\n`;\n if (chain.maxDepthReached) header += '⚠️ 注意:递归追踪触达深度上限,可能存在更深层的脚本调用未被扫描。\\n';\n if (chain.maxSizeReached) header += '⚠️ 注意:累计文件大小触达上限,部分脚本可能未被完整读取。\\n';\n\n return header + parts.join('\\n---\\n\\n');\n}\n\n/** [deprecated] Use formatScriptChainForPrompt. */\nexport function formatScriptAnalysisForPrompt(chain: ScriptChainAnalysisResult): string {\n return formatScriptChainForPrompt(chain);\n}\n\nconst CHILD_SCRIPT_PATTERNS: RegExp[] = [\n /(?:^|\\s|&&|\\|\\|)\\s*bash\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*sh\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*source\\s+(\\S+)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*\\.\\s+(\\S+)/,\n /(?:^|\\s|&&|\\|\\|)\\s*python3?\\s+(\\S+\\.py)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*node\\s+(\\S+\\.js)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*ruby\\s+(\\S+\\.rb)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*perl\\s+(\\S+\\.pl)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*php\\s+(\\S+\\.php)/i,\n /(?:^|\\s|&&|\\|\\|)\\s*lua\\s+(\\S+\\.lua)/i,\n];\n","/**\n * Token usage statistics — record and query LLM token consumption.\n *\n * Mirrors Python agent_moss/infra/token_stats.py.\n *\n * Storage: JSON file at ~/.config/agentmoss/agent_moss_token_stats.json\n * (env override AGENT_MOSS_TOKEN_STATS_PATH). Whole-file rewrite per record\n * (not append). Max 10000 records, oldest trimmed.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n\nconst STATS_DIR = join(homedir(), '.config', 'agentmoss');\nconst STATS_FILE = join(STATS_DIR, 'agent_moss_token_stats.json');\nconst ENV_STATS_PATH = 'AGENT_MOSS_TOKEN_STATS_PATH';\nconst MAX_RECORDS = 10000;\n\nexport interface TokenUsageRecord {\n timestamp?: string; // ISO with milliseconds; auto-filled if omitted\n sessionId: string;\n step: string; // \"L3_security_judge\" | \"step2_policy_gen\"\n model: string;\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\ninterface RawRecord {\n timestamp: string;\n session_id: string;\n step: string;\n model: string;\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n}\n\ninterface Aggregated {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n calls: number;\n}\n\nexport interface TokenStatsSummary {\n total_prompt_tokens: number;\n total_completion_tokens: number;\n total_tokens: number;\n total_calls: number;\n by_step: Record<string, Aggregated>;\n by_model: Record<string, Aggregated>;\n by_date: Record<string, Aggregated>;\n}\n\nexport interface TokenTrend {\n dates: string[];\n models: string[];\n series: Record<string, Record<string, number>>;\n}\n\nfunction getStatsPath(): string {\n const envPath = process.env[ENV_STATS_PATH];\n return envPath || STATS_FILE;\n}\n\nfunction loadAllRecords(statsPath: string): RawRecord[] {\n if (!existsSync(statsPath)) return [];\n try {\n const data = JSON.parse(readFileSync(statsPath, 'utf-8'));\n if (Array.isArray(data)) return data;\n if (data && Array.isArray(data.records)) return data.records;\n return [];\n } catch (e) {\n return [];\n }\n}\n\nfunction saveRecords(statsPath: string, records: RawRecord[]): void {\n try {\n const dir = statsPath.substring(0, statsPath.lastIndexOf('/'));\n if (dir && !existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(statsPath, JSON.stringify(records, null, 2), 'utf-8');\n } catch (e) {\n // best-effort\n }\n}\n\n/** Record a single LLM call's token usage. */\nexport function recordTokenUsage(record: TokenUsageRecord): void {\n const statsPath = getStatsPath();\n const records = loadAllRecords(statsPath);\n records.push({\n timestamp: record.timestamp || new Date().toISOString(),\n session_id: record.sessionId,\n step: record.step,\n model: record.model,\n prompt_tokens: record.promptTokens,\n completion_tokens: record.completionTokens,\n total_tokens: record.totalTokens,\n });\n if (records.length > MAX_RECORDS) {\n records.splice(0, records.length - MAX_RECORDS);\n }\n saveRecords(statsPath, records);\n}\n\nfunction filterByDate(\n records: RawRecord[],\n days: number = 0,\n startDate?: string | null,\n endDate?: string | null,\n): RawRecord[] {\n if (startDate || endDate) {\n let startDt = startDate ? new Date(startDate) : new Date(-8640000000000000);\n let endDt = endDate ? new Date(endDate) : undefined;\n if (endDate) {\n const e = new Date(endDate);\n e.setHours(23, 59, 59, 999);\n endDt = e;\n }\n const endMs = endDt ? endDt.getTime() : Number.MAX_SAFE_INTEGER;\n return records.filter(r => {\n try {\n const ts = new Date(r.timestamp).getTime();\n return ts >= startDt.getTime() && ts <= endMs;\n } catch { return true; }\n });\n } else if (days > 0) {\n const cutoff = Date.now() - days * 86400000;\n return records.filter(r => {\n try { return new Date(r.timestamp).getTime() >= cutoff; }\n catch { return true; }\n });\n }\n return records;\n}\n\nfunction aggregate(records: RawRecord[]): {\n totalPrompt: number; totalCompletion: number; totalTotal: number;\n byStep: Record<string, Aggregated>; byModel: Record<string, Aggregated>; byDate: Record<string, Aggregated>;\n} {\n let totalPrompt = 0, totalCompletion = 0, totalTotal = 0;\n const byStep: Record<string, Aggregated> = {};\n const byModel: Record<string, Aggregated> = {};\n const byDate: Record<string, Aggregated> = {};\n\n const bucket = (b: Record<string, Aggregated>, key: string, r: RawRecord) => {\n const e = b[key] || (b[key] = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0, calls: 0 });\n e.prompt_tokens += r.prompt_tokens || 0;\n e.completion_tokens += r.completion_tokens || 0;\n e.total_tokens += r.total_tokens || 0;\n e.calls += 1;\n };\n\n for (const r of records) {\n totalPrompt += r.prompt_tokens || 0;\n totalCompletion += r.completion_tokens || 0;\n totalTotal += r.total_tokens || 0;\n bucket(byStep, r.step || 'unknown', r);\n bucket(byModel, r.model || 'unknown', r);\n let dateKey = 'unknown';\n try {\n dateKey = new Date(r.timestamp).toISOString().slice(0, 10);\n } catch { /* keep unknown */ }\n bucket(byDate, dateKey, r);\n }\n\n // by_date sorted desc by date\n const sortedDate = Object.keys(byDate).sort((a, b) => (a < b ? 1 : a > b ? -1 : 0));\n const sortedByDate: Record<string, Aggregated> = {};\n for (const k of sortedDate) sortedByDate[k] = byDate[k];\n\n return { totalPrompt, totalCompletion, totalTotal, byStep, byModel, byDate: sortedByDate };\n}\n\nexport function getTokenStats(\n days: number = 0,\n startDate?: string | null,\n endDate?: string | null,\n): TokenStatsSummary {\n const records = filterByDate(loadAllRecords(getStatsPath()), days, startDate, endDate);\n const a = aggregate(records);\n return {\n total_prompt_tokens: a.totalPrompt,\n total_completion_tokens: a.totalCompletion,\n total_tokens: a.totalTotal,\n total_calls: records.length,\n by_step: a.byStep,\n by_model: a.byModel,\n by_date: a.byDate,\n };\n}\n\nexport function getRecentRecords(limit: number = 20): RawRecord[] {\n const records = loadAllRecords(getStatsPath());\n return records.slice(-limit);\n}\n\nexport function getTokenTrend(\n days: number = 0,\n startDate?: string | null,\n endDate?: string | null,\n): TokenTrend {\n const records = filterByDate(loadAllRecords(getStatsPath()), days, startDate, endDate);\n const series: Record<string, Record<string, number>> = {};\n const datesSet = new Set<string>();\n for (const r of records) {\n let dateKey: string;\n try { dateKey = new Date(r.timestamp).toISOString().slice(0, 10); }\n catch { continue; }\n const model = r.model || 'unknown';\n const tokens = r.total_tokens || 0;\n datesSet.add(dateKey);\n series[model] = series[model] || {};\n series[model][dateKey] = (series[model][dateKey] || 0) + tokens;\n }\n const dates = Array.from(datesSet).sort();\n const models = Object.keys(series).sort();\n return { dates, models, series };\n}\n\nexport function resetTokenStats(): void {\n const statsPath = getStatsPath();\n if (existsSync(statsPath)) {\n try { unlinkSync(statsPath); } catch { /* ignore */ }\n }\n}\n","import { SecurityJudgment } from './types';\nimport type { AnalysisInput } from './coordinator';\nimport { getLLMConfig, isLLMAvailable, detectProvider, getProviderHeaders, getTimeoutConfig, getRetryConfig } from '../config';\nimport { matchSkills, formatSkillsForPrompt } from './skill-loader';\nimport { loadTemplates } from './template-loader';\nimport { analyzeScriptContent, formatScriptAnalysisForPrompt } from './script-analyzer';\nimport { formatScriptChainForPrompt } from './script-content-analyzer';\nimport { appendFileSync } from 'fs';\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 skipL3Hints?: string;\n scriptChain?: import('./script-content-analyzer').ScriptChainAnalysisResult;\n /** per-request LLM prompt 日志路径(来自调用方 metadata.llm_log_path) */\n llmLogPath?: string;\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 // 优先使用 per-request 的 LLM 配置(OpenDesk 按当前会话模型传入)\n const globalConfig = getLLMConfig();\n const config = input.llmConfig?.apiKey\n ? { ...globalConfig, ...input.llmConfig }\n : globalConfig;\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. Prefer the script chain from coordinator\n // (L1.5/L2.5 already did recursive tracking); fall back to single-file scan.\n let scriptAnalysis: import('./script-analyzer').ScriptAnalysisResult | undefined;\n let scriptChainText = '';\n if (previous.scriptChain) {\n scriptChainText = formatScriptChainForPrompt(previous.scriptChain);\n } else {\n scriptAnalysis = analyzeScriptContent(input.aNext.actionType, input.aNext.actionDetail);\n }\n const prompt = buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis, previous.skipL3Hints ?? '', scriptChainText);\n\n // 写 LLM prompt 到日志(per-request logPath 优先,对齐 py _log_prompt)。\n // 与 bridge.ts 写 HOOK_INPUT/HOOK_OUTPUT 同一个文件,对齐 audit_agent AUDIT_LOG_PATH。\n logPrompt(prompt, input.aNext, previous.llmLogPath);\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\n/**\n * 写 LLM prompt 到日志文件(对齐 Python _log_prompt)。\n * logPath 来自 per-request metadata.llm_log_path(调用方 env 注入)。\n * 与 bridge.ts 的 HOOK_INPUT/HOOK_OUTPUT 写同一个文件,对齐 audit_agent AUDIT_LOG_PATH。\n */\nfunction logPrompt(prompt: string, aNext: { actionType: string; actionDetail: string }, logPath?: string): void {\n if (!logPath) return;\n try {\n const actionType = aNext.actionType || 'unknown';\n const actionDetail = (aNext.actionDetail || '').slice(0, 100);\n const line =\n `[${new Date().toISOString()}] ` +\n `[LLM_PROMPT] action_type=${actionType}, action_detail=${actionDetail}... ` +\n `prompt_length=${prompt.length}\\n` +\n `${prompt}\\n` +\n `--- END PROMPT ---\\n`;\n appendFileSync(logPath, line, 'utf-8');\n } catch (e) {\n console.warn('[AgentMoss] Failed to write LLM prompt to log:', e);\n }\n}\n\nexport function 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 skipL3Hints: string = '',\n scriptChainText: string = '',\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 // Prefer coordinator-provided script chain text (recursive tracking result);\n // fall back to single-file keyword prescan; else empty.\n const scriptAnalysisText = scriptChainText\n ? scriptChainText\n : (scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : '');\n\n // Format L1/L2 hints (mirrors Python LLMAnalyzer._format_hints)\n const hintsText = formatHints(previous);\n\n // Layer 3 安全判断用 security_judge_template(对齐 Python get_security_judge_prompt)。\n // prompt1/prompt2 是 Cerberus 沙箱策略模板,不适用于此处的 Allow/Deny 裁决。\n const securityJudgeTemplate = templates['security_judge'];\n if (securityJudgeTemplate) {\n // 占位符逐个替换(不能用全局 {x} 正则:模板 JSON 示例里的 {{ }} 会误伤)。\n // security_judge_template.txt 用 {{ }} 转义 JSON 大括号,替换完后还原为单括号。\n return securityJudgeTemplate\n .replaceAll('{prompt_session}', input.promptSession || '(未提供)')\n .replaceAll('{action_history}', historyStr)\n .replaceAll('{action_type}', input.aNext.actionType)\n .replaceAll('{action_detail}', input.aNext.actionDetail)\n .replaceAll('{reason}', input.reason || '未说明')\n .replaceAll('{skills_text}', skillsText)\n .replaceAll('{hints_text}', hintsText)\n .replaceAll('{script_analysis_text}', scriptAnalysisText)\n .replaceAll('{skip_l3_hints}', skipL3Hints)\n .replaceAll('{{', '{')\n .replaceAll('}}', '}');\n }\n\n // Fallback:security_judge 模板缺失时(旧包/加载异常),退回稀疏 prompt,避免崩溃。\n // 这种情况下 LLM 裸跑,判断质量下降,但不阻断流程。\n console.warn('[AgentMoss] security_judge template missing, using sparse fallback prompt');\n return `## 当前操作上下文\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请根据以上信息,对即将执行的操作进行安全判断。前置检测为 low/medium 且有合理执行理由时应当允许。你必须输出严格的 JSON 格式,不要包含任何其他文字、注释或 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 timeoutCfg = getTimeoutConfig();\n const retryCfg = getRetryConfig();\n const client = new OpenAI({\n baseURL: config.baseUrl,\n apiKey: config.apiKey,\n // 单次 LLM 调用超时用 prompt1Timeout(对齐 py);env 覆盖的 config.timeout 仍向后兼容\n timeout: (config.timeout || timeoutCfg.prompt1Timeout) * 1000,\n defaultHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined,\n });\n\n // maxRetries 优先 env,否则用 retry 配置(默认 2,对齐 py)\n const maxRetries = parseInt(process.env.AGENT_MOSS_LLM_RETRIES || String(retryCfg.maxRetries), 10);\n\n // totalTimeout 强制执行:用 AbortController 确保整个 LLM 分析(含所有重试)\n // 在 totalTimeout(默认 90s)后强制中断,防止最坏情况 ~372s 超时。\n const totalTimeoutMs = timeoutCfg.totalTimeout * 1000;\n const abortController = new AbortController();\n const totalTimeoutTimer = setTimeout(() => {\n console.error(`[AgentMoss] totalTimeout (${timeoutCfg.totalTimeout}s) exceeded, aborting all LLM calls`);\n abortController.abort();\n }, totalTimeoutMs);\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n if (abortController.signal.aborted) {\n break;\n }\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: '只输出纯 JSON,不要包含 markdown 标记、代码块或任何其他文字。' },\n { role: 'user', content: prompt },\n ],\n signal: abortController.signal,\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 // 记录 token 用量(step=\"L3_security_judge\")\n try {\n const usage = response.usage;\n const { recordTokenUsage } = await import('./token-stats');\n recordTokenUsage({\n sessionId: 'audit',\n step: 'L3_security_judge',\n model: response.model || config.model,\n promptTokens: usage?.prompt_tokens || 0,\n completionTokens: usage?.completion_tokens || 0,\n totalTokens: usage?.total_tokens || 0,\n });\n } catch { /* token stats optional */ }\n\n clearTimeout(totalTimeoutTimer);\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 // totalTimeout 触发的 AbortError:直接跳出循环,不再重试\n if (abortController.signal.aborted) {\n console.error(`[AgentMoss] LLM analysis aborted by totalTimeout (${timeoutCfg.totalTimeout}s)`);\n break;\n }\n if (attempt < maxRetries) {\n console.error(`[AgentMoss] LLM call failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${retryCfg.retryInterval}s:`, (err as Error).message);\n await new Promise(resolve => setTimeout(resolve, retryCfg.retryInterval * 1000));\n } else {\n clearTimeout(totalTimeoutTimer);\n console.error('[AgentMoss] LLM call failed after all retries:', (err as Error).message);\n throw new Error(`LLM 分析失败 (${maxRetries + 1} 次尝试): ${(err as Error).message}`);\n }\n }\n }\n\n // totalTimeout 超时或 AbortError 导致循环中断\n clearTimeout(totalTimeoutTimer);\n throw new Error(`LLM 分析超时(totalTimeout ${timeoutCfg.totalTimeout}s)`);\n}\n","/**\n * Runtime config — full implementation (mirrors Python runtime_config.py).\n *\n * Runtime JSON: ~/.config/agentmoss/agent_moss_runtime.json\n * (env AGENT_MOSS_RUNTIME_CONFIG_PATH override). Seed from OSProfile +\n * module consts + SKILL_KEYWORD_MAP. mergeConfig on load (preserve user\n * toggles, append builtins, mark removed).\n *\n * Priority: env > runtime JSON > agent_moss_settings > default.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\n// 静态 import(非 require):package.json type=module,require 在 ESM 不可用。\n// 这三个模块不反向 import runtime-config,无循环依赖。\nimport { DANGEROUS_PATTERNS, INJECTION_KEYWORDS } from '../engine/heuristic';\nimport {\n ROOT_SENSITIVE_PATHS, HOME_SENSITIVE_PATHS, CREDENTIAL_PATHS,\n PASSWORD_MODIFY_PATTERNS, USER_DELETION_PATTERNS, INTENT_DEVIATION_PATTERNS,\n} from '../engine/logic-rules';\nimport { SKILL_KEYWORD_MAP } from '../engine/skill-loader';\n\nconst RUNTIME_CONFIG_DIR = join(homedir(), '.config', 'agentmoss');\nconst RUNTIME_CONFIG_PATH = join(RUNTIME_CONFIG_DIR, 'agent_moss_runtime.json');\nconst ENV_RUNTIME_CONFIG_PATH = 'AGENT_MOSS_RUNTIME_CONFIG_PATH';\n\nconst LAYER_DISABLE_ENV: Record<string, string> = {\n L1_heuristic: 'AGENT_MOSS_DISABLE_HEURISTIC',\n L2_logic_rules: 'AGENT_MOSS_DISABLE_LOGIC_RULES',\n L3_llm_analysis: 'AGENT_MOSS_DISABLE_LLM',\n};\n\nexport const DENY_MODE_LABELS: Record<string, string> = {\n deny_write: '仅拦截写入',\n deny_read: '仅拦截读取',\n deny_both: '读写均拦截',\n};\n\n// ==================== Types ====================\n\nexport interface Rule {\n id: string;\n enabled: boolean;\n builtin: boolean;\n source_removed?: boolean;\n pattern?: string;\n risk_level?: string;\n risk_type?: string;\n reason?: string;\n keyword?: string;\n lang?: string;\n path?: string;\n desc?: string;\n deny_mode?: string;\n source_deny_mode?: string;\n credential?: boolean;\n read_only?: boolean;\n skip_l3_on_disabled?: boolean;\n intent_keywords?: string[];\n dangerous_actions?: string[];\n}\n\nexport interface Skill {\n id: string;\n keywords: string[];\n enabled: boolean;\n builtin: boolean;\n}\n\ninterface Category {\n category_enabled?: boolean;\n category_desc?: string;\n rules?: Rule[];\n skills?: Skill[];\n}\n\nexport interface RuntimeConfig {\n version: number;\n layers: { L1_heuristic: boolean; L2_logic_rules: boolean; L3_llm_analysis: boolean };\n L1_rules: Record<string, Category>;\n L2_rules: Record<string, Category>;\n L3_skills: Record<string, Category>;\n}\n\n// ==================== Path / load / save ====================\n\nexport function getRuntimeConfigPath(): string {\n const envPath = process.env[ENV_RUNTIME_CONFIG_PATH];\n if (envPath) return envPath;\n // agent_moss_settings.json fallback omitted in TS (env-only); default path.\n return RUNTIME_CONFIG_PATH;\n}\n\nexport function saveRuntimeConfig(config: RuntimeConfig): void {\n const p = getRuntimeConfigPath();\n const dir = p.substring(0, p.lastIndexOf('/'));\n if (dir && !existsSync(dir)) mkdirSync(dir, { recursive: true });\n writeFileSync(p, JSON.stringify(config, null, 2), 'utf-8');\n}\n\n/** Minimal default (all layers on, empty rule categories). The full\n * profile-driven seed generator (generate_source_defaults equivalent)\n * is deferred to Stage 4 (console backend); for now a missing runtime\n * file yields this minimal config — coordinator's getDisabledL2RulesWithSkipL3\n * returns {} (safe default, no skip_l3 hard constraint). */\nfunction emptyRuntimeConfig(): RuntimeConfig {\n return {\n version: 1,\n layers: { L1_heuristic: true, L2_logic_rules: true, L3_llm_analysis: true },\n L1_rules: {},\n L2_rules: {},\n L3_skills: {},\n };\n}\n\nexport function loadRuntimeConfig(): RuntimeConfig {\n const p = getRuntimeConfigPath();\n if (!existsSync(p)) {\n // 首次:seed + save,与 py load_runtime_config 的 fallback seed 对齐。\n // 不 seed 时 getDisabledL2RulesWithSkipL3 返回 {}(无 skip_l3 约束),\n // 但 Console 需要全量规则展示,所以必须 seed。\n const seeded = mergeConfig({}, generateSourceDefaults());\n try { saveRuntimeConfig(seeded); } catch { /* 只读 fs 时忽略 */ }\n return seeded;\n }\n try {\n const data = JSON.parse(readFileSync(p, 'utf-8'));\n const merged = mergeConfig(data, generateSourceDefaults());\n return {\n version: data.version || 1,\n layers: {\n L1_heuristic: data.layers?.L1_heuristic ?? true,\n L2_logic_rules: data.layers?.L2_logic_rules ?? true,\n L3_llm_analysis: data.layers?.L3_llm_analysis ?? true,\n },\n L1_rules: merged.L1_rules || {},\n L2_rules: merged.L2_rules || {},\n L3_skills: merged.L3_skills || {},\n };\n } catch {\n return emptyRuntimeConfig();\n }\n}\n\n// ==================== Layer toggles ====================\n\n/**\n * Is a layer enabled? Priority: env > runtime JSON > default true.\n *\n * Note: the agent_moss_settings.json fallback (used in Python) is not\n * consulted here — env vars are the primary TS-side override. The runtime\n * JSON is authoritative when env is unset.\n */\nexport function isLayerEnabled(layerKey: string): boolean {\n const disableKey = LAYER_DISABLE_ENV[layerKey];\n if (disableKey && process.env[disableKey] === '1') return false;\n const runtime = loadRuntimeConfig();\n const layers = runtime.layers || {} as RuntimeConfig['layers'];\n if (layerKey in layers) return !!layers[layerKey as keyof typeof layers];\n return true;\n}\n\nexport function getEnvOverrides(): Record<string, {\n env_var: string; env_value: string; overridden: boolean; effect: string;\n}> {\n const overrides: Record<string, any> = {};\n for (const [layerKey, envKey] of Object.entries(LAYER_DISABLE_ENV)) {\n const val = process.env[envKey];\n if (val !== undefined) {\n overrides[layerKey] = {\n env_var: envKey,\n env_value: val,\n overridden: val === '1',\n effect: val === '1' ? 'disabled' : 'no_override',\n };\n }\n }\n return overrides;\n}\n\n// ==================== Rule filtering / queries ====================\n\nexport function filterEnabledRules(rules: Rule[], categoryEnabled: boolean = true): Rule[] {\n if (!categoryEnabled) return [];\n return rules.filter(r => r.enabled !== false);\n}\n\nexport function getEnabledL1CommandPatterns(runtime: RuntimeConfig): { pattern: string; risk_level: string; risk_type: string; reason: string }[] {\n const cat = runtime.L1_rules?.dangerous_commands || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => ({\n pattern: r.pattern || '', risk_level: r.risk_level || '', risk_type: r.risk_type || '', reason: r.reason || '',\n }));\n}\n\nexport function getEnabledL2SensitivePaths(runtime: RuntimeConfig): { path: string; risk_level: string; desc: string; deny_mode: string; credential?: boolean; read_only?: boolean }[] {\n const cat = runtime.L2_rules?.sensitive_path_access || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => {\n const out: any = { path: r.path || '', risk_level: r.risk_level || '', desc: r.desc || '', deny_mode: r.deny_mode || 'deny_write' };\n if (r.credential) out.credential = true;\n if (r.read_only) out.read_only = true;\n return out;\n });\n}\n\nexport function hasRuntimeConfig(): boolean {\n const p = getRuntimeConfigPath();\n if (!existsSync(p)) return false;\n try {\n JSON.parse(readFileSync(p, 'utf-8'));\n return true;\n } catch { return false; }\n}\n\n// ==================== skip_l3 hard constraint ====================\n\n/**\n * L2 rules with enabled=false AND skip_l3_on_disabled=true, grouped by\n * category, returning their key content (path / intent_keywords / pattern).\n * Consumed by coordinator to build skip_l3_hints for the L3 prompt.\n */\nexport function getDisabledL2RulesWithSkipL3(): Record<string, string[]> {\n let runtime: RuntimeConfig;\n try { runtime = loadRuntimeConfig(); }\n catch { return {}; }\n const result: Record<string, string[]> = {};\n const l2 = runtime.L2_rules || {};\n for (const [catName, cat] of Object.entries(l2)) {\n if (!cat.category_enabled) continue;\n const items: string[] = [];\n for (const r of cat.rules || []) {\n if (r.enabled === false && r.skip_l3_on_disabled) {\n if (catName === 'sensitive_path_access') {\n if (r.path) items.push(r.path);\n } else if (catName === 'intent_consistency') {\n items.push(...(r.intent_keywords || []));\n } else if (r.pattern) {\n items.push(r.pattern);\n }\n }\n }\n if (items.length > 0) result[catName] = items;\n }\n return result;\n}\n\n// ==================== Helpers ====================\n\nfunction _slugify(text: string): string {\n return text.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '') || 'x';\n}\n\nfunction _generatePatternId(pattern: string): string {\n return `pat_${_slugify(pattern)}`;\n}\n\n/** 从 credential / read_only 推导 deny_mode(向后兼容)。优先用已有 deny_mode。 */\nfunction _deriveDenyMode(rule: Partial<Rule>): string {\n if (rule.deny_mode) return rule.deny_mode;\n if (rule.credential) return 'deny_both';\n if (rule.read_only) return 'deny_read';\n return 'deny_write';\n}\n\n/** 根据 deny_mode 同步 credential / read_only(保持底层检测逻辑兼容) */\nfunction _syncDenyModeFields(rule: Rule): void {\n const dm = rule.deny_mode || 'deny_write';\n if (dm === 'deny_both') {\n rule.credential = true;\n delete rule.read_only;\n } else if (dm === 'deny_read') {\n delete rule.credential;\n rule.read_only = true;\n } else {\n delete rule.credential;\n delete rule.read_only;\n }\n}\n\n// ==================== Seed (generateSourceDefaults) ====================\n//\n// py 的 generate_source_defaults 从 OSProfile 拿 dangerous_commands / sensitive_paths\n// / intent_deviation_patterns / injection_keywords(运行时按 OS 类型分叉)。\n// TS 不分 OS profile(只 win/linux 用于 os_type 字段,不影响规则集),规则集硬编码\n// 在 heuristic.ts / logic-rules.ts 常量里。所以 TS seed 直接从常量生成,不走 profile。\n\nfunction _l1CommandPatternsToRules(): Rule[] {\n // DANGEROUS_PATTERNS 是 RegExp,seed 时存 source 字符串。\n return DANGEROUS_PATTERNS.map((p) => ({\n id: _generatePatternId(p.pattern instanceof RegExp ? p.pattern.source : p.pattern),\n pattern: p.pattern instanceof RegExp ? p.pattern.source : p.pattern,\n risk_level: p.severity,\n risk_type: p.riskType,\n reason: p.description,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l1InjectionKeywordsToRules(): Rule[] {\n return INJECTION_KEYWORDS.map((kw) => ({\n id: `inj_${_slugify(kw.keyword)}`,\n keyword: kw.keyword,\n risk_level: kw.riskLevel,\n lang: kw.lang || 'en',\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l2SensitivePathsToRules(): Rule[] {\n const all = [...ROOT_SENSITIVE_PATHS, ...HOME_SENSITIVE_PATHS, ...CREDENTIAL_PATHS] as any[];\n return all.map((sp) => {\n const denyMode = _deriveDenyMode({\n deny_mode: sp.deny_mode,\n credential: sp.credential,\n read_only: sp.read_only,\n });\n const rule: Rule = {\n id: `path_${_slugify(sp.path)}`,\n path: sp.path,\n risk_level: sp.riskLevel,\n desc: sp.desc,\n deny_mode: denyMode,\n source_deny_mode: denyMode,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n };\n _syncDenyModeFields(rule);\n return rule;\n });\n}\n\nfunction _l2IntentPatternsToRules(): Rule[] {\n return INTENT_DEVIATION_PATTERNS.map((pat, i) => ({\n id: `intent_${i + 1}_${_slugify(pat.reason.slice(0, 30))}`,\n intent_keywords: pat.intentKeywords,\n dangerous_actions: pat.dangerousActions,\n reason: pat.reason,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l2PasswordPatternsToRules(): Rule[] {\n return PASSWORD_MODIFY_PATTERNS.map((p) => ({\n id: `pw_${_slugify(p.source)}`,\n pattern: p.source,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l2UserDeletionPatternsToRules(): Rule[] {\n return USER_DELETION_PATTERNS.map((p) => ({\n id: `ud_${_slugify(p.source)}`,\n pattern: p.source,\n skip_l3_on_disabled: true,\n enabled: true,\n builtin: true,\n }));\n}\n\nfunction _l3SkillsToRules(): Record<string, Category> {\n const skillCategories: Record<string, string[]> = {\n file_operations: ['file_access_guard', 'script_execution_guard', 'indirect_access_guard'],\n network_security: ['data_exfiltration_guard', 'browser_web_access_guard',\n 'lateral_movement_guard', 'email_operation_guard'],\n persistence_supply_chain: ['persistence_backdoor_guard', 'supply_chain_guard',\n 'skill_installation_guard'],\n intent_and_general: ['intent_deviation_guard', 'general_tool_risk_guard'],\n resource: ['resource_exhaustion_guard'],\n };\n const out: Record<string, Category> = {};\n for (const [cat, ids] of Object.entries(skillCategories)) {\n out[cat] = {\n category_enabled: true,\n category_desc: '',\n skills: ids.map((s: string) => ({\n id: s,\n keywords: SKILL_KEYWORD_MAP[s] || [],\n enabled: true,\n builtin: true,\n })),\n };\n }\n const categorized = new Set<string>(Object.values(skillCategories).flat());\n for (const s of Object.keys(SKILL_KEYWORD_MAP)) {\n if (!categorized.has(s)) {\n (out.intent_and_general ??= { category_enabled: true, category_desc: '', skills: [] })\n .skills!.push({\n id: s, keywords: SKILL_KEYWORD_MAP[s], enabled: true, builtin: true,\n });\n }\n }\n out.user_custom = { category_enabled: true, category_desc: '', skills: [] };\n return out;\n}\n\n/** 从 TS 常量生成 runtime 默认结构(出厂种子)。TS 不走 profile,直接从常量。 */\nexport function generateSourceDefaults(): RuntimeConfig {\n return {\n version: 1,\n layers: { L1_heuristic: true, L2_logic_rules: true, L3_llm_analysis: true },\n L1_rules: {\n dangerous_commands: {\n category_enabled: true,\n category_desc: '危险命令检测(递归删除、全权限设置、提权执行等)',\n rules: _l1CommandPatternsToRules(),\n },\n injection_detection: {\n category_enabled: true,\n category_desc: 'Prompt 注入攻击检测',\n rules: _l1InjectionKeywordsToRules(),\n },\n user_sensitive_actions: { category_enabled: true, category_desc: '用户自定义敏感动作/工具规则', rules: [] },\n user_custom: { category_enabled: true, category_desc: '用户自定义命令规则', rules: [] },\n },\n L2_rules: {\n sensitive_path_access: {\n category_enabled: true,\n category_desc: '敏感路径访问检测',\n rules: _l2SensitivePathsToRules(),\n },\n intent_consistency: {\n category_enabled: true,\n category_desc: '意图一致性检测',\n rules: _l2IntentPatternsToRules(),\n },\n password_modify_consent: {\n category_enabled: true,\n category_desc: '非交互式密码修改授权检测',\n rules: _l2PasswordPatternsToRules(),\n },\n user_deletion_consent: {\n category_enabled: true,\n category_desc: '用户/组删除操作授权检测',\n rules: _l2UserDeletionPatternsToRules(),\n },\n read_before_write: { category_enabled: true, category_desc: 'read_before_write 安全原则检测', rules: [] },\n dangerous_patterns: { category_enabled: true, category_desc: '危险操作模式检测', rules: [] },\n },\n L3_skills: _l3SkillsToRules(),\n };\n}\n\n// ==================== Merge (preserve user toggles) ====================\n\n/** 规则内容指纹(跨 id 变更识别同一规则)。 */\nfunction _ruleFingerprint(rule: Partial<Rule>): string {\n if ((rule.intent_keywords && rule.intent_keywords.length) || (rule.dangerous_actions && rule.dangerous_actions.length)) {\n return JSON.stringify([\n [...(rule.intent_keywords || [])].sort(),\n [...(rule.dangerous_actions || [])].sort(),\n ]);\n }\n if (rule.path) return JSON.stringify([rule.path]);\n if (rule.pattern) return JSON.stringify([rule.pattern]);\n if (rule.keyword) return JSON.stringify([rule.keyword, rule.lang || '']);\n return JSON.stringify([rule.id || '']);\n}\n\n/** 合并 L1/L2 分类与规则(保留用户 enabled/skip_l3/deny_mode,补入新 builtin,标记删除)。 */\nfunction _mergeRuleCategories(userCfg: RuntimeConfig, srcDefaults: RuntimeConfig, layerKey: 'L1_rules' | 'L2_rules'): void {\n const userLayer = (userCfg[layerKey] || (userCfg[layerKey] = {})) as Record<string, Category>;\n const srcLayer = srcDefaults[layerKey] || {};\n for (const [catName, srcCat] of Object.entries(srcLayer)) {\n if (!(catName in userLayer)) {\n userLayer[catName] = srcCat;\n continue;\n }\n const userCat: Category = userLayer[catName];\n if (userCat.category_desc === undefined) userCat.category_desc = srcCat.category_desc || '';\n if (userCat.category_enabled === undefined) userCat.category_enabled = srcCat.category_enabled ?? true;\n const srcRules = srcCat.rules || [];\n const userRules = (userCat.rules || (userCat.rules = []));\n const userByFp = new Map<string, Rule>();\n for (const r of userRules) userByFp.set(_ruleFingerprint(r), r);\n const srcFps = new Set<string>();\n for (const srcR of srcRules) {\n const fp = _ruleFingerprint(srcR);\n srcFps.add(fp);\n if (userByFp.has(fp)) {\n const existing = userByFp.get(fp)!;\n const userEnabled = existing.enabled;\n const userSkipL3 = existing.skip_l3_on_disabled;\n const userDenyMode = existing.deny_mode;\n const userSourceDeny = existing.source_deny_mode;\n Object.keys(existing).forEach(k => delete (existing as any)[k]);\n Object.assign(existing, srcR);\n existing.enabled = userEnabled;\n if (userSkipL3 !== undefined) existing.skip_l3_on_disabled = userSkipL3;\n if (userDenyMode && userSourceDeny && userDenyMode !== userSourceDeny) {\n existing.deny_mode = userDenyMode;\n }\n if (existing.deny_mode) _syncDenyModeFields(existing);\n } else {\n const newR: Rule = { ...srcR, enabled: true };\n userRules.push(newR);\n }\n }\n for (const r of userRules) {\n // builtin 且指纹不在 src 集合 → 源码已删除该规则\n if (r.builtin && !srcFps.has(_ruleFingerprint(r))) {\n r.source_removed = true;\n r.enabled = false;\n }\n }\n if (catName === 'sensitive_path_access') {\n for (const r of userRules) {\n if (!r.deny_mode) r.deny_mode = _deriveDenyMode(r);\n _syncDenyModeFields(r);\n }\n }\n }\n}\n\n/** 合并 L3_skills 分类。新分类整体加入;已有分类补全元字段 + 追加新 builtin skill。 */\nfunction _mergeSkillCategories(userCfg: RuntimeConfig, srcDefaults: RuntimeConfig, layerKey: 'L3_skills'): void {\n const userLayer = (userCfg[layerKey] || (userCfg[layerKey] = {})) as Record<string, Category>;\n const srcLayer = srcDefaults[layerKey] || {};\n for (const [catName, srcCat] of Object.entries(srcLayer)) {\n if (!(catName in userLayer)) {\n userLayer[catName] = srcCat;\n continue;\n }\n const userCat: Category = userLayer[catName];\n if (userCat.category_desc === undefined) userCat.category_desc = srcCat.category_desc || '';\n if (userCat.category_enabled === undefined) userCat.category_enabled = srcCat.category_enabled ?? true;\n const userSkills = (userCat.skills || (userCat.skills = []));\n const existingIds = new Set(userSkills.map(s => s.id));\n for (const srcS of (srcCat.skills || [])) {\n if (!existingIds.has(srcS.id)) userSkills.push({ ...srcS });\n }\n }\n}\n\n/** 合并用户配置与源码默认值。保留用户开关;新增 builtin 补入;源码删除的标记。 */\nexport function mergeConfig(userCfg: Partial<RuntimeConfig>, srcDefaults: RuntimeConfig): RuntimeConfig {\n const cfg = userCfg as RuntimeConfig;\n if (cfg.version === undefined) cfg.version = srcDefaults.version || 1;\n if (!cfg.layers) cfg.layers = {} as RuntimeConfig['layers'];\n for (const [layerKey, defaultVal] of Object.entries(srcDefaults.layers)) {\n if (!(layerKey in cfg.layers)) (cfg.layers as any)[layerKey] = defaultVal;\n }\n _mergeRuleCategories(cfg, srcDefaults, 'L1_rules');\n _mergeRuleCategories(cfg, srcDefaults, 'L2_rules');\n _mergeSkillCategories(cfg, srcDefaults, 'L3_skills');\n return cfg;\n}\n\n// ==================== Query 补齐 ====================\n\nexport function getEnabledL1InjectionKeywords(runtime: RuntimeConfig): { keyword: string; risk_level: string; lang: string }[] {\n const cat = runtime.L1_rules?.injection_detection || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => ({\n keyword: r.keyword || '', risk_level: r.risk_level || '', lang: r.lang || 'en',\n }));\n}\n\nexport function getEnabledL2IntentPatterns(runtime: RuntimeConfig): { intent_keywords: string[]; dangerous_actions: string[]; reason: string }[] {\n const cat = runtime.L2_rules?.intent_consistency || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => ({\n intent_keywords: r.intent_keywords || [], dangerous_actions: r.dangerous_actions || [], reason: r.reason || '',\n }));\n}\n\nexport function getEnabledL2PasswordPatterns(runtime: RuntimeConfig): string[] {\n const cat = runtime.L2_rules?.password_modify_consent || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => r.pattern || '');\n}\n\nexport function getEnabledL2UserDeletionPatterns(runtime: RuntimeConfig): string[] {\n const cat = runtime.L2_rules?.user_deletion_consent || { category_enabled: true, rules: [] };\n return filterEnabledRules(cat.rules || [], cat.category_enabled).map(r => r.pattern || '');\n}\n\nexport function isL2CategoryEnabled(runtime: RuntimeConfig, categoryKey: string): boolean {\n const cat = runtime.L2_rules?.[categoryKey as keyof typeof runtime.L2_rules] as Category | undefined;\n return cat?.category_enabled ?? true;\n}\n\n/** 所有被禁用的 skill id(整分类禁用→该分类所有 skill,或单条 enabled=false) */\nexport function getDisabledSkillIds(runtime: RuntimeConfig): Set<string> {\n const disabled = new Set<string>();\n for (const catData of Object.values(runtime.L3_skills || {})) {\n if (!catData.category_enabled) {\n for (const s of (catData.skills || [])) disabled.add(s.id);\n } else {\n for (const s of (catData.skills || [])) {\n if (s.enabled === false) disabled.add(s.id);\n }\n }\n }\n return disabled;\n}\n\n// ==================== _or_default 回退系列 ====================\n// runtime 规则非空→用 runtime;为空且文件不存在→回退 source defaults;\n// 为空但文件存在(用户主动禁用)→返回空。与 py 语义对齐。\n\nexport function getEnabledL1CommandPatternsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL1CommandPatterns(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l1CommandPatternsToRules();\n return [];\n}\nexport function getEnabledL1InjectionKeywordsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL1InjectionKeywords(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l1InjectionKeywordsToRules();\n return [];\n}\nexport function getEnabledL2SensitivePathsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL2SensitivePaths(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l2SensitivePathsToRules();\n return [];\n}\nexport function getEnabledL2IntentPatternsOrDefault(runtime: RuntimeConfig): Rule[] {\n const enabled = getEnabledL2IntentPatterns(runtime) as unknown as Rule[];\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) return _l2IntentPatternsToRules();\n return [];\n}\nexport function getEnabledL2PasswordPatternsOrDefault(runtime: RuntimeConfig): string[] {\n const enabled = getEnabledL2PasswordPatterns(runtime);\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) {\n return PASSWORD_MODIFY_PATTERNS.map((p) => p.source);\n }\n return [];\n}\nexport function getEnabledL2UserDeletionPatternsOrDefault(runtime: RuntimeConfig): string[] {\n const enabled = getEnabledL2UserDeletionPatterns(runtime);\n if (enabled.length) return enabled;\n if (!hasRuntimeConfig()) {\n return USER_DELETION_PATTERNS.map((p) => p.source);\n }\n return [];\n}\n\n// ==================== CRUD / update ====================\n\nconst SKILL_ID_RE = /^[A-Za-z0-9_-]+$/;\nfunction _validateSkillId(skillId: string): void {\n if (!skillId || !SKILL_ID_RE.test(skillId)) {\n throw new Error(`skill_id '${skillId}' 不合法:只允许字母、数字、下划线和连字符`);\n }\n}\n\nexport function updateLayerEnabled(layerKey: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n (runtime.layers as any)[layerKey] = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateRuleEnabled(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const r of (runtime[layer]?.[category]?.rules || [])) {\n if (r.id === ruleId) { r.enabled = enabled; break; }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateRuleDenyMode(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string, denyMode: string): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const r of (runtime[layer]?.[category]?.rules || [])) {\n if (r.id === ruleId) { r.deny_mode = denyMode; _syncDenyModeFields(r); break; }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateRuleSkipL3(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string, skipL3: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const r of (runtime[layer]?.[category]?.rules || [])) {\n if (r.id === ruleId) { r.skip_l3_on_disabled = skipL3; break; }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateCategoryEnabled(layer: 'L1_rules' | 'L2_rules', category: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime[layer]?.[category];\n if (cat) cat.category_enabled = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function addCustomRule(layer: 'L1_rules' | 'L2_rules', category: string, rule: Partial<Rule>): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const layerObj = runtime[layer] || (runtime[layer] = {} as Record<string, Category>);\n const cat = layerObj[category] || (layerObj[category] = { category_enabled: true, category_desc: '', rules: [] });\n const rules = cat.rules || (cat.rules = []);\n const newRule: Rule = { ...rule, builtin: false, enabled: true } as Rule;\n if (!newRule.id) {\n newRule.id = `custom_${Date.now()}_${_slugify(JSON.stringify(rule).slice(0, 30))}`;\n }\n if (newRule.deny_mode) _syncDenyModeFields(newRule);\n rules.push(newRule);\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function deleteCustomRule(layer: 'L1_rules' | 'L2_rules', category: string, ruleId: string): RuntimeConfig | null {\n const runtime = loadRuntimeConfig();\n const rules = runtime[layer]?.[category]?.rules || [];\n const idx = rules.findIndex(r => r.id === ruleId);\n if (idx >= 0) {\n if (rules[idx].builtin) return null; // builtin 不允许删\n rules.splice(idx, 1);\n saveRuntimeConfig(runtime);\n }\n return runtime;\n}\n\nexport function addCustomSkill(skillId: string, category: string, keywords: string[], content: string): RuntimeConfig {\n _validateSkillId(skillId);\n const runtime = loadRuntimeConfig();\n const skillsDir = join(RUNTIME_CONFIG_DIR, 'agent_moss_skills');\n try { mkdirSync(skillsDir, { recursive: true }); } catch { /* 已存在 */ }\n writeFileSync(join(skillsDir, `${skillId}.md`), content, 'utf-8');\n const l3 = runtime.L3_skills || (runtime.L3_skills = {});\n const cat = l3[category] || (l3[category] = { category_enabled: true, category_desc: '', skills: [] });\n (cat.skills || (cat.skills = [])).push({ id: skillId, keywords, enabled: true, builtin: false });\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function deleteCustomSkill(skillId: string, category: string): RuntimeConfig | null {\n _validateSkillId(skillId);\n const runtime = loadRuntimeConfig();\n const skills = runtime.L3_skills?.[category]?.skills || [];\n const idx = skills.findIndex(s => s.id === skillId);\n if (idx >= 0) {\n if (skills[idx].builtin) return null;\n skills.splice(idx, 1);\n const skillPath = join(RUNTIME_CONFIG_DIR, 'agent_moss_skills', `${skillId}.md`);\n try { if (existsSync(skillPath)) unlinkSync(skillPath); } catch { /* ignore */ }\n saveRuntimeConfig(runtime);\n }\n return runtime;\n}\n\nexport function updateSkillEnabled(skillId: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n for (const catData of Object.values(runtime.L3_skills || {})) {\n for (const s of (catData.skills || [])) {\n if (s.id === skillId) { s.enabled = enabled; break; }\n }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function updateSkillCategoryEnabled(category: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.L3_skills?.[category];\n if (cat) cat.category_enabled = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function getProfileOrDetect(): null {\n // TS 不走 OSProfile(规则集硬编码常量),此函数仅为 py API 对齐保留,返回 null。\n return null;\n}\n","import { SecurityJudgment } from './types';\nimport { runHeuristicCheck, isInlineScriptCommand, DANGEROUS_PATTERNS } from './heuristic';\nimport { runLogicCheck } from './logic-rules';\nimport { analyzeInlineScript, isLiteralTextCommand } from './inline-analyzer';\nimport { runLLMAnalysis } from './llm-analyzer';\nimport { analyzeScriptContent as analyzeScriptChain, formatScriptChainForPrompt } from './script-content-analyzer';\nimport { isHeuristicEnabled, isLogicRulesEnabled, isLLMAvailable } from '../config';\nimport { getAgentExtensions } from '../agents';\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 /** 调用方 agent 标识(如 'xiaoo' / 'opencode' / 'opendesk')。空 = 通用模式。 */\n agentId: string;\n /** 可选的 per-request LLM 配置覆盖(由 OpenDesk 按当前会话模型传入) */\n llmConfig?: { baseUrl: string; apiKey: string; model: string; provider?: string };\n /** 可选的 per-request LLM prompt 日志路径(来自调用方 env,per-request 注入。\n * 跟 llmConfig 同理:调用方子进程有 AGENT_MOSS_LOG_PATH env 但服务进程不一定有,\n * 通过 metadata 注入让服务端写 [LLM_PROMPT] 日志,对齐 py _log_prompt) */\n llmLogPath?: 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 白名单(通用 baseline,agent_ext.builtin_safe_skills 会追加)。\n * 测试可 import 此常量直接断言\"无 agentId 时白名单不含某 skill\",避免走 L3\n * LLM 调用导致测试脆弱(依赖 LLM 401 fail_open 兜底)。 */\nexport const TRUSTED_SKILLS_BASE = new Set<string>([]);\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 假阳性防护:不立即拦截,交 inline_analyzer 静态判定\n // 因为字符串字面量中的敏感路径(如 '/etc/shadow')不应被正则误拦截\n const isInlineScriptCmd = isInlineScriptCommand(input.aNext.actionDetail.toLowerCase());\n const isLiteralTextCmd = isLiteralTextCommand(input.aNext.actionDetail.toLowerCase());\n if (heuristicResult && !heuristicResult.allowed) {\n const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && heuristicResult.riskType === 'file_access';\n if (!skipInlineFileAccess) {\n return heuristicResult;\n }\n }\n\n // ===== L1.5: Script content pre-scan (recursive chain + L1 reuse) =====\n // For bash actions invoking a script, recursively track the call chain,\n // preprocess, and scan each node with runHeuristicCheck (L1). high/critical\n // deny directly (layer \"1.1-script\"). Catches \"rm -rf /\" inside a script\n // whose entry command is just \"bash deploy.sh\". Reduces L3 token use.\n let scriptChain: ReturnType<typeof analyzeScriptChain> | null = null;\n if (input.aNext.actionType.toLowerCase() === 'bash') {\n scriptChain = analyzeScriptChain(input);\n if (scriptChain.nodes.length > 0) {\n for (const node of scriptChain.nodes) {\n if (node.l1Hit && (node.l1RiskLevel === 'high' || node.l1RiskLevel === 'critical')) {\n return {\n allowed: false,\n reason: `脚本内容包含危险操作: ${node.l1Reason} (文件: ${node.scriptPath}, 深度: ${node.depth})`,\n riskLevel: node.l1RiskLevel as SecurityJudgment['riskLevel'],\n riskType: node.l1RiskType,\n confidence: 90,\n source: 'heuristic_script_scan',\n violatedLayers: ['1.1-script'],\n };\n }\n }\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 直接放行(通用 baseline + agent_ext.builtin_safe_skills)\n const agentExt = getAgentExtensions(input.agentId);\n const trustedSkills = new Set<string>(TRUSTED_SKILLS_BASE);\n if (agentExt?.builtin_safe_skills) {\n for (const s of agentExt.builtin_safe_skills) trustedSkills.add(s);\n }\n if (actionType === 'skill' && trustedSkills.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 // 凭据文件:无论读写、无论是否 inline,都直接拒绝(isCredential 来自 profile 标记)\n const isCredentialPath = !!logicResult.isCredential;\n // 内联脚本/文本输出命令:走静态语义判定,区分\"文本字面量\"vs\"真实读写\"。\n // 即使是凭据路径(如 deny_both 的 /etc/shadow),只要它是字符串字面量\n // (python -c \"print('/etc/shadow')\"),inline_analyzer 判 Allow 时应放行——\n // 因为并未真实读取该文件。actionable=false(提取不到代码)时才回退到\n // 凭据/敏感路径的硬拒绝。\n const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && logicResult.riskType === 'sensitive_path_access';\n if (skipInlineFileAccess) {\n const inlineJudgment = analyzeInlineScript(input.aNext.actionDetail);\n if (inlineJudgment.actionable) {\n if (!inlineJudgment.allowed) {\n return {\n allowed: false,\n reason: inlineJudgment.reason,\n riskLevel: inlineJudgment.riskLevel as SecurityJudgment['riskLevel'],\n riskType: inlineJudgment.riskType,\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: ['1.2'],\n };\n }\n // 字面量 → Allow,不再走 Layer 3\n return {\n allowed: true,\n reason: inlineJudgment.reason,\n riskLevel: inlineJudgment.riskLevel as SecurityJudgment['riskLevel'],\n riskType: inlineJudgment.riskType,\n confidence: 90,\n source: 'logic_rule',\n violatedLayers: [],\n };\n }\n // actionable=false(提取不到代码)→ 回退原逻辑:high/critical 直接 Deny\n }\n if ((logicResult.riskLevel === 'high' || logicResult.riskLevel === 'critical') && (!skipInlineFileAccess || isCredentialPath)) {\n return logicResult;\n }\n // medium/low 风险:不直接拦截,走层3 LLM 语义判断\n }\n\n // ===== L2.5: Script content L2 scan (per-node sensitive path / dangerous\n // pattern / intent reuse on preprocessed content). high/critical deny\n // directly (layer \"1.2-script\"). =====\n if (scriptChain && scriptChain.nodes.length > 0 && isLogicRulesEnabled()) {\n for (const node of scriptChain.nodes) {\n if (node.error || !node.preprocessedContent) continue;\n if (node.l1RiskLevel === 'critical') break;\n if (node.l2Hit && (node.l2RiskLevel === 'high' || node.l2RiskLevel === 'critical')) {\n return {\n allowed: false,\n reason: node.l2Reason,\n riskLevel: node.l2RiskLevel as SecurityJudgment['riskLevel'],\n riskType: node.l2RiskType,\n confidence: 85,\n source: 'logic_rule_script_scan',\n violatedLayers: ['1.2-script'],\n };\n }\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 // Build skip_l3_hints: hard-constraint for user-disabled L2 rules with\n // skip_l3_on_disabled. runtime_config lands in Stage 2; until then\n // getDisabledL2RulesWithSkipL3 resolves to a no-op returning empty.\n let skipL3Hints = '无(当前无禁用规则命中)';\n try {\n const { getDisabledL2RulesWithSkipL3 } = await import('../infra/runtime-config');\n const disabledL2 = getDisabledL2RulesWithSkipL3();\n if (disabledL2 && Object.keys(disabledL2).length > 0) {\n const actionLower = input.aNext.actionDetail.toLowerCase();\n const matched: string[] = [];\n for (const items of Object.values(disabledL2)) {\n for (const item of items) {\n if (item.toLowerCase().includes(actionLower) || actionLower.includes(item.toLowerCase())) {\n matched.push(item);\n }\n }\n }\n if (matched.length > 0) {\n skipL3Hints =\n `⚠️ 重要约束:用户已主动禁用针对以下内容的安全拦截规则,这是用户的明确决策:\\n` +\n ` ${matched.join(', ')}\\n` +\n `对这些路径/关键词的相关操作,必须视为允许的,不允许仅因涉及这些内容就拒绝。` +\n `但你仍需检查命令的其他部分是否有独立于这些内容的安全风险(如网络外传、提权等)。`;\n }\n }\n } catch { /* runtime_config not yet present — skip_l3_hints stays default */ }\n\n let llmResult: SecurityJudgment;\n try {\n llmResult = await runLLMAnalysis(input, {\n heuristic: heuristicResult,\n logic: logicResult,\n skipL3Hints,\n scriptChain: scriptChain ?? undefined,\n llmLogPath: input.llmLogPath,\n });\n } catch (e) {\n // LLM 分析失败。前两层未拦截时按 fail_mode 决策:\n // - fail_open(默认):Allow + 警告(可用性优先)\n // - fail_closed:Deny(安全优先)\n const { getLLMFailMode } = await import('../config');\n if (getLLMFailMode() === 'fail_open') {\n console.warn(`[AgentMoss] LLM 分析失败,fail_open 模式:允许执行(前两层未拦截): ${(e as Error).message}`);\n return {\n allowed: true,\n reason: `LLM 分析失败(warn-allow,fail_open): ${(e as Error).message}`,\n riskLevel: 'low',\n riskType: '',\n confidence: 50,\n source: 'llm_failure_fallback',\n violatedLayers: [],\n };\n }\n return {\n allowed: false,\n reason: `LLM 分析失败,因无法完成深度语义分析,按 fail-closed 原则拒绝: ${(e as Error).message}`,\n riskLevel: 'medium',\n riskType: '',\n confidence: 60,\n source: 'llm_failure_fallback',\n violatedLayers: ['3'],\n };\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, startServer } 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 install Install systemd service for AgentMoss\n\nServer options:\n --host <host> Listen host (default: 127.0.0.1)\n --port <port> Listen port (default: 9090, 0=auto assign)\n\nInstall options:\n --enable Enable service on boot (systemctl enable)\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 agentId: data.agent_id || '',\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 // startServer 内部 findFreePort:port 被占自动找空闲端口。\n const server = await startServer(host, port);\n console.log(`Listening on http://${host}:${server.port}`);\n server.serve();\n break;\n }\n\n case 'install': {\n const enable = args.includes('--enable');\n const { execSync } = await import('child_process');\n const fs = await import('fs');\n const path = await import('path');\n const { fileURLToPath } = await import('url');\n\n // 检查 root 权限\n if (process.getuid?.() !== 0) {\n const sudoArgs = ['sudo', process.execPath, ...process.argv.slice(1)];\n if (enable) sudoArgs.push('--enable');\n console.log('需要 root 权限安装 systemd service,正在通过 sudo 重新执行...');\n execSync(sudoArgs.join(' '), { stdio: 'inherit' });\n process.exit(0);\n }\n\n // 找到 service 文件(dist/data/ 或 src/data/)\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n let srcPath = path.join(__dirname, 'data', 'agent_moss.service');\n if (!fs.existsSync(srcPath)) {\n // 开发模式回退\n srcPath = path.join(__dirname, '..', 'src', 'data', 'agent_moss.service');\n }\n if (!fs.existsSync(srcPath)) {\n console.error('错误:找不到 agent_moss.service 模板文件');\n process.exit(1);\n }\n\n // 找到 agent-moss 命令路径\n const which = execSync('which agent-moss 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n const binPath = which || `${process.execPath} ${path.join(__dirname, 'cli.js')}`;\n\n // 读取模板,替换 ExecStart\n let content = fs.readFileSync(srcPath, 'utf-8');\n content = content.replace('__AGENT_MOSS_BIN__', binPath);\n\n // 写入 /etc/systemd/system/\n const dst = '/etc/systemd/system/agent_moss.service';\n fs.writeFileSync(dst, content, 'utf-8');\n fs.chmodSync(dst, 0o644);\n console.log(`✅ 已安装 systemd service: ${dst}`);\n\n // daemon-reload\n execSync('systemctl daemon-reload', { stdio: 'inherit' });\n console.log('✅ systemctl daemon-reload 完成');\n\n // 可选 enable\n if (enable) {\n execSync('systemctl enable agent_moss', { stdio: 'inherit' });\n console.log('✅ systemctl enable agent_moss 完成');\n }\n\n console.log('\\n启动服务: sudo systemctl start agent_moss');\n console.log('查看状态: sudo systemctl status agent_moss');\n console.log('查看日志: journalctl -u agent_moss -f');\n break;\n }\n\n case 'status': {\n const http = await import('http');\n const { execSync } = await import('child_process');\n\n // systemd 状态\n let systemdInfo = '';\n try {\n const out = execSync('systemctl is-active agent_moss 2>/dev/null || true', { encoding: 'utf-8' }).trim();\n if (out === 'active') {\n const show = execSync('systemctl show agent_moss --property=MainPID,ActiveEnterTimestamp,ExecStart 2>/dev/null || true', { encoding: 'utf-8' });\n for (const line of show.trim().split('\\n')) {\n const [key, ...vals] = line.split('=');\n const val = vals.join('=');\n if (key === 'MainPID' && val && val !== '0') systemdInfo += ` PID: ${val}\\n`;\n else if (key === 'ActiveEnterTimestamp' && val) systemdInfo += ` 启动时间: ${val}\\n`;\n else if (key === 'ExecStart' && val) systemdInfo += ` 启动命令: ${val}\\n`;\n }\n if (!systemdInfo) systemdInfo = ' Systemd: active\\n';\n }\n } catch {}\n\n // 探测端口\n let foundPort = 0;\n let version = '';\n for (let port = 9090; port <= 9095; port++) {\n try {\n const data = await new Promise<any>((resolve, reject) => {\n const req = http.get(`http://127.0.0.1:${port}/api/v1/health`, { timeout: 2000 }, (res) => {\n let body = '';\n res.on('data', (chunk: string) => body += chunk);\n res.on('end', () => { try { resolve(JSON.parse(body)); } catch { reject(); } });\n });\n req.on('error', reject);\n });\n if (data.status === 'healthy') {\n foundPort = port;\n version = data.version || '';\n break;\n }\n } catch {}\n }\n\n if (foundPort) {\n console.log(`✅ AgentMoss 服务运行中`);\n console.log(` 版本: ${version || '?'}`);\n console.log(` 端口: ${foundPort}`);\n console.log(` Console: http://127.0.0.1:${foundPort}/console`);\n console.log(` Health: http://127.0.0.1:${foundPort}/api/v1/health`);\n if (systemdInfo) {\n process.stdout.write(systemdInfo);\n } else {\n console.log(` Systemd: 未注册(运行 agent-moss install --enable 安装)`);\n }\n // 获取 L3 状态\n try {\n const data = await new Promise<any>((resolve, reject) => {\n const req = http.get(`http://127.0.0.1:${foundPort}/console/api/config`, { timeout: 3000 }, (res) => {\n let body = '';\n res.on('data', (chunk: string) => body += chunk);\n res.on('end', () => { try { resolve(JSON.parse(body)); } catch { reject(); } });\n });\n req.on('error', reject);\n });\n const layers = data.layers || {};\n const l1 = layers.L1_heuristic !== false ? '✅ 启用' : '❌ 禁用';\n const l2 = layers.L2_logic_rules !== false ? '✅ 启用' : '❌ 禁用';\n const l3 = layers.L3_llm_analysis !== false ? '✅ 启用' : '❌ 禁用';\n console.log(` L1 静态检测: ${l1}`);\n console.log(` L2 逻辑规则: ${l2}`);\n console.log(` L3 LLM 分析: ${l3}`);\n } catch {}\n console.log();\n console.log(' 启停命令:');\n console.log(' systemctl start agent_moss 启动');\n console.log(' systemctl stop agent_moss 停止');\n console.log(' systemctl restart agent_moss 重启');\n console.log(' systemctl status agent_moss 状态');\n console.log(' journalctl -u agent_moss -f 日志');\n } else {\n console.log(`❌ AgentMoss 服务未运行`);\n if (systemdInfo) {\n console.log(` Systemd: active 但端口探测不到`);\n console.log(` 检查日志:journalctl -u agent_moss -n 20 --no-pager`);\n } else {\n console.log(` 启动方式:`);\n console.log(` systemctl start agent_moss (systemd)`);\n console.log(` agent-moss server (前台)`);\n }\n process.exit(1);\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 net from 'node:net';\nimport { analyzeRoute, healthRoute } from './routes';\nimport { createConsoleRouter } from './console';\n\nexport function createApp(): Hono {\n const app = new Hono();\n\n // Middleware\n app.use('*', cors({ origin: '*', allowMethods: ['GET', 'POST', 'PUT', 'DELETE', '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 // Policy Console(浏览器策略管控台,挂载在 /console 前缀)\n app.route('/console', createConsoleRouter());\n // /console/ → /console(hono route 挂载后带尾斜杠匹配行为不一致,加重定向兼容)\n app.get('/console/', (c) => c.redirect('/console'));\n\n return app;\n}\n\n/**\n * 从 startPort 开始找第一个可用端口(照搬 OpenDesk findFreePort 策略)。\n * 用 net.createServer().listen 试端口,成功立刻 close 返回该端口;全占 fallback\n * 到 startPort(让 hono 自己报错,不静默换到离谱端口)。\n *\n * 为什么需要:默认 9090 被占时服务起不来、xiaoO 全 fail-closed。预探测找空闲端口,\n * 配合消费方探测兜底(bridge.ts probeAgentMossUrl),保证服务总能起、消费方能连上。\n */\nexport async function findFreePort(\n startPort: number,\n host: string = '127.0.0.1',\n scan: number = 100,\n): Promise<number> {\n for (let port = startPort; port < startPort + scan; port++) {\n const free = await new Promise<boolean>((resolve) => {\n const server = net.createServer();\n server.listen(port, host, () => {\n server.close(() => resolve(true));\n });\n server.on('error', () => resolve(false));\n });\n if (free) {\n if (port !== startPort) {\n console.warn(`[AgentMoss] Port ${startPort} in use, using ${port} instead`);\n }\n return port;\n }\n }\n return startPort; // fallback\n}\n\nexport async function startServer(\n host = '127.0.0.1',\n port = 9090,\n): Promise<{ serve: () => void; port: number }> {\n const actualPort = await findFreePort(port, host);\n const app = createApp();\n return {\n port: actualPort,\n serve: () => {\n console.log(`AgentMoss HTTP server on ${host}:${actualPort}`);\n // @hono/node-server 动态 import(ESM 下 require 不可用)\n import('@hono/node-server').then(({ serve: honoServe }) => {\n honoServe({ fetch: app.fetch, hostname: host, port: actualPort });\n });\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 agentId: req.agent_id,\n llmConfig: (req.metadata as any)?.llm_config,\n llmLogPath: (req.metadata as any)?.llm_log_path,\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 agent_id: z.string().default('').describe(\"Caller agent identifier, e.g. 'xiaoo' / 'opencode' / 'opendesk'. Empty = generic mode (no agent-specific rules).\"),\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","/** Policy Console 子应用(挂载到主 app 的 /console 前缀)。 */\nexport { createConsoleRouter } from './router';\n","/**\n * Policy Console Hono 路由 — 挂载到主 app 的 /console 前缀下。\n * 1:1 对齐 Python console/router.py 的 23 路由契约(前端 SPA 共用)。\n *\n * 复用 infra.runtime-config + engine.token-stats。Bearer 认证\n * (AGENT_MOSS_CONSOLE_TOKEN 未设则本机免认证,iframe 嵌入场景)。\n */\nimport { Hono } from 'hono';\nimport { readFileSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport {\n loadRuntimeConfig, saveRuntimeConfig, updateLayerEnabled,\n updateRuleEnabled, updateRuleDenyMode, updateRuleSkipL3,\n updateCategoryEnabled, addCustomRule, deleteCustomRule,\n addCustomSkill, deleteCustomSkill, updateSkillEnabled,\n updateSkillCategoryEnabled, getEnvOverrides, generateSourceDefaults,\n getRuntimeConfigPath,\n} from '../infra/runtime-config';\nimport {\n getTokenStats, getRecentRecords, getTokenTrend, resetTokenStats,\n} from '../engine/token-stats';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst STATIC_DIR = join(__dirname, 'static');\n\nconst CONSOLE_TOKEN_ENV = 'AGENT_MOSS_CONSOLE_TOKEN';\n\nfunction getConsoleToken(): string {\n return process.env[CONSOLE_TOKEN_ENV] || '';\n}\n\n/** 验证 Bearer token。未配置 token 时本机访问免认证(iframe 嵌入场景)。 */\nfunction verifyAuth(req: Request): boolean {\n const token = getConsoleToken();\n if (!token) return true;\n const auth = req.headers.get('Authorization') || '';\n if (auth.startsWith('Bearer ')) return auth.slice(7) === token;\n return false;\n}\n\n/** 鉴权中间件:失败返 401。 */\nfunction authMiddleware() {\n return async (c: any, next: any) => {\n if (!verifyAuth(c.req.raw)) {\n return c.json({ error: 'Unauthorized: invalid or missing Bearer token' }, 401);\n }\n await next();\n };\n}\n\nexport function createConsoleRouter(): Hono {\n const console = new Hono();\n console.use('/api/*', authMiddleware());\n\n // ==================== SPA ====================\n // /console 和 /console/ 都返回 SPA(hono route 挂载后两者匹配行为不同,都兜住)\n const serveIndex = (c: any) => {\n const indexFile = join(STATIC_DIR, 'index.html');\n if (existsSync(indexFile)) {\n return c.html(readFileSync(indexFile, 'utf-8'));\n }\n return c.html('<h1>AgentMoss Policy Console</h1><p>Frontend not built. Use /console/api/* endpoints.</p>');\n };\n console.get('/', serveIndex);\n console.get('', serveIndex);\n\n // ==================== 层级管理 ====================\n console.get('/api/layers', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ layers: rc.layers });\n });\n\n console.put('/api/layers', async (c) => {\n const body = await c.req.json();\n const rc = updateLayerEnabled(body.layer_key, body.enabled);\n return c.json({ layers: rc.layers });\n });\n\n // ==================== 规则管理 ====================\n console.get('/api/rules', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/rules/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateRuleEnabled(b.layer, b.category, b.rule_id, b.enabled);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/rules/deny_mode', async (c) => {\n const b = await c.req.json();\n const rc = updateRuleDenyMode(b.layer, b.category, b.rule_id, b.deny_mode);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/rules/skip_l3', async (c) => {\n const b = await c.req.json();\n const rc = updateRuleSkipL3(b.layer, b.category, b.rule_id, b.skip_l3_on_disabled);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.put('/api/categories/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateCategoryEnabled(b.layer, b.category, b.enabled);\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.post('/api/rules', async (c) => {\n const b = await c.req.json();\n const rc = addCustomRule(b.layer, b.category, {\n pattern: b.pattern, risk_level: b.risk_level, risk_type: b.risk_type,\n reason: b.reason, keyword: b.keyword, lang: b.lang,\n path: b.path, desc: b.desc, credential: b.credential, deny_mode: b.deny_mode,\n });\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n console.delete('/api/rules', async (c) => {\n const b = await c.req.json();\n deleteCustomRule(b.layer, b.category, b.rule_id);\n const rc = loadRuntimeConfig();\n return c.json({ L1_rules: rc.L1_rules, L2_rules: rc.L2_rules });\n });\n\n // ==================== Skill 管理 ====================\n console.get('/api/skills', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.put('/api/skills/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateSkillEnabled(b.skill_id, b.enabled);\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.put('/api/skill-categories/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateSkillCategoryEnabled(b.category, b.enabled);\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.post('/api/skills', async (c) => {\n const b = await c.req.json();\n const rc = addCustomSkill(b.skill_id, b.category || 'user_custom', b.keywords || [], b.content);\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.delete('/api/skills', async (c) => {\n const b = await c.req.json();\n deleteCustomSkill(b.skill_id, b.category);\n const rc = loadRuntimeConfig();\n return c.json({ L3_skills: rc.L3_skills });\n });\n\n console.get('/api/skills/:skill_id/content', async (c) => {\n const skillId = c.req.param('skill_id');\n if (!/^[A-Za-z0-9_-]+$/.test(skillId)) {\n return c.json({ error: 'invalid skill_id' }, 400);\n }\n const skillPath = join(dirname(getRuntimeConfigPath()), 'agent_moss_skills', `${skillId}.md`);\n if (!existsSync(skillPath)) {\n // fallback 到 builtin skill 目录\n const builtinPath = join(__dirname, '..', '..', 'agent_moss', 'skills', `${skillId}.md`);\n if (existsSync(builtinPath)) return c.text(readFileSync(builtinPath, 'utf-8'));\n return c.json({ error: 'skill not found' }, 404);\n }\n return c.text(readFileSync(skillPath, 'utf-8'));\n });\n\n // ==================== 配置 / env / reset ====================\n console.get('/api/config', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ config: rc, config_path: getRuntimeConfigPath() });\n });\n\n console.get('/api/env-overrides', (c) => {\n return c.json({ overrides: getEnvOverrides() });\n });\n\n console.post('/api/reset', (c) => {\n const defaults = generateSourceDefaults();\n saveRuntimeConfig(defaults);\n return c.json({ config: defaults });\n });\n\n // ==================== Token stats ====================\n console.get('/api/token-stats', (c) => {\n const days = parseInt(c.req.query('days') || '7', 10);\n return c.json(getTokenStats(days));\n });\n\n console.get('/api/token-stats/recent', (c) => {\n const limit = parseInt(c.req.query('limit') || '20', 10);\n return c.json({ records: getRecentRecords(limit) });\n });\n\n console.get('/api/token-stats/trend', (c) => {\n const days = parseInt(c.req.query('days') || '7', 10);\n return c.json(getTokenTrend(days));\n });\n\n console.post('/api/token-stats/reset', (c) => {\n resetTokenStats();\n return c.json({ reset: true });\n });\n\n return console;\n}\n"],"mappings":"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","names":["path","fileURLToPath","__filename","__dirname","fs","path","READ_KEYWORDS","WRITE_KEYWORDS","readFileSync","readdirSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","readFileSync","existsSync","resolve","join","dirname","path","scanScriptForKeywords","SUSPICIOUS_PATTERNS","assessKeywordCombinationRisk","KEYWORD_COMBINATION_RISKS","SINGLE_KEYWORD_RISKS","LEVEL_ORDER","extractScriptPath","SCRIPT_EXEC_PATTERNS","readScriptContent","node","analyzeScriptContent","parts","readFileSync","existsSync","join","homedir","recordTokenUsage","resolve","readFileSync","writeFileSync","existsSync","mkdirSync","unlinkSync","join","homedir","main","analyzeScriptContent","getDisabledL2RulesWithSkipL3","getLLMFailMode","Hono","require","fs","readFileSync","existsSync","join","dirname","fileURLToPath","__dirname","console","Hono","resolve","fs","path","runAnalysis","fileURLToPath","__filename","__dirname","version","resolve"]}
|