@kenhkl/agent-moss 0.11.3 → 0.11.4

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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/infra/paths.ts","../src/config.ts","../src/engine/inline-analyzer.ts","../src/engine/logic-rules.ts","../src/engine/skill-loader.ts","../src/infra/runtime-config.ts","../src/agents/index.ts","../src/engine/heuristic.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/engine/coordinator.ts","../node_modules/better-sqlite3/lib/util.js","../node_modules/better-sqlite3/lib/sqlite-error.js","../node_modules/file-uri-to-path/index.js","../node_modules/bindings/bindings.js","../node_modules/better-sqlite3/lib/methods/wrappers.js","../node_modules/better-sqlite3/lib/methods/transaction.js","../node_modules/better-sqlite3/lib/methods/pragma.js","../node_modules/better-sqlite3/lib/methods/backup.js","../node_modules/better-sqlite3/lib/methods/serialize.js","../node_modules/better-sqlite3/lib/methods/function.js","../node_modules/better-sqlite3/lib/methods/aggregate.js","../node_modules/better-sqlite3/lib/methods/table.js","../node_modules/better-sqlite3/lib/methods/inspect.js","../node_modules/better-sqlite3/lib/database.js","../node_modules/better-sqlite3/lib/index.js","../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","/**\n * Path resolution — unified data root + multi-instance (instance) isolation.\n *\n * Mirrors Python agent_moss/infra/paths.py.\n *\n * Solves two problems:\n * 1. Data-owner user directory: even when the service runs as root/systemd\n * (started via `sudo systemctl`), AGENT_MOSS_DATA_DIR can point it at the\n * \"current user\"'s data dir, so config / runtime / token all land in that\n * user's directory instead of root's /root. Falls back to\n * ~/.config/agentmoss (legacy behavior) when unset.\n *\n * 2. Token isolation by instance: services started by different agents\n * (AGENT_MOSS_INSTANCE) don't share token-usage files. With an instance,\n * tokens go to <data_root>/<instance>/agent_moss_token_stats.json; without\n * one, to <data_root>/agent_moss_token_stats.json (default location).\n *\n * config / runtime are NOT split by instance (rules/config are shared); they\n * only follow the data root.\n */\n\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { readFileSync } from 'fs';\n\nconst ENV_DATA_ROOT = 'AGENT_MOSS_DATA_DIR';\nconst ENV_INSTANCE = 'AGENT_MOSS_INSTANCE';\n\nconst DEFAULT_DATA_ROOT = join(homedir(), '.config', 'agentmoss');\n\n/** True when the process runs as root (systemd `sudo systemctl`). */\nexport function isRoot(): boolean {\n const getuid = (process as any).getuid;\n return typeof getuid === 'function' && getuid() === 0;\n}\n\n/** Resolve the \"real user\"'s home when running as root.\n * Priority: SUDO_USER (sudo invoker) > LOGNAME/USER (login user) >\n * first UID>=1000 ordinary user in /etc/passwd. Returns null if none found. */\nexport function resolveOwnerHome(): string | null {\n for (const name of [process.env.SUDO_USER, process.env.LOGNAME, process.env.USER]) {\n if (name && name !== 'root' && name !== '') {\n const home = homeOf(name);\n if (home) return home;\n }\n }\n // /etc/passwd fallback: first UID>=1000 ordinary user\n try {\n const passwd = readFileSync('/etc/passwd', 'utf-8');\n for (const line of passwd.split('\\n')) {\n if (!line || line.startsWith('#')) continue;\n const parts = line.split(':');\n if (parts.length < 6) continue;\n const uid = parseInt(parts[2], 10);\n const name = parts[0];\n if (uid >= 1000 && name && !name.startsWith('_')) {\n return parts[5];\n }\n }\n } catch { /* ignore */ }\n return null;\n}\n\nfunction homeOf(name: string): string | null {\n try {\n const passwd = readFileSync('/etc/passwd', 'utf-8');\n for (const line of passwd.split('\\n')) {\n if (!line || line.startsWith('#')) continue;\n const parts = line.split(':');\n if (parts.length >= 6 && parts[0] === name) {\n return parts[5];\n }\n }\n } catch { /* ignore */ }\n return null;\n}\n\n/** Data root directory.\n * Priority: env AGENT_MOSS_DATA_DIR > ~/.config/agentmoss.\n * BUT when running as root (any `sudo systemctl` service), automatically\n * redirects to the real user's dir so config/runtime/token land there\n * instead of /root. */\nexport function getDataRoot(): string {\n const envPath = process.env[ENV_DATA_ROOT];\n if (envPath) return envPath;\n if (isRoot()) {\n const ownerHome = resolveOwnerHome();\n if (ownerHome) {\n return join(ownerHome, '.config', 'agentmoss');\n }\n }\n return DEFAULT_DATA_ROOT;\n}\n\n/** Instance identifier (empty string when unset). */\nexport function getInstance(): string {\n const v = process.env[ENV_INSTANCE] || '';\n return v.trim().replace(/^[/\\\\]+|[/\\\\]+$/g, '');\n}\n\n/** Config file directory (config.json). Not split by instance; follows data root. */\nexport function getConfigDir(): string {\n return getDataRoot();\n}\n\n/** Runtime config directory (agent_moss_runtime.json + skills dir). Not split by instance. */\nexport function getRuntimeConfigDir(): string {\n return getDataRoot();\n}\n\n/**\n * Token stats file path.\n * With instance → <data_root>/<instance>/agent_moss_token_stats.json\n * Without → <data_root>/agent_moss_token_stats.json\n */\nexport function getTokenStatsPath(): string {\n const instance = getInstance();\n if (instance) {\n return join(getDataRoot(), instance, 'agent_moss_token_stats.json');\n }\n return join(getDataRoot(), 'agent_moss_token_stats.json');\n}","import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { LLMConfig, TimeoutConfig, RetryConfig } from './engine/types';\nimport { getConfigDir } from './infra/paths';\n\n/** Custom rule from user config */\nexport interface CustomRule {\n pattern: string;\n action: 'Allow' | 'Deny';\n severity: string;\n description?: 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(getConfigDir(), '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// 打包内 user_rules.json 路径(npm 安装自包含)+ dev 回退到仓库根 agent_moss/rules。\n// 对齐 skill-loader.ts 的 fileURLToPath(import.meta.url) 双路径解析:\n// - tsup 打包后 config.ts 被内联进 dist/{cli,server,engine/coordinator}.js,\n// import.meta.url 指向该 chunk(dist/engine/coordinator.js → __dirname=dist/engine/),\n// 故 dist 内 rules 在 ../rules(即 dist/rules/user_rules.json,copy-assets.cjs 复制)。\n// - dev(vitest) 模式 config.ts 源文件 __dirname=ts/src/,仓库根 agent_moss/rules\n// 在 ../../agent_moss/rules。三条候选路径覆盖 dist 与 dev 两种形态,命中即用。\nconst __configModuleDir = (() => {\n try { return path.dirname(fileURLToPath(import.meta.url)); }\n catch { return typeof __dirname !== 'undefined' ? __dirname : process.cwd(); }\n})();\nconst USER_RULES_PATHS = [\n path.join(__configModuleDir, 'rules', 'user_rules.json'), // 源在 ts/src/rules(一般不存在)\n path.join(__configModuleDir, '..', 'rules', 'user_rules.json'), // dist: dist/engine/../rules = dist/rules ✅\n path.join(__configModuleDir, '..', '..', 'agent_moss', 'rules', 'user_rules.json'), // dev src: ts/src/../../agent_moss\n];\n\nfunction wildcardToRegExp(pattern: string): string {\n // 对齐 Python UserRuleMatcher: re.escape(pattern).replace(r\"\\*\", \".*\")\n // JS 无 re.escape,手动转义所有正则元字符,再把转义后的 \\* 还原为 .*\n return pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\\\\\*/g, '.*');\n}\n\nfunction loadCustomRules(): CustomRule[] {\n const rules: CustomRule[] = [];\n // 1. AGENT_MOSS_CUSTOM_RULES env var(运行时注入,最高优先)\n try {\n const raw = process.env.AGENT_MOSS_CUSTOM_RULES;\n if (raw) {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n for (const r of parsed) {\n if (r && r.pattern && r.action) rules.push({ pattern: r.pattern, action: r.action, severity: r.severity || 'high' });\n }\n }\n }\n } catch { /* ignore env parse error */ }\n\n // 2. 打包内 agent_moss/rules/user_rules.json 的 sensitive_actions(通配符规则)。\n // 对齐 Python UserRuleMatcher(DEFAULT_RULES_PATH = agent_moss/rules/user_rules.json),\n // 含 crontab -e / crontab -r / * | crontab / iptables - 等用户敏感规则。\n // TS 此前只读 env 不读该文件,导致 crontab -e 等 L1 漏检(FN-2)。wildcard → RegExp。\n for (const rulesPath of USER_RULES_PATHS) {\n try {\n if (!fs.existsSync(rulesPath)) continue;\n const data = JSON.parse(fs.readFileSync(rulesPath, 'utf-8'));\n const actions = Array.isArray(data?.sensitive_actions) ? data.sensitive_actions : [];\n for (const r of actions) {\n const p = r?.pattern;\n if (!p) continue;\n rules.push({ pattern: wildcardToRegExp(p), action: 'Deny', severity: 'high' });\n }\n break; // 命中第一个存在的文件即可\n } catch { /* ignore user_rules.json read/parse error */ }\n }\n return rules;\n}\n\n/** Custom rules loaded from AGENT_MOSS_CUSTOM_RULES env var + packaged user_rules.json */\nlet customRules: CustomRule[] = loadCustomRules();\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 * Probe LLM connectivity with a minimal max_tokens=1 request.\n * Mirrors Python _probe_llm (tests/conftest.py): same source of truth\n * (getLLMConfig / get_default_config), so a passing probe means the actual\n * L3 call in tests uses the same key/endpoint and will succeed.\n *\n * Returns true on any successful response (finish_reason length/stop both ok);\n * false on timeout / 401 / network error. Used by L3 tests to skip rather than\n * let a dead key fail-open and false-pass.\n */\nexport async function probeLLMConnection(timeoutMs: number = 8000): Promise<boolean> {\n if (!isLLMAvailable()) return false;\n const OpenAI = (await import('openai')).default;\n const config = getLLMConfig();\n const provider = detectProvider(config.baseUrl, config.provider);\n const extraHeaders = getProviderHeaders(provider);\n const client = new OpenAI({\n baseURL: config.baseUrl,\n apiKey: config.apiKey,\n timeout: timeoutMs,\n maxRetries: 0,\n defaultHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined,\n });\n try {\n const resp = await client.chat.completions.create({\n model: config.model,\n messages: [{ role: 'user', content: 'ping' } as any],\n max_tokens: 1,\n } as any);\n return !!(resp && resp.choices && resp.choices[0]);\n } catch {\n return false;\n }\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 * 内联脚本静态语义判定 — 区分敏感路径是\"被当作文本\"还是\"被当作读写目标\"。\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 等纯文本输出命令(敏感路径可能作为字符串字面量出现)。\n\n echo/printf 含真实文件重定向(> /path,非 /dev/null 丢弃、非 >& fd)时返回 false——\n 重定向目标是真实写文件,路径不是字面量,不当文本命令(否则 echo x > '~/.bashrc'\n 被当文本命令 → inline_analyzer 把引号内路径当字面量 → 漏报敏感路径写)。 */\nexport function isLiteralTextCommand(command: string): boolean {\n ECHO_CMD_RE.lastIndex = 0;\n if (!ECHO_CMD_RE.test(command)) return false;\n // 含真实文件重定向 → 不是纯文本输出\n if (command.includes('>')) {\n let d = command.replace(/<=>|>=|<=|<>|=>/g, ' ');\n d = d.replace(/(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/g, '');\n // 摘引号重定向目标(去引号保留路径,支持 / 或 ~ 开头)\n d = d.replace(new RegExp(\">{1,2}\\\\s*(['\\\"])([~./][^'\\\"]+)\\\\1\", \"g\"), (_m, _q, p) => '>' + p);\n d = d.replace(/'[^']*'|\"[^\"]*\"/g, '');\n if (/>{1,2}\\s*(?!&)\\S/.test(d)) {\n return false;\n }\n }\n return true;\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 不进此判定)\n// 对齐 Python inline_analyzer._build_redirect_to_sensitive_re(profile):Python 按\n// profile.sensitive_paths 动态编译(其中含 ~/.bashrc)。TS 无 profile 运行时注入,\n// 故在 ROOT/HOME/CREDENTIAL 静态列表基础上,额外补 shell rc 文件名片段,\n// 让 `echo 'x' >> ~/.bashrc`、`echo 'x' >> /storage/Users/currentUser/.bashrc`\n//(鸿蒙 home 形态)都能被识别为真实重定向写入 → Deny,而非落到\"文本字面量\"放行。\n// 注意:shell rc 片段用文件名匹配(不带 ~ 前缀),可命中任意 home 绝对路径下的 rc 文件。\nconst SHELL_RC_FRAGMENTS = [\n '.bashrc', '.zshrc', '.profile', '.bash_profile', '.zprofile',\n];\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 ...SHELL_RC_FRAGMENTS,\n];\nconst REDIRECT_TO_SENSITIVE_RE = new RegExp(`>{1,2}\\\\s*(?:\\\\S*/)?(${SENSITIVE_PATH_FRAGMENTS.map((p) => p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})(?:\\\\s|$)`, '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: '物理内存访问设备(读写均危险)', credential: true },\n { path: '/dev/kmsg', riskLevel: 'high', desc: '内核消息缓冲区' },\n // SSH 主机私钥\n // SSH 主机私钥(排除 .pub 公钥变体,对齐 Python .ssh/id_rsa(?!\\.pub) 范式)\n { path: '/etc/ssh/ssh_host_rsa_key(?!\\\\.pub)', riskLevel: 'critical', desc: 'SSH 主机 RSA 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ed25519_key(?!\\\\.pub)', riskLevel: 'critical', desc: 'SSH 主机 Ed25519 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ecdsa_key(?!\\\\.pub)', 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// 只读工具精确名(豁免 read_before_write;与 coordinator READONLY_SENSITIVE_TOOLS/FULLY_SAFE_TOOLS 对齐)。\n// 注意:不含 filemgr-writefile/filemgr-editfile/filemgr-searchreplace(这些是真写)。\nconst NON_WRITE_TOOLS = new Set([\n 'ask_user_question', 'glob', 'grep', 'list_dir', 'count_text_length', 'search',\n // filemgr 只读三件套(globfiles 在 coordinator FULLY_SAFE_TOOLS 提前放行,此处兜底防御非 coordinator 入口)\n 'filemgr-globfiles', 'filemgr-readfile', 'filemgr-grepfiles',\n // 通用只读工具名\n 'read', 'read_file', 'file_read', 'head', 'tail', 'cat',\n]);\n\n// 非 bash/terminal 类工具前缀豁免 read_before_write。\n// 仅保留通用基线前缀(与 EXCLUDED_PREFIXES / SENSITIVE_EXCLUDED_PREFIXES 一致):\n// memory-/skill-manager-/mailbox-/app- 是数据/编排/通信工具,read_before_write(写文件前先读)对其\n// 无意义,且工具名含 remove/update(memory-removeMemory/memory-updateUserPortrait)会命中\n// WRITE_KEYWORDS 子串 → 误判为写。L2 层独立豁免,不再仅依赖 coordinator opendesk 白名单。\n// 不含 skill-(任意能力,coordinator 故意保留 L3)、todomgr-/planning-(opendesk 专属命名空间,\n// 经 opendesk/rules.json builtin_safe_action_types 在 coordinator 层豁免 L2+L3,不到 L2)。\n// mailbox-sendEmail/replyEmail 的外传风险由 L3 LLM 管,不归 L2 read_before_write。\nconst NON_WRITE_TOOL_PREFIXES = ['memory-', 'skill-manager-', 'mailbox-', 'app-'];\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 (also used by L1 SensitivePathChecker)\nexport const WRITE_KEYWORDS = ['write', '写入', 'save', '保存', 'modify', '修改', 'update', '更新', 'delete', '删除', 'remove', '移除', 'create', '创建', 'append', '追加', 'truncate', '截断', 'overwrite', '覆盖', 'replace', '替换', 'edit'];\n\n// 写/删命令词边界正则(对齐 Python _WRITE_COMMAND_RES)。\n// 子串匹配无法可靠识别 rm/cp/dd(\"rm\" 误命中 arm/form),故用词边界。\nexport const WRITE_COMMAND_RES: RegExp[] = [\n /\\brm\\b/, /\\bunlink\\b/, /\\brmdir\\b/, /\\bshred\\b/, /\\bcp\\b/, /\\bmv\\b/,\n /\\binstall\\b/, /\\btee\\b/, /\\bdd\\b/, /\\bmkfs\\b/,\n /\\b(fdisk|parted|cfdisk|sfdisk)\\b/, /\\bchmod\\b/, /\\bchown\\b/, /\\btruncate\\b/,\n];\n\n// 只读命令集合(重定向写判定用,对齐 Python READ_ONLY_COMMANDS)。\n// 这些命令带 > 也是输出重定向非写文件意图(如 cat file > /dev/null)。\nexport const 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 // NEW-FP-I: echo/printf 是文本输出命令,参数是字面量非写目标。加入此集让\n // read_before_write 的 echo 段走只读命令分支(只提取重定向目标,不提取参数路径),\n // 避免 echo \"cat /etc/shadow\" > /tmp/x.sh 的引号内 /etc/shadow 被当写目标误报。\n // echo \"x\" > /tmp/x.sh 的重定向目标 /tmp/x.sh 仍被提取(真实写不漏报)。\n 'echo', 'printf',\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 的丢弃写法(对齐 Python _DEVNULL_REDIRECT_RE)。\n// 注意带 g 标志:一条诊断命令常含多个 2>/dev/null(cd ... && ls ... 2>/dev/null; find ... 2>/dev/null),\n// JS String.replace 无 g 只替换首个,残留的 2>/dev/null 仍带 `>` 会触发重定向写误判(FP)。\n// Python 端用 re.sub 全局替换,此处对齐之。\nconst DEVNULL_REDIRECT_RE = /(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/g;\n\n/**\n * 综合判定是否为写/删操作(对齐 Python _is_write_operation,单一事实源)。\n * 供 L2 read_before_write 与 L1 sensitive_path 共用,避免手写复刻漂移。\n *\n * 1. WRITE_KEYWORDS 子串匹配 actionType+actionDetail(与 Python 一致,不加词边界以保持双端同步)\n * 2. WRITE_COMMAND_RES 词边界正则(rm/cp/dd/tee/truncate/...)\n * 3. sed -i 原地编辑\n * 4. 重定向写入:剥 devnull 后有 `>` 且首词非只读命令\n */\nexport function isWriteOperation(actionType: string, actionDetail: string, writeKeywords: string[] = WRITE_KEYWORDS): boolean {\n // 1. 关键词子串匹配(actionType 或 actionDetail)\n if (writeKeywords.some(kw => actionType.includes(kw) || actionDetail.includes(kw))) return true;\n // 2. 写/删命令词边界\n if (WRITE_COMMAND_RES.some(rx => rx.test(actionDetail))) return true;\n // 3. sed -i 原地编辑\n if (/\\bsed\\s+-[a-zA-Z]*i/i.test(actionDetail)) return true;\n // 3b. wget/curl + -O/-o/--output 下载写入(无 > 重定向,漏判 → 漏报,且可写 shell 后门绕过敏感路径)\n // 3c. rsync 同步写 dest(非 --list-only/--dry-run/-n 只读模式)\n // 两类都按命令段判定首词(排除 echo/printf 字面量)\n for (const seg of actionDetail.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const parts = trimmed.split(/\\s+/);\n const fw = parts[0]?.toLowerCase() || '';\n if (fw === 'wget' || fw === 'curl') {\n // NEW-FP-C: -O- / -o- / --output-document=- / --output=- 是 stdout(值为 -),不算文件写\n const isStdout = /\\s(?:-O|-o)-(?:\\s|$)/.test(trimmed) ||\n /\\s--output-document=-(?:\\s|$)/i.test(trimmed) ||\n /\\s--output=-(?:\\s|$)/i.test(trimmed);\n if (isStdout) continue;\n // NEW-FP-N: -o /dev/null / --output=/dev/null 是丢弃响应体只测状态码,非真实写文件\n const isDevnull = /\\s(?:-O|--output-document|--output)\\s*\\/dev\\/null(?:\\s|$)/i.test(trimmed) ||\n /\\s(?:-O|--output-document|--output)=[/]?dev\\/null(?:\\s|$)/i.test(trimmed);\n if (isDevnull) continue;\n if (/\\s(?:-O|--output-document|--output)(?:=|\\s|$)/i.test(trimmed) || /\\s-O\\S/.test(trimmed)) {\n return true;\n }\n }\n if (fw === 'rsync' && !/--list-only|--dry-run/i.test(trimmed) && !/(^|[^a-zA-Z])-n([^a-zA-Z]|$)/.test(trimmed)) {\n return true;\n }\n }\n // 4. 重定向写入:先排除 /dev/null 丢弃和比较运算符,再看是否还有真实文件重定向。\n // NEW-FN-D 修复:不再用「整条命令首词是否只读」判断——`cat in > out` 里 cat 是\n // 只读命令但其重定向目标 out 是真实写文件(覆写/追加),应判写。只读命令的「安全\n // 重定向」只指 `> /dev/null`(丢弃输出,已剥)。改为只读命令带真实文件重定向也算写。\n // fd 重定向(>&N / N>&M / 2>&1)不是写文件,用「> 后紧跟 &」排除。\n // grep/awk 搜索模式里的 > 字面量(如 grep \"a>b\" file)不是重定向——剥引号内容后再判。\n if (actionDetail.includes('>')) {\n // 先剥掉比较运算符(>=, <=, <>, <=>, =>),避免 Python 代码里的 `r.get('seq',0) >= 28`\n // 被当成重定向写(`>=` 含 `>`)。这些是表达式而非重定向,不应计入写判定。\n const detailWithoutCompare = actionDetail.replace(/<=>|>=|<=|<>|=>/g, ' ');\n const detailWithoutDevnull = detailWithoutCompare.replace(DEVNULL_REDIRECT_RE, '');\n // 先摘「> '引号路径'」为裸路径(支持引号包裹的重定向目标,如 echo x > '/tmp/file'),\n // 否则下一步剥引号内容会把重定向目标路径也删掉 → 漏判写(漏报)。\n const detailUnquotedRedirect = detailWithoutDevnull.replace(\n />{1,2}\\s*(['\"])([~./][^'\"]+)\\1/g,\n (_m, _q, p) => '>' + p,\n );\n // 剥掉剩余引号内内容(grep/awk 搜索模式、python -c 代码里的 > 字面量),只看引号外\n // 是否还有真实文件重定向。\n const detailWithoutQuotes = detailUnquotedRedirect.replace(/'[^']*'|\"[^\"]*\"/g, '');\n // 真实文件重定向:> 或 >> 后紧跟非空白、非 & 的文件目标字符。\n // `>{1,2}\\s*(?!&)\\S` 匹配 echo x > /file、cat in >file、sort in >> /file;\n // 排除 ls 2>&1、echo >&2(>& 紧邻或 > 后 & 是 fd 合并,非写文件)。\n if (/>{1,2}\\s*(?!&)\\S/.test(detailWithoutQuotes)) {\n return true;\n }\n }\n return false;\n}\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\n/**\n * 匹配危险动作词。中文用子串(无词边界歧义),英文用词边界正则。\n *\n * 裸 includes() 会在 actionDetail 参数/搜索模式里误报:\n * - `git log --format=` 含 \"format\" → 误判\"格式化磁盘\"\n * - grep 搜索模式 `NON_WRITE|non_write` 含 \"write\" → 误判\"修改\"\n * - `pip install --update` 含 \"update\" → 误判\"修改\"\n * 英文词用 `(?<!-)\\bWORD\\b`:\n * - 前面不是 `-`(排除 --format / --update / -delete 等参数形态)\n * - 词边界(排除 NON_WRITE 里的 write、arm 里的 rm 等)\n */\nfunction matchDangerousAction(actionDetail: string, action: string): boolean {\n // 中文词(含非 ASCII)走子串匹配\n if (/[^\\x00-\\x7f]/.test(action)) {\n return actionDetail.includes(action);\n }\n // 英文词走词边界 + 排除参数前缀\n const escaped = action.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = new RegExp(`(?<![-\\\\w])${escaped}\\\\b`, 'i');\n return re.test(actionDetail);\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 // 内联脚本命令(python -c / perl -e 等)跳过 intent 的 dangerousAction 词匹配。\n // 内联脚本代码内容里的英文词(print(delete this) 的 delete)是字符串字面量,\n // 不是真实动作;词边界 (?<![-\\w])delete\\b 能挡 print 里的 rm(短词),但挡不住\n // delete(长词独立词)→ intent 误报(Bug4)。内联脚本的「危险」由 L1.2\n // inline-analyzer 专门管(区分字面量 vs 真实调用),intent 不重复管。\n if (INLINE_SCRIPT_RE.test(actionDetail)) {\n // fall through to next rule, skip intent\n } else {\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 => matchDangerousAction(actionDetail, 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\n // 注:敏感路径访问检测 (checkSensitivePath) / 危险操作模式检测 / 横向移动检测\n // 已按\"L1 只看这一步\"原则搬至 heuristic.ts 的 runHeuristicCheck。\n // 本函数仅保留需要 action_history / prompt_session / cwd 的 L2 规则。\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 // 判据:sudo 后跟的命令本身是包管理/服务管理(apt/systemctl/yum/...)→ 合法运维\n // 直接放行,不要求历史先有一次 admin(新会话首次 sudo apt install 是合法高频运维)。\n // sudo + 非运维命令才查历史有无 admin 上下文;历史也无则视为异常提权。\n // 注意:剥掉 sudo 前缀再匹配 admin 关键词,否则 actionDetail 必含 sudo 导致永远放行。\n // 注:admin 关键词曾尝试词边界 \\b,但 grep apt / pip apt 里 apt 是独立词,\\bapt\\b 仍命中,\n // 词边界无法区分\"命令位置\"vs\"参数位置\",故暂保留子串匹配。提权漏检(grep apt 误当 admin\n // 上下文放行 sudo cat)是已知问题,待用命令位置匹配专项处理。\n // 内联脚本命令(python -c / perl -e 等)跳过提权词匹配:代码内容里的词\n // (print(\"chmod u+s\") 的 chmod u+s)是字符串字面量,不是真实动作,提权子串匹配\n // 会误报(FP-2 变体)。内联脚本的「危险」由 inline-analyzer 管,提权检测不重复管。\n if (INLINE_SCRIPT_RE.test(actionDetail)) {\n // fall through to next rule, skip privilege escalation\n // NEW-FP-J: 提权关键词改为「命令位置」判定。旧逻辑对整个 actionDetail 做子串匹配,\n // grep -rn \"sudo\" file、awk '/sudo/'、echo \"sudo make install\" 里参数/搜索模式/字面量\n // 位置的 sudo 被误判为真实提权。仅当段首词是提权命令(sudo/su/setuid,或 chmod+u+s)\n // 才认为存在提权意图。\n } else if (containsPrivilegeEscalation(actionDetail)) {\n const detailAfterSudo = actionDetail.replace(/(^|\\|\\||&&|\\s)sudo\\s+/g, ' ');\n const isAdminCmd = ['apt', 'systemctl', 'yum', 'dnf', 'pacman', 'zypper', 'apk'].some(kw => detailAfterSudo.includes(kw));\n if (!isAdminCmd) {\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\n // 注:横向移动检测已搬至 heuristic.ts (runHeuristicCheck)。\n // Rule 6: Non-interactive password modification consent check\n const pwdResult = checkPasswordConsent(actionType, actionDetail, actionHistory);\n if (pwdResult) return pwdResult;\n\n // Rule 7: 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)\nexport function 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 // key=value 语法的路径:of=/path、if=/path、--output=/path 等。\n // 现有 unixPaths 正则要求路径前是行首或空白,`of=/tmp/x` 里 / 前是 = 不匹配 →\n // dd of=/path 等漏报(NEW-FN-A)。此正则匹配 `=` 后紧跟的 / 路径。\n // NEW-FP-H: 先剥掉引号内容,避免 echo \"of=/dev/null done\" 这类输出文本里的\n // of=/dev/null 被误当真实写目标。引号内纯路径(dd of=\"/tmp/file\")由下方\n // quotedPaths 独立提取(要求引号内以 / 开头),故剥引号不会漏报真实写。\n const textNoQuotes = text.replace(/'[^']*'|\"[^\"]*\"/g, '');\n const kvPaths = textNoQuotes.match(/(?:=)(\\/[^\\s;|&><'\"]+)/g);\n if (kvPaths) paths.push(...kvPaths.map(p => p.replace(/^=/, '')));\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 // 豁免非文件类工具前缀(memory-/skill-/mailbox-/todomgr-...)与只读工具,\n // 避免 memory-removeMemory(工具名含 remove)/ filemgr-grepfiles(搜索模式含 write)等误判为写。\n // L2 层独立保护,不再仅依赖 coordinator opendesk 白名单(非 opendesk agent / 单测直调也安全)。\n if (NON_WRITE_TOOL_PREFIXES.some(p => actionType.startsWith(p))) return null;\n if (NON_WRITE_TOOLS.has(actionType)) return null;\n\n // 写判定按工具类型分流:\n // - bash/executebash/terminal-executebash:用 isWriteOperation(对齐 Python\n // _is_write_operation 单一事实源:WRITE_KEYWORDS 子串 + WRITE_COMMAND_RES 词边界\n // rm/cp/dd + sed -i + 重定向(剥 devnull+只读首词保护))。比手写 WRITE_KEYWORDS.includes\n // 多了词边界命令识别,能抓 `rm`/`cp`/`dd` 等;重定向/2>/dev/null 由它统一处理。\n // - 其他工具:只匹配 actionType,不看 actionDetail 内容。\n // 理由:非 shell 工具的写意图只能从工具名体现(filemgr-writefile/write/edit),\n // 参数内容里的中文\"更新\"\"移除\"是业务语义不是文件写语义;\n // grep 搜索模式里的 write/update/remove 子串绝不能算写意图(误报根因)。\n const isBashLike = actionType === 'bash' || actionType === 'executebash' || actionType === 'terminal-executebash';\n const isWrite = isBashLike\n ? isWriteOperation(actionType, actionDetail)\n : WRITE_KEYWORDS.some(kw => actionType.includes(kw));\n\n if (!isWrite) return null;\n\n // 删除/安全命令复合(无真正写命令)不触发 read_before_write。\n // read_before_write 的语义是「写文件前先读内容」,对删除不适用——删除不需要读文件字节,\n // 且删除的元数据预检(rm -rf /etc 等敏感路径、递归)由 L1 命令模式负责(/tmp 清理 L1\n // 判定安全放行,rm -rf /etc L1 拦截)。这是「rm 豁免狭义读内容」而非「跳过 RBW」——\n // 广义元数据预检仍由 L1 完成。判定:命令链无「写命令段」即跳过。写命令段 = 段首词是\n // 写命令(cp/mv/install/tee/dd/truncate/mkfs/sed -i)或含真实重定向写。\n // 注意:chmod/chown 不在此列——改元数据不改文件内容,「写前先读」对其无意义,\n // `chmod 644 /tmp/已有未读` 不应误报。危险 chmod 形态(777/u+s/4755 提权、chmod /敏感路径)\n // 由 L1 专门模式和 sensitive_path 检测负责(WRITE_COMMAND_RES 仍保留 chmod/chown 供敏感路径写判定)。\n // `rm ... && echo done` 豁免,`rm /a && echo x > /b` 仍走 rbw,\n // `chmod 644 /tmp/x`(普通)豁免,`chmod u+s /tmp/x`(提权)由 L1 拦。\n const WRITE_CMDS = new Set(['cp', 'mv', 'install', 'tee', 'dd', 'truncate', 'mkfs', 'fdisk', 'parted']);\n if (isBashLike) {\n const detailNoCompare = actionDetail.replace(/<=>|>=|<=|<>|=>/g, ' ');\n const detailNoDevnull = detailNoCompare.replace(DEVNULL_REDIRECT_RE, '');\n // 先摘「> '引号路径'」为裸路径(支持引号包裹重定向目标),再剥剩余引号内容,\n // 与 isWriteOperation 的重定向判定保持一致(避免两处漂移)。\n const detailUnquotedRedirect = detailNoDevnull.replace(\n />{1,2}\\s*(['\"])([~./][^'\"]+)\\1/g,\n (_m, _q, p) => '>' + p,\n );\n const detailNoQuotes = detailUnquotedRedirect.replace(/'[^']*'|\"[^\"]*\"/g, '');\n const hasRedirectWrite = />{1,2}\\s*(?!&)\\S/.test(detailNoQuotes);\n let hasWriteSeg = hasRedirectWrite;\n if (!hasWriteSeg) {\n for (const seg of actionDetail.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const fw = trimmed.split(/\\s+/)[0]?.toLowerCase() || '';\n if (WRITE_CMDS.has(fw) || /\\bsed\\s+-[a-zA-Z]*i/i.test(trimmed)) {\n hasWriteSeg = true;\n break;\n }\n // wget/curl + -O/-o/--output 下载写入\n if ((fw === 'wget' || fw === 'curl') &&\n (/\\s(?:-O|--output-document|--output)(?:=|\\s|$)/i.test(trimmed) || /\\s-O\\S/.test(trimmed))) {\n hasWriteSeg = true;\n break;\n }\n // rsync 同步写 dest(非 --list-only/--dry-run/-n 只读模式)\n if (fw === 'rsync' && !/--list-only|--dry-run/i.test(trimmed) && !/(^|[^a-zA-Z])-n([^a-zA-Z]|$)/.test(trimmed)) {\n hasWriteSeg = true;\n break;\n }\n }\n }\n if (!hasWriteSeg) return null;\n }\n\n // Extract target file paths,过滤掉非写目标的参数路径。\n // - cd 是目录切换不是写操作,cd /path 的 /path 不应作为写目标(否则 `cd /敏感 && ls` 误报)。\n // - 读命令(cat/head/tail/grep/find/less/more/wc/cut 等 READ_ONLY_COMMANDS)的文件参数是\n // 读取目标不是写目标,`echo x > /tmp/t1; cat /tmp/t2` 里 t2 是 cat 的读目标却会被\n // extractFilePaths 当写目标提取 → read_before_write 误报(Bug5)。过滤之。\n // - 写命令的源文件参数(cp/mv/install 的首个路径参数)是读取目标不是写目标,\n // `cp /src /dst` 里 /src 是读目标不是写目标 → 误报(NEW-FP-1)。过滤首个路径参数。\n // - dd 的 if=/path 是输入源(读目标),of=/path 才是输出目标(写目标)。\n // `dd if=/dev/zero of=/tmp/x` 里 if= 的 /dev/zero 是读源,必须排除否则误报;\n // of= 的 /tmp/x 是写目标保留(NEW-FN-A:此前 of= 路径根本提取不到 → 漏报)。\n // 逐段法(per-segment):按 &&/||/;/换行 拆命令段,每段独立计算写目标——\n // cd → 无写目标(切目录);\n // 只读命令(cat/grep/sort/head 等)→ 命令参数是读目标,但重定向目标(> /path)\n // 是写目标,需提取(NEW-FN-D:此前整段排除把重定向目标也丢了 → `cat in > out` 漏检 out);\n // cp/mv/install → 排除首个路径(源文件),其余为写目标;\n // dd → 排除 if= 路径(输入源),of= 为写目标;\n // 其他段 → 所有路径为写目标。\n // 关键:排除是 per-segment 局部的,不是全局——否则 `cp /a /b && cp /b /c` 里\n // /b 既是第一段 dest(写目标)又是第二段 source(读目标),全局排除会让第一段\n // 对 /b 的覆写漏检(NEW-FN-B)。逐段计算确保 /b 在第一段仍被作为写目标检查。\n const SOURCE_ARG_CMDS = new Set(['cp', 'mv', 'install', 'rsync']);\n // 重定向写目标正则:> 或 >> 后紧跟文件路径(裸路径或引号包裹,排除 >& fd)。\n // 用 RegExp 构造避免正则字面量里 / 与路径分隔符冲突。\n const REDIRECT_TARGET_RE = new RegExp(\">{1,2}\\\\s*(?!&)(?:'(/[^']+)'|\\\"(/[^\\\\\\\"]+)\\\"|(/[^\\\\s;|&><'\\\\\\\"]+))\");\n const targetPaths: string[] = [];\n for (const seg of actionDetail.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const firstWord = trimmed.split(/\\s+/)[0]?.toLowerCase() || '';\n if (firstWord === 'cd') {\n continue;\n }\n if (READ_ONLY_COMMANDS.has(firstWord)) {\n // 只读命令:文件参数是读目标,但重定向目标是写目标(NEW-FN-D)。\n // 先摘引号重定向目标(去引号保留路径),再剥剩余引号内容(grep 模式),再提取目标。\n // NEW-FP-M: 先剥 /dev/null 重定向(cat f 2>/dev/null 的 /dev/null 是 stderr 丢弃\n // 非写目标),否则 REDIRECT_TARGET_RE 把 2>/dev/null 提取为写目标误报。\n const segUnquoted = trimmed.replace(new RegExp(\">{1,2}\\\\s*(['\\\"])([~./][^'\\\"]+)\\\\1\", \"g\"), (_m, _q: string, p: string) => '>' + p);\n const segNoDevnull = segUnquoted.replace(DEVNULL_REDIRECT_RE, '');\n const segNoQuotes = segNoDevnull.replace(/'[^']*'|\"[^\"]*\"/g, '');\n const m = segNoQuotes.match(REDIRECT_TARGET_RE);\n if (m) targetPaths.push(m[1] || m[2] || m[3]);\n continue;\n }\n const segPaths = extractFilePaths(trimmed);\n // NEW-FP-N: curl/wget 的 -o /dev/null 是丢弃响应体非真实写文件,排除 /dev/null\n // 路径(extractFilePaths 会把 -o /dev/null 的 /dev/null 提取为写目标 → 误报)。\n const segPathsFiltered = (firstWord === 'wget' || firstWord === 'curl')\n ? segPaths.filter(p => p !== '/dev/null')\n : segPaths;\n if (SOURCE_ARG_CMDS.has(firstWord)) {\n // 排除首个路径(源文件),其余为写目标\n if (segPathsFiltered.length > 1) targetPaths.push(...segPathsFiltered.slice(1));\n } else if (firstWord === 'dd') {\n // dd 的 if= 是输入源(读目标),of= 是输出目标(写目标)。\n // 排除 if= 的路径,保留 of= 的路径作为写目标。\n // NEW-FP-G: of=/dev/null 是丢弃输出非真实写文件(dd if=/dev/zero\n // of=/dev/null 是丢弃测试),与重定向 >/dev/null 同语义,排除避免\n // read_before_write 误报 /dev/null。/dev/zero/urandom 同理(设备文件)。\n const ifSourceMatches = trimmed.match(/\\bif=(\\/[^\\s;|&><'\"]+)/g);\n const ifSourcePaths = new Set(ifSourceMatches ? ifSourceMatches.map((m: string) => m.replace(/^if=/, '')) : []);\n const devNullMatches = trimmed.match(/\\bof=(\\/dev\\/\\S+)/g);\n const devNullTargets = new Set(devNullMatches ? devNullMatches.map((m: string) => m.replace(/^of=/, '')) : []);\n for (const sp of segPaths) {\n if (!ifSourcePaths.has(sp) && !devNullTargets.has(sp)) targetPaths.push(sp);\n }\n } else {\n // 其他段(含重定向写 echo > file、tee、truncate 等):该段所有路径为写目标\n targetPaths.push(...segPathsFiltered);\n }\n }\n // 去重\n const uniqueTargetPaths = [...new Set(targetPaths)];\n if (uniqueTargetPaths.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 uniqueTargetPaths) {\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 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// NEW-FP-J: 提权关键词「命令位置」判定。仅当段首词是提权命令(sudo/su/setuid,\n// 或 chmod+u+s setuid 位)才认为存在提权意图。引号感知分段:echo \"a; sudo rm\" 的\n// ; 在引号内不分段,整段首词 echo 不触发。grep/awk/echo 首词段的参数是搜索模式/字面量。\nfunction containsPrivilegeEscalation(actionDetail: string): boolean {\n const ad = actionDetail.toLowerCase();\n for (const seg of ad.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const parts = trimmed.split(/\\s+/);\n const fw = parts[0]?.toLowerCase() || '';\n if (fw === 'sudo' || fw === 'su' || fw === 'setuid') return true;\n if (fw === 'chmod' && /\\bu\\s*\\+\\s*s\\b/.test(trimmed)) return true;\n }\n return false;\n}\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","/**\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, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\nimport { getRuntimeConfigDir } from './paths';\nconst __dirname = dirname(fileURLToPath(import.meta.url));\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// type-only import:避免 agents ↔ runtime-config 循环依赖(运行时用 require 取 resolveAgentsDir)\nimport type { AgentExtensions } from '../agents/types';\n\nconst ENV_RUNTIME_CONFIG_PATH = 'AGENT_MOSS_RUNTIME_CONFIG_PATH';\n\nfunction runtimeDir(): string {\n return getRuntimeConfigDir();\n}\n\nconst RUNTIME_CONFIG_DIR = runtimeDir();\nconst RUNTIME_CONFIG_PATH = join(RUNTIME_CONFIG_DIR, 'agent_moss_runtime.json');\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 /** builtin_safe_action_types / builtin_safe_skills 项的值(前缀或精确工具名) */\n value?: 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 /** agent 定制规则(按 agent_id 分区,每 agent 内按类别组织) */\n agent_rules?: Record<string, 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 agent_rules: {},\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 agent_rules: merged.agent_rules || {},\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 // 优先读 L1_rules.sensitive_path_access(重分类后归属 L1);\n // 回退 L2_rules.sensitive_path_access(兼容迁移前老配置)。函数名保留 l2 前缀仅为兼容。\n let cat = runtime.L1_rules?.sensitive_path_access;\n if (!cat || !cat.rules || cat.rules.length === 0) {\n cat = runtime.L2_rules?.sensitive_path_access || { category_enabled: true, rules: [] };\n }\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 // 敏感路径已重分类到 L1,遍历 L1_rules + L2_rules 两层。函数名保留 l2 前缀仅为兼容。\n for (const layerKey of ['L1_rules', 'L2_rules'] as const) {\n const layer = runtime[layerKey] || {};\n for (const [catName, cat] of Object.entries(layer)) {\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 }\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/** 扫描 agent_moss/agents/<id>/rules.json,转为 agent_rules 分区结构(出厂种子)。\n * 每个 agent 的 rules.json 字段 → agent_rules[<id>] 的 Category 结构(与 L1/L2 同形)。\n * builtin_safe_action_types / builtin_safe_skills 原为 string[],转成 [{value, enabled, builtin}]。\n * 路径内联解析(不 import agents/index.ts 避免 ESM 循环依赖),与 agents/index.ts resolveAgentsDir 同策略。 */\nconst _AGENTS_DIR_PROD = join(__dirname, 'agents');\nconst _AGENTS_DIR_DEV = join(__dirname, '..', '..', '..', 'agent_moss', 'agents');\nfunction _agentRulesToDefaults(): Record<string, Record<string, Category>> {\n const out: Record<string, Record<string, Category>> = {};\n const agentsDir = existsSync(_AGENTS_DIR_PROD) ? _AGENTS_DIR_PROD\n : existsSync(_AGENTS_DIR_DEV) ? _AGENTS_DIR_DEV : _AGENTS_DIR_PROD;\n if (!existsSync(agentsDir)) return out;\n let entries: string[];\n try {\n entries = readdirSync(agentsDir, { withFileTypes: true })\n .filter(d => d.isDirectory()).map(d => d.name);\n } catch {\n return out;\n }\n for (const agentId of entries) {\n const rulesFile = join(agentsDir, agentId, 'rules.json');\n if (!existsSync(rulesFile)) continue;\n let data: any;\n try { data = JSON.parse(readFileSync(rulesFile, 'utf-8')); } catch { continue; }\n out[agentId] = {\n builtin_safe_action_types: {\n category_enabled: true,\n category_desc: 'agent 完全安全操作白名单(前缀尾随 - 或精确名,命中跳 L2+L3)',\n rules: (data.builtin_safe_action_types || []).map((v: string) =>\n ({ value: v, enabled: true, builtin: true })),\n },\n builtin_safe_skills: {\n category_enabled: true,\n category_desc: 'agent 信任的内置 Skill(命中跳 L2+L3)',\n rules: (data.builtin_safe_skills || []).map((v: string) =>\n ({ value: v, enabled: true, builtin: true })),\n },\n extra_command_patterns: {\n category_enabled: true,\n category_desc: 'agent 专属危险命令正则(L1 末尾追加)',\n rules: (data.extra_command_patterns || []).map((p: any) =>\n ({ ...p, enabled: true, builtin: true })),\n },\n extra_injection_keywords: {\n category_enabled: true,\n category_desc: 'agent 专属注入关键词(L1 末尾追加)',\n rules: (data.extra_injection_keywords || []).map((k: any) =>\n ({ ...k, enabled: true, builtin: true })),\n },\n extra_sensitive_paths: {\n category_enabled: true,\n category_desc: 'agent 专属敏感路径(L1 末尾追加)',\n rules: (data.extra_sensitive_paths || []).map((sp: any) =>\n ({ ...sp, enabled: true, builtin: true })),\n },\n };\n }\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 sensitive_path_access: {\n category_enabled: true,\n category_desc: '敏感路径访问检测(deny_both/deny_read/deny_write)',\n rules: _l2SensitivePathsToRules(),\n },\n user_custom: { category_enabled: true, category_desc: '用户自定义命令规则', rules: [] },\n },\n L2_rules: {\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 user_custom: { category_enabled: true, category_desc: '用户自定义 L2 逻辑规则', rules: [] },\n },\n L3_skills: _l3SkillsToRules(),\n agent_rules: _agentRulesToDefaults(),\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 // builtin_safe_action_types / builtin_safe_skills 项用 value 字段\n if (rule.value) return JSON.stringify([rule.value]);\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 // 清理源码已移除的类目:保留 user_custom(用户自定义壳),删除其余不在 src 的类目\n // (如本次重构删除的 dangerous_patterns / lateral_movement,老配置落盘仍残留)。\n for (const catName of Object.keys(userLayer)) {\n if (catName === 'user_custom') continue;\n if (!(catName in srcLayer)) delete userLayer[catName];\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/** 合并 agent_rules 分区(按 agent_id 分区,每个 agent 内复用类别合并逻辑)。\n * 新出厂 agent → 整体加入;已有 agent → 每类别走 _mergeRuleCategories 同套\n * (指纹去重 + 保留 enabled + 新 builtin 追加 + 删除标记 source_removed)。 */\nfunction _mergeAgentRules(userCfg: RuntimeConfig, srcDefaults: RuntimeConfig): void {\n const userAgent = (userCfg.agent_rules || (userCfg.agent_rules = {})) as Record<string, Record<string, Category>>;\n const srcAgent = srcDefaults.agent_rules || {};\n for (const [agentId, srcCats] of Object.entries(srcAgent)) {\n if (!(agentId in userAgent)) {\n userAgent[agentId] = JSON.parse(JSON.stringify(srcCats));\n continue;\n }\n const userCats = userAgent[agentId];\n for (const [catName, srcCat] of Object.entries(srcCats)) {\n if (!(catName in userCats)) {\n userCats[catName] = JSON.parse(JSON.stringify(srcCat));\n continue;\n }\n const userCat: Category = userCats[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 Object.keys(existing).forEach(k => delete (existing as any)[k]);\n Object.assign(existing, srcR);\n existing.enabled = userEnabled;\n } else {\n userRules.push({ ...srcR, enabled: true });\n }\n }\n for (const r of userRules) {\n if (r.builtin && !srcFps.has(_ruleFingerprint(r))) {\n r.source_removed = true;\n r.enabled = false;\n }\n }\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 // 跨层迁移:敏感路径已从 L2 重分类到 L1。老配置 sensitive_path_access 还在\n // L2_rules 下,搬到 L1_rules(保留用户 enabled/deny_mode/自定义项),L2 删除该分类。\n // 注:dangerous_patterns / lateral_movement 检测是硬编码子检测器,不读 runtime\n // config rules,故老配置 L2 里这两类的 rules 不迁移(默认种子已删除该类目)。\n _migrateCategoriesAcrossLayers(cfg, 'L2_rules', 'L1_rules',\n ['sensitive_path_access']);\n _mergeRuleCategories(cfg, srcDefaults, 'L1_rules');\n _mergeRuleCategories(cfg, srcDefaults, 'L2_rules');\n _mergeSkillCategories(cfg, srcDefaults, 'L3_skills');\n _mergeAgentRules(cfg, srcDefaults);\n return cfg;\n}\n\n/** 把指定分类从 srcLayer 搬到 dstLayer(保留分类内全部内容,按指纹去重合并)。 */\nfunction _migrateCategoriesAcrossLayers(cfg: RuntimeConfig, srcLayer: 'L1_rules' | 'L2_rules', dstLayer: 'L1_rules' | 'L2_rules', catNames: string[]): void {\n const src = (cfg as any)[srcLayer] || {};\n const dst: any = cfg[dstLayer] || (cfg[dstLayer] = {} as RuntimeConfig['L1_rules']);\n for (const catName of catNames) {\n if (!(catName in src)) continue;\n const srcCat = src[catName];\n if (!dst[catName]) {\n dst[catName] = { category_enabled: true, category_desc: '', rules: [] };\n }\n const dstCat = dst[catName];\n if (!dstCat.category_desc && srcCat.category_desc) dstCat.category_desc = srcCat.category_desc;\n if (dstCat.category_enabled === undefined) dstCat.category_enabled = srcCat.category_enabled;\n // 合并 rules:dst 已有的按指纹保留,src 独有的追加\n if (srcCat.rules && srcCat.rules.length > 0) {\n const dstFps = new Set((dstCat.rules || []).map((r: any) => _ruleFingerprint(r)));\n for (const r of srcCat.rules) {\n const fp = _ruleFingerprint(r);\n if (!dstFps.has(fp)) {\n (dstCat.rules = dstCat.rules || []).push(r);\n dstFps.add(fp);\n }\n }\n }\n delete src[catName];\n }\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 // 允许删:用户自定义(builtin=false)+ 已移除的(builtin=true 但 source_removed=true)。\n // 活跃 builtin 规则不允许删(用 enabled 开关)。\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 const r = rules[idx];\n if (r.builtin && !r.source_removed) 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\n// ==================== agent 定制规则(runtime_config 统一治理)====================\n\nexport function getAgentRules(runtime: RuntimeConfig): Record<string, Record<string, Category>> {\n return runtime.agent_rules || {};\n}\n\nfunction _agentCategoryEnabledRules(cat: Category | undefined): Rule[] {\n if (!cat || cat.category_enabled === false) return [];\n return (cat.rules || []).filter(r => r.enabled !== false);\n}\n\n/** 从 runtime_config 的 agent_rules[agent_id] 构造 AgentExtensions(应用 enabled 过滤)。\n * 供 getAgentExtensions 在 hasRuntimeConfig() 时调用。无该 agent 分区返回 null。 */\nexport function getEnabledAgentExtensions(runtime: RuntimeConfig, agentId: string): AgentExtensions | null {\n const agentData = runtime.agent_rules?.[agentId];\n if (!agentData) return null;\n const safeAction = _agentCategoryEnabledRules(agentData.builtin_safe_action_types);\n const safeSkills = _agentCategoryEnabledRules(agentData.builtin_safe_skills);\n const cmdPatterns = _agentCategoryEnabledRules(agentData.extra_command_patterns)\n .filter(r => r.pattern).map(r => ({\n pattern: r.pattern!, risk_level: r.risk_level || '',\n risk_type: r.risk_type || '', reason: r.reason || '',\n }));\n const injKeywords = _agentCategoryEnabledRules(agentData.extra_injection_keywords)\n .filter(r => r.keyword).map(r => ({\n keyword: r.keyword!, risk_level: r.risk_level || '', lang: r.lang || 'en',\n }));\n const sensitivePaths = _agentCategoryEnabledRules(agentData.extra_sensitive_paths)\n .filter(r => r.path).map(r => ({\n path: r.path!, risk_level: r.risk_level || '', desc: r.desc || '',\n credential: r.credential, read_only: r.read_only, deny_mode: r.deny_mode,\n }));\n return {\n agent_id: agentId,\n description: '',\n extra_command_patterns: cmdPatterns,\n extra_injection_keywords: injKeywords,\n extra_sensitive_paths: sensitivePaths,\n builtin_safe_skills: safeSkills.filter(r => r.value).map(r => r.value!),\n builtin_safe_action_types: safeAction.filter(r => r.value).map(r => r.value!),\n extra_skills: [],\n };\n}\n\nexport function updateAgentRuleEnabled(agentId: string, category: string, ruleFp: Partial<Rule>, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.agent_rules?.[agentId]?.[category];\n if (cat) {\n const targetFp = _ruleFingerprint(ruleFp);\n for (const r of (cat.rules || [])) {\n if (_ruleFingerprint(r) === targetFp) { r.enabled = enabled; break; }\n }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function addAgentRule(agentId: string, category: string, rule: Record<string, unknown>): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n if (!runtime.agent_rules) runtime.agent_rules = {};\n if (!runtime.agent_rules[agentId]) runtime.agent_rules[agentId] = {};\n const cats = runtime.agent_rules[agentId];\n if (!cats[category]) cats[category] = { category_enabled: true, category_desc: '', rules: [] };\n (cats[category].rules || (cats[category].rules = [])).push({ ...rule, enabled: true, builtin: false } as Rule);\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function deleteAgentRule(agentId: string, category: string, ruleFp: Partial<Rule>): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.agent_rules?.[agentId]?.[category];\n if (cat) {\n const targetFp = _ruleFingerprint(ruleFp);\n cat.rules = (cat.rules || []).filter(r => _ruleFingerprint(r) !== targetFp);\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\n/** 切换某 agent 某类别的 category_enabled(整类开关,与通用规则分类开关同范式)。 */\nexport function updateAgentCategoryEnabled(agentId: string, category: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.agent_rules?.[agentId]?.[category];\n if (cat) cat.category_enabled = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\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\nexport function 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 let ext: AgentExtensions | null = null;\n // 统一存储:优先读 runtime_config 的 agent_rules 分区(用户可在 console\n // 查看/编辑/禁用/新增,享受与通用规则一致的合并升级)。回退 rules.json\n // (无 runtime_config 时,如直接起服务未 seed、或旧部署)。\n try {\n const { hasRuntimeConfig, loadRuntimeConfig, getEnabledAgentExtensions } = require('../infra/runtime-config');\n if (hasRuntimeConfig()) {\n ext = getEnabledAgentExtensions(loadRuntimeConfig(), agentId);\n }\n } catch { /* runtime-config 不可用时回退 rules.json */ }\n\n if (ext === null) {\n const agentsDir = resolveAgentsDir();\n const rulesFile = resolve(agentsDir, agentId, 'rules.json');\n if (!existsSync(rulesFile)) {\n cache.set(agentId, null);\n return null;\n }\n try {\n const raw = readFileSync(rulesFile, 'utf-8');\n 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 } 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 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 `${ext.builtin_safe_action_types?.length ?? 0} builtin safe action types`\n );\n return ext;\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';\nimport {\n ROOT_SENSITIVE_PATHS,\n HOME_SENSITIVE_PATHS,\n CREDENTIAL_PATHS,\n isWriteOperation,\n} from './logic-rules';\n\n/**\n * Layer 1: Feature-matching 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 — var 分支排除 /var/tmp/(合法清理)\n { pattern: /\\brm\\s+-[a-zA-Z]*[rf][a-zA-Z]*\\s+\\/(etc|var(?!\\/tmp)|home|usr|boot|root|opt|srv|sys|proc)\\b/i, severity: 'critical', description: '删除关键系统目录', riskType: 'script_execution' },\n // 3. rm -r absolute path (no -f) — 排除 /tmp/ /var/tmp/ /run/ /dev/shm/(CI/开发高频合法清理)\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*\\s+\\/(?!tmp\\/|var\\/tmp\\/|run\\/|dev\\/shm\\/)/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+\\/(?!tmp\\/|var\\/tmp\\/|run\\/|dev\\/shm\\/)/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 // curl|bash 优先匹配 user_rules(high/sensitive_action),见下方 UserRuleMatcher 段;\n // 非 bash 的 curl|sh/zsh/dash 走 CommandPatternScanner critical。两条分流由\n // runHeuristicCheck 的规则顺序保证(bash 在前 high,其余 fall-through 到 critical)。\n { pattern: /curl\\s+.*\\|\\s*bash/i, severity: 'high', description: 'curl pipe bash 执行 (user_rules)', riskType: 'sensitive_action' },\n { pattern: /curl\\s+.*\\|\\s*(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: 'high', description: 'base64 解码执行 (user_rules)', riskType: 'sensitive_action' },\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(?!\\.pub)/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 // --- Critical: dangerous permissions / ownership (提权 / 权限敞口) ---\n // 修正「只拦 777、xx7 漏放」的缺口:\n // 1) 八进制末位 7:other 位含写+执行敞口(chmod 777/647/007/4777 等);644/755/1700 不命中\n // 2) 八进制 setuid/setgid 位:首位 4(setuid)/2(setgid) 的 4 位八进制(chmod 4755/2755)\n // 3) 符号 setuid/setgid:chmod u+s / g+s / a+s\n // 普通权限修改(chmod 644)不在此列——L2 read_before_write 已豁免 chmod/chown(不写内容),\n // 危险形态在此 L1 专门拦,以「提权」正确理由拦截,不再靠 RBW 误打误撞。\n { pattern: /chmod\\s+[0-7]{0,3}7\\b/i, severity: 'critical', description: '危险权限设置 (chmod ...7, other 位含写+执行敞口)', riskType: 'privilege_escalation' },\n { pattern: /chmod\\s+[24][0-7]{3}\\b/i, severity: 'critical', description: 'setuid/setgid 位设置 (chmod 4xxx/2xxx, 提权)', riskType: 'privilege_escalation' },\n { pattern: /chmod\\s+[ugoa]\\+s\\b/i, severity: 'critical', description: '符号 setuid/setgid 设置 (chmod u+s/g+s/a+s, 提权)', riskType: 'privilege_escalation' },\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 // > /etc/ 重定向覆盖:对齐 Python CommandPatternScanner `>\\s*/etc/`(不兼容引号路径),\n // 引号包裹的重定向目标(cat > '/etc/ssh/sshd_config')走 checkSensitivePath 敏感路径 high。\n { pattern: />\\s*\\/etc\\//i, severity: 'critical', description: '覆盖写入系统配置目录', riskType: 'file_access' },\n { pattern: />\\s*\\/boot\\//i, severity: 'critical', description: '覆盖写入启动引导目录', riskType: 'file_access' },\n // 注:/proc/ 重定向覆盖走 checkSensitivePath 的 high(内核参数 /proc/sys/),此处不拦 /proc/ 避免遮蔽(对齐 Python)。\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 // 两条规则:第一条匹配 ~ 与 /home/<user>/ 形态;第二条按文件名兜底,\n // 覆盖非标准 home 路径(如鸿蒙 /storage/Users/currentUser/.bashrc、\n // /root/.bashrc),避免按 home 前缀枚举导致漏检持久化后门。\n { pattern: />>\\s*(~|\\/home\\/[^/]+)\\/(\\.bashrc|\\.zshrc|\\.profile|\\.bash_profile|\\.zprofile)/, severity: 'high', description: '检测到修改 Shell 配置文件(~/.bashrc 等),可能用于持久化后门', riskType: 'persistence' },\n { pattern: />>\\s*\\S*\\/(\\.bashrc|\\.zshrc|\\.profile|\\.bash_profile|\\.zprofile)\\b/, 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(对齐 Python UserRuleMatcher 命中即短路返回,\n // 不让后续 CommandPatternScanner/SensitivePathChecker 叠加取最高遮蔽 user rules 的判定)。\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 return {\n allowed: false,\n reason: `命中用户敏感动作规则: ${rule.description || rule.pattern}`,\n riskLevel: rule.severity as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_action',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // Allow rules just pass through\n }\n } catch { /* invalid regex, skip */ }\n }\n\n // Check built-in dangerous patterns\n // NEW-FP-I: echo/printf 引号内参数是字面量非真实命令,剥掉引号内容后再匹配,\n // 避免 echo \"rm -rf /tmp\" 的输出文本被当真实命令误报。引号外的重定向 > 和管道 |\n // 后的真实操作保留(echo \"x\" > /etc/passwd 仍被 >/etc/ 检测,echo pass | passwd\n // 的 passwd 仍被匹配)。非 echo/printf 段(rm -rf; echo done 的 rm 段)不剥。\n const scanDetail = stripLiteralTextSegments(input.aNext.actionDetail);\n const scanCommand = `${input.aNext.actionType}: ${scanDetail}`;\n let topRiskType = '';\n for (const rule of DANGEROUS_PATTERNS) {\n if (rule.pattern.test(scanCommand)) {\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(scanCommand)) {\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 // ===== 从 L2 搬入的静态子检测器(只看 a_next)=====\n const actionTypeL = input.aNext.actionType.toLowerCase();\n const detailL = input.aNext.actionDetail.toLowerCase();\n const isExcludedType = SENSITIVE_EXCLUDED_PREFIXES.some(p => actionTypeL.startsWith(p));\n\n // 危险操作模式检测优先(对应 Python CommandPatternScanner 第2检测器,先于 SensitivePathChecker):\n // 含 > /etc/ > /boot/ 重定向覆盖 critical——echo >> /etc/passwd 命中 critical 短路,\n // 不走后面的 checkSensitivePath high(对齐 Python ground truth)。\n const dangerousResult = checkDangerousPatterns(actionTypeL, detailL);\n if (dangerousResult) return dangerousResult;\n\n // 敏感路径访问检测:deny_both/deny_read/deny_write + 凭据边界匹配。\n // 排除 memory-/skill- 等非文件工具前缀,避免参数关键词误报。\n if (!isExcludedType) {\n const pathResult = checkSensitivePath(detailL, input.cwd || '/', agentExt);\n if (pathResult) return pathResult;\n }\n\n // 用户敏感规则命中(custom_rule)须先于敏感路径和横向移动检测:\n // - 避免 ssh -o StrictHostKeyChecking=no 被 checkLateralMovement 标 lateral medium 遮蔽\n // (Python UserRuleMatcher 先于 LateralMovementChecker)。\n // - 避免 ssh ... 'cat /etc/shadow' 被 checkSensitivePath 的 /etc/shadow critical 遮蔽\n // (Python UserRuleMatcher 先于 SensitivePathChecker,user rules high 优先于敏感路径 critical)。\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 // 横向移动检测:ssh/scp/rsync 到非本机主机\n const lateralResult = checkLateralMovement(detailL);\n if (lateralResult) return lateralResult;\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\n/**\n * NEW-FP-I: 对首词 echo/printf 的命令段剥掉引号内容(字面量参数)。\n *\n * echo/printf 是文本输出命令,其引号内参数是被打印的字面量而非真实命令——\n * `echo \"rm -rf /tmp\"` 是打印这串文本不是执行删除。但 DANGEROUS_PATTERNS 旧实现\n * 对整个 actionDetail 做正则匹配,引号内的 rm/chmod/mkfs 等危险命令模式被误当\n * 真实命令匹配 → 误报(NEW-FP-I)。\n *\n * 修复:按 &&/||/;/换行 分段,首词是 echo/printf 的段,剥掉引号内容(字面量),\n * 保留引号外的重定向 >/>> 和管道 | 后的真实操作:\n * - `echo \"rm -rf /tmp\"` → `echo `(rm 模式不匹配,误报消除)\n * - `echo \"x\" > /etc/passwd` → `echo > /etc/passwd`(重定向 >/etc/ 仍匹配,真实写不漏报)\n * - `rm -rf /tmp; echo done` → rm 段不剥,echo 段剥,rm 仍匹配(真实危险不漏报)\n * - `echo pass | passwd` → passwd 无引号在管道后,剥后仍保留(管道注入不漏报)\n */\nexport function stripLiteralTextSegments(actionDetail: string): string {\n // 旁路(NEW-FN-H 待修):含\"写脚本 + 后续执行\"或\"管道喂解释器\"绕过链时整条不剥离。\n // 保留引号内路径让 L1 凭据检测兜底,避免剥离后绕过链漏检(inline-09/10 依赖)。\n // - inline-09: echo \"cat /etc/shadow\" > /tmp/x.sh && bash /tmp/x.sh(写脚本+执行)\n // - inline-10: printf 'cat /etc/shadow' | bash(管道喂解释器)\n const writeScriptExec = />\\s*[/~]\\S*\\.(sh|py|pl|rb)\\b/.test(actionDetail) &&\n /(?:&&|\\|\\||;|\\n|\\|)\\s*(?:bash|sh|zsh|dash|python|perl|ruby|node)/.test(actionDetail);\n const pipeToInterpreter = /\\|\\s*(?:bash|sh|zsh|dash|python|perl|ruby|node)\\b/.test(actionDetail);\n if (writeScriptExec || pipeToInterpreter) {\n return actionDetail;\n }\n // 按命令分隔符分段,但跳过引号内的分隔符(echo \"a; b\" 的 ; 在引号内不分段)\n const resultParts: string[] = [];\n for (const seg of splitCommandSegments(actionDetail)) {\n const fw = (seg.trim().split(/\\s+/)[0] || '').toLowerCase();\n if (fw === 'echo' || fw === 'printf') {\n // 先摘重定向目标的引号路径为裸路径(保留真实写目标),再剥剩余引号内容\n const segUnquotedRedirect = seg.replace(\n />{1,2}\\s*(['\"])([~./][^'\"]+)\\1/g,\n (_m, _q, p: string) => '>' + p,\n );\n resultParts.push(segUnquotedRedirect.replace(/'[^']*'|\"[^\"]*\"/g, ''));\n } else {\n resultParts.push(seg);\n }\n }\n return resultParts.join('');\n}\n\n/**\n * 按命令分隔符分段,跳过引号内的分隔符(对齐 Python _split_command_segments)。\n * echo \"a; b && c\" 的引号内分隔符是字面量非命令分隔,不能分段——否则\n * 引号内 chmod/mkfs 等词会脱离 echo 段被当独立命令首词误匹配(NEW-FP-I)。\n */\nfunction splitCommandSegments(actionDetail: string): string[] {\n const segments: string[] = [];\n let cur = '';\n let quote: string | null = null;\n for (let i = 0; i < actionDetail.length; i++) {\n const ch = actionDetail[i];\n if (quote) {\n cur += ch;\n if (ch === quote) quote = null;\n continue;\n }\n if (ch === \"'\" || ch === '\"') {\n quote = ch;\n cur += ch;\n continue;\n }\n if (ch === ';' || ch === '\\n') {\n segments.push(cur); segments.push(ch); cur = '';\n continue;\n }\n if (ch === '&' && actionDetail[i + 1] === '&') {\n segments.push(cur); segments.push('&&'); cur = '';\n i++; continue;\n }\n if (ch === '|' && actionDetail[i + 1] === '|') {\n segments.push(cur); segments.push('||'); cur = '';\n i++; continue;\n }\n cur += ch;\n }\n if (cur) segments.push(cur);\n return segments;\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// ==================== 从 L2 搬入 L1 的静态子检测器 ====================\n// 以下三个检测器只看 a_next(不看 action_history),按\"L1 只看这一步\"原则\n// 从 logic-rules.ts 搬入。逻辑原样保留,source 改为 'heuristic'、\n// violatedLayers 改为 ['1.1'],对齐 L1 命令模式/注入关键词的层号。\n\n// 敏感路径检测排除的非文件工具前缀(避免 memory-searchMemory 等误报)\nconst SENSITIVE_EXCLUDED_PREFIXES = ['memory-', 'skill-', 'skill-manager-', 'mailbox-', 'app-'];\n\n/**\n * 敏感路径访问检测(从 L2 搬入)。\n * deny_both(凭据):无论读写都拦截,isCredential=true\n * deny_read:只拦截读取(如 /dev/random)\n * deny_write:只拦截写入/删除\n */\nexport function checkSensitivePath(\n command: string,\n cwd: string,\n agentExt?: import('../agents').AgentExtensions | null,\n): SecurityJudgment | null {\n const expandedCwd = cwd.replace(/^~/, process.env.HOME || '/home/user');\n\n // 写判定统一用 isWriteOperation(对齐 Python _is_write_operation 单一事实源),\n // 替代原手写 isWriteOpFlag(含 ''.includes(kw) 笔误、重定向逻辑矛盾)。\n // command 在此 = actionDetail 小写(调用方 :231 传 detailL),actionType 留空——\n // isWriteOperation 的 actionType.includes 走空串无影响,actionDetail 部分覆盖 command。\n const isWriteOpFlag = isWriteOperation('', command);\n\n // NEW-FP-I: echo/printf 引号内参数是字面量,其中的敏感路径不应被当真实访问。\n // 对首词 echo/printf 的段剥引号内容后再做路径匹配。非 echo/printf 段(cat \"/etc/shadow\")\n // 不剥,引号内真实路径参数仍匹配。引号外的重定向(echo \"x\" > /etc/passwd)保留。\n const pathScanText = stripLiteralTextSegments(command);\n\n // 边界路径匹配(对齐 Python heuristic.py:121-132,避免子串误报)。\n // 裸 command.includes(sp.path) 会把 /etc/passwd 命中到 /tmp/etc_passwd_backup、\n // /boot/ 命中到 /boot-log。改用边界正则:/ 开头路径前导用 ^|空白|/|反斜杠|引号,\n // 其余用 \\b;尾随 \\b。凭据(deny_both)尤其需要边界(如 .env 不能命中 .environment)。\n const pathMatches = (text: string, path: string): boolean => {\n // 含正则前瞻语法(如 (?!\\\\.pub) 排除公钥变体)时保留前瞻不转义,仅转义其余元字符。\n // 把路径切成「前瞻块 / 其余」分段处理,前瞻块原样保留,其余分段转义元字符。\n const parts = path.split(/(\\(\\?!.*?\\))/);\n const escaped = parts.map(part => {\n if (part.startsWith('(?!')) return part; // 前瞻块原样\n return part.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }).join('');\n const re = path.startsWith('.') || path.startsWith('/')\n ? new RegExp(`(?:^|[\\\\s/\\\\\\\\'\"])${escaped}\\\\b`, 'i')\n : new RegExp(`\\\\b${escaped}\\\\b`, 'i');\n return re.test(text);\n };\n\n for (const sp of ROOT_SENSITIVE_PATHS) {\n if (pathMatches(pathScanText, 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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n isCredential: !!sp.credential,\n };\n }\n }\n\n for (const sp of HOME_SENSITIVE_PATHS) {\n const expanded = `${expandedCwd}/${sp.path}`;\n // 私钥路径(不以 .pub 结尾)排除公钥变体:.ssh/id_rsa 不应命中 .ssh/id_rsa.pub(公钥公开)\n const pathRe = sp.path.endsWith('.pub')\n ? new RegExp(sp.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'i')\n : new RegExp(sp.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + '(?!\\\\.pub)', 'i');\n const expandedRe = sp.path.endsWith('.pub')\n ? new RegExp(expanded.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'i')\n : new RegExp(expanded.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + '(?!\\\\.pub)', 'i');\n if (pathRe.test(pathScanText) || expandedRe.test(pathScanText)) {\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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n isCredential: !!sp.credential,\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 (pathMatches(command, spPath) || pathMatches(command, 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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n isCredential: !!sp.credential,\n };\n }\n }\n }\n\n // 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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n\n return null;\n}\n\n/** 危险操作模式检测(从 L2 搬入):通配符+删除、重定向覆盖 /etc /boot /proc */\nexport function checkDangerousPatterns(actionType: string, actionDetail: string): SecurityJudgment | null {\n if (actionType === 'file_write' || actionType === 'file_edit') return null;\n\n // Wildcard + delete — 排除 /tmp 等临时目录的清理操作\n // 用边界正则匹配目录名本身(/tmp 和 /tmp/ 都算),避免 `find /tmp -delete`\n // 因 \"/tmp/\" 子串不匹配(/tmp 后是空格)而 isTempPath=false 误报(Bug6)。\n const TEMP_DIRS = ['/tmp', '/var/tmp', '/run', '/dev/shm'];\n const isTempPath = TEMP_DIRS.some(td =>\n new RegExp(`(?:^|[\\\\s/])${td.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}(?:[\\\\s/]|$)`).test(actionDetail)\n );\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: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // find -exec <写命令> / find | xargs <写命令> — find 在 READ_ONLY_COMMANDS 导致整段\n // 被当只读,-exec 或 | xargs 后的 chmod/cp/mv/rm/sed -i 等写命令漏检(NEW-FN-C: -exec;\n // NEW-FN-E: | xargs 等价变体未覆盖)。find 遍历出的文件被批量执行写操作,静态无法确定\n // 具体目标文件,但「find + 写命令」组合本身就是批量写意图,此处识别 -exec/-execdir/-ok\n // 后紧跟写命令、或 | xargs 后紧跟写命令即拦截。只匹配写命令首词,避免 -exec grep /\n // | xargs ls 等只读误报。xargs 后的 sed -i 单独匹配(sed -i 是 sed + -i 参数)。\n const findWriteMatch = actionDetail.match(\n /\\bfind\\b.*?(?:(?:^|\\s)-exec(?:dir)?\\s+(chmod|chown|cp|mv|rm|dd|tee|truncate|mkfs|shred|rmdir|unlink)\\b|(?:^|\\s)\\|\\s*xargs\\s+(?:sed\\s+-[a-zA-Z]*i|chmod|chown|cp|mv|rm|dd|tee|truncate|mkfs|shred|rmdir|unlink)\\b)/i\n );\n if (findWriteMatch) {\n const cmdHit = findWriteMatch[1] || 'xargs';\n return {\n allowed: false,\n reason: `检测到 find 批量执行写操作 (${cmdHit}),可能批量修改/删除文件`,\n riskLevel: 'high',\n riskType: 'script_execution',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // Redirect overwrite to system directories(对齐 Python CommandPatternScanner `>\\s*/etc/` critical,不排除敏感路径)。\n // echo >> /etc/passwd、cat > /etc/ssh/sshd_config 均命中 critical 短路(Python ground truth)。\n if (/>\\s*\\/etc\\//.test(actionDetail) || />\\s*\\/boot\\//.test(actionDetail)) {\n return {\n allowed: false,\n reason: '检测到重定向覆盖写入关键系统目录',\n riskLevel: 'critical',\n riskType: 'file_access',\n confidence: 95,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // A16: 重定向覆盖设备文件(对齐 Python linux.py:180 `>\\s*/dev/(sd|hd|nvme|vd|loop|mem|kmsg|port|zero|random|urandom|full|core)`)。\n // high/file_access。须先于 checkSensitivePath 的 /dev/mem critical 命中,避免写 /dev/mem 被标 critical(Python 是 high)。\n if (/>\\s*\\/dev\\/(sd|hd|nvme|vd|loop|mem|kmsg|port|zero|random|urandom|full|core)/i.test(actionDetail)) {\n return {\n allowed: false,\n reason: '检测到重定向写入设备文件',\n riskLevel: 'high',\n riskType: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n return null;\n}\n\n\nfunction extractRemoteHost(command: string): string | null {\n // NEW-FN-G: 旧正则 (?:ssh|scp|rsync)\\s+(?:-[\\w]+\\s+)*(\\S+@\\S+|\\b(?!-)[\\w.-]+\\b)\n // 的 (?:-[\\w]+\\s+)* 只匹配单选项不匹配带参数值选项(-p 2222、-L 8080:...、\n // -D 1080、-e ssh),导致 host 提取取到端口号或选项参数。token 化三策略更可靠。\n // NEW-FP-E: bash -c/sh -c \"ssh user@host\" 的 user@host 被引号包裹成 \"user@host\"\n // 正则不匹配(\" 非 \\w)→ 漏报。bash -c 内联命令是真实调用,应检测。\n // 剥 token 首尾引号后再匹配(python -c 已在 checkLateralMovement 开头 INLINE_SCRIPT_RE 跳过)。\n const tokens = command.split(/\\s+/).map(t => t.replace(/^[\"']|[\"']$/g, ''));\n // 策略1:优先找 user@host 或 user@host: 模式(最可靠,带值选项参数值如\n // -L 8080:localhost:80 的 localhost 会被 isLocalHost 排除,不会误匹配)。\n for (const tok of tokens) {\n const am = tok.match(/^([\\w.-]+)@([\\w.-]+)(:.*)?$/);\n if (am && am[2] && !isLocalHost(am[2])) {\n return `${am[1]}@${am[2]}`;\n }\n }\n // 策略2:host: 模式(rsync/scp 远程路径 host:/path,无 user@)\n for (const tok of tokens) {\n const hm = tok.match(/^([\\w.-]+):\\/(.*)?$/);\n if (hm && hm[1] && !isLocalHost(hm[1])) {\n return hm[1];\n }\n }\n // 策略3:回退\"第一个非选项 token\"(ssh host 无 @ 无 :,如 ssh 10.0.0.5)。\n // 跳过 - 开头选项及其参数值(-p 2222 / -e ssh / -L 8080:...)。\n const skipValueOpts = new Set([\n '-p', '-l', '-i', '-o', '-b', '-c', '-m', '-F',\n '-e', '-S', '-W', '-J', '-I', '-T', '-B',\n '-L', '-R', '-D', '-E', '-M', '-O', '-P', '-q',\n ]);\n let foundCmd = false;\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i];\n if (t === 'ssh' || t === 'scp' || t === 'rsync') {\n foundCmd = true;\n continue;\n }\n if (!foundCmd) continue;\n if (t.startsWith('-')) {\n // 带值选项:跳过下一个 token(-p 2222 / -e ssh / -L 8080:...)\n if (skipValueOpts.has(t) && i + 1 < tokens.length) {\n i++;\n }\n continue;\n }\n // 非选项 token:候选主机。排除纯路径(/ 开头本地路径非主机名)。\n if (t.startsWith('/')) continue;\n return t;\n }\n return 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\n/** 横向移动检测(从 L2 括入):ssh/scp/rsync 到非本机主机 */\nexport function checkLateralMovement(actionDetail: string): SecurityJudgment | null {\n // NEW-FP-D: 内联脚本(python -c / perl -e 等)里的 ssh/scp/rsync 是字面量非真调用,\n // 跳过交 inline-analyzer 专门管,与 intent/privilege 一致\n if (/\\b(?:python|python3|perl|ruby|node|php|lua)\\b\\s+.*-[cer][a-zA-Z]*\\s/.test(actionDetail)) return null;\n\n // NEW-FP-D: echo/printf �首词的参数是字面量非真调用(echo ssh user@host 是打印字面量)\n // 按命令段判定:首词 echo/printf 跳过,与 isWriteOperation 的 wget/curl 字面量判定一致\n const segments = actionDetail.split(/&&|\\|\\||;|\\n/).map(s => s.trim()).filter(Boolean);\n let hasRealCall = false;\n for (const seg of segments) {\n const parts = seg.split(/\\s+/);\n const fw = (parts[0] || '').toLowerCase();\n if (fw === 'echo' || fw === 'printf') continue;\n if (/(?:ssh|scp|rsync)\\s+/.test(seg)) { hasRealCall = true; break; }\n }\n if (!hasRealCall) return null;\n\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: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n }\n return null;\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 <data_root>/agent_moss_token_stats.json\n * (default ~/.config/agentmoss). With AGENT_MOSS_INSTANCE the file is isolated\n * to <data_root>/<instance>/ (see infra/paths.ts). env override\n * AGENT_MOSS_TOKEN_STATS_PATH wins. Whole-file rewrite per record (not append).\n * Max 10000 records, oldest trimmed.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'fs';\nimport { join } from 'path';\nimport { getTokenStatsPath } from '../infra/paths';\n\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 if (envPath) return envPath;\n return getTokenStatsPath();\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 } as any);\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 // LLM 回 JSON 字段名可能是 camelCase(riskLevel)或 snake_case(risk_level),\n // 两种都兼容避免拿不到 risk_level 走兜底 'low'(双端对齐 Python 字段名)\n const riskLevel = parsed.riskLevel ?? parsed.risk_level;\n const riskType = parsed.riskType ?? parsed.risk_type;\n return {\n allowed: parsed.allowed !== false,\n reason: parsed.reason || 'LLM 分析完成',\n riskLevel: ['low', 'medium', 'high', 'critical'].includes(riskLevel) ? riskLevel : 'low',\n riskType: 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","import { SecurityJudgment } from './types';\nimport { runHeuristicCheck, isInlineScriptCommand, DANGEROUS_PATTERNS } from './heuristic';\nimport { runLogicCheck, isWriteOperation } 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: Feature-matching 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 // 对齐 py coordinator.py:172-176 should_deny_l1:\n // high/critical 直接 Deny;\n // medium + file_access(敏感路径写)确定性拦截;\n // 其他 medium(如 git push --force / rm -f 单文件 / prompt 注入 repeat-instructions)\n // 不直接 Deny,fall-through 到 L2/L3。\n const shouldDenyL1 =\n heuristicResult.riskLevel === 'high' ||\n heuristicResult.riskLevel === 'critical' ||\n (heuristicResult.riskLevel === 'medium' && heuristicResult.riskType === 'file_access');\n if (shouldDenyL1) {\n return heuristicResult;\n }\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 // agent 专属扩展(agent_moss/agents/<id>/rules.json),取一次供 fast-pass 各白名单复用\n const agentExt = getAgentExtensions(input.agentId);\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 // agent 专属完全安全操作白名单(精确名或前缀,来自 rules.json builtin_safe_action_types)。\n // 前缀以 '-' 结尾 → startswith 匹配(如 \"memory-\");否则精确名匹配(如 \"mailbox-getEmailList\")。\n // 命中即跳过 L2+L3,与 builtin_safe_skills 同范式。仅对该 agent_id 生效,不污染其他 agent。\n // OpenDesk 的 memory-*/todomgr-*/planning-* 是纯数据/只读操作,走 L3 LLM 耗时 1~137s 无意义。\n if (agentExt?.builtin_safe_action_types && agentExt.builtin_safe_action_types.length > 0) {\n // actionType 已小写化(:143);rules.json 精确名可能是驼峰(如 mailbox-getEmailList),\n // 故比较时对白名单项也 lower。前缀项(尾随 '-')同样 lower 后 startswith。\n const hit = agentExt.builtin_safe_action_types.some(t => {\n const tl = t.toLowerCase();\n return tl.endsWith('-') ? actionType.startsWith(tl) : actionType === tl;\n });\n if (hit) {\n return {\n allowed: true,\n reason: `agent 内部安全操作,跳过深度分析: ${actionType}`,\n riskLevel: (heuristicResult?.riskLevel || 'low') as SecurityJudgment['riskLevel'],\n riskType: '',\n confidence: 95,\n source: 'whitelist_bypass',\n violatedLayers: [],\n };\n }\n }\n\n // 内置安全 Skill 直接放行(通用 baseline + agent_ext.builtin_safe_skills)\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 // 安全兜底 1:检查完整命令是否命中高危模式(如 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 // 安全兜底 2:检查是否含真实重定向写(echo x > file / printf >> file)。\n // is_fully_safe_bash_command 只看首命令名(echo),会忽略 >/>> 重定向,\n // 导致 `echo x > /tmp/existing.txt` 覆写已存在文件被白名单放行跳过 L2(Bug3)。\n // 复用 isWriteOperation 的重定向判定(已剥 devnull + 比较运算符 + 只读首词保护)。\n const hasRedirectWrite = isWriteOperation(firstCmd, lowerDetail);\n if (!fullCmdHit && !hasRedirectWrite) {\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 // file_access 命中合并:敏感路径/危险模式现已在 L1(heuristicResult),\n // 间接文件访问仍在 L2(logicResult)。两者任一命中 file_access 都需进入\n // inline/credential 包装判定。优先采用 logicResult,退而取 heuristicResult。\n const l1FileAccessHit = !!(heuristicResult && !heuristicResult.allowed && heuristicResult.riskType === 'file_access');\n const effectiveResult = (logicResult && !logicResult.allowed) ? logicResult\n : (l1FileAccessHit ? heuristicResult : null);\n if (effectiveResult) {\n // 凭据文件:无论读写、无论是否 inline,都直接拒绝。\n // 来源:L1 sensitive path(isCredential)或 L2 indirect_file_access\n const isCredentialPath = !!effectiveResult.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) && effectiveResult.riskType === 'file_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 ((effectiveResult.riskLevel === 'high' || effectiveResult.riskLevel === 'critical') && (!skipInlineFileAccess || isCredentialPath)) {\n return effectiveResult;\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","'use strict';\n\nexports.getBooleanOption = (options, key) => {\n\tlet value = false;\n\tif (key in options && typeof (value = options[key]) !== 'boolean') {\n\t\tthrow new TypeError(`Expected the \"${key}\" option to be a boolean`);\n\t}\n\treturn value;\n};\n\nexports.cppdb = Symbol();\nexports.inspect = Symbol.for('nodejs.util.inspect.custom');\n","'use strict';\nconst descriptor = { value: 'SqliteError', writable: true, enumerable: false, configurable: true };\n\nfunction SqliteError(message, code) {\n\tif (new.target !== SqliteError) {\n\t\treturn new SqliteError(message, code);\n\t}\n\tif (typeof code !== 'string') {\n\t\tthrow new TypeError('Expected second argument to be a string');\n\t}\n\tError.call(this, message);\n\tdescriptor.value = '' + message;\n\tObject.defineProperty(this, 'message', descriptor);\n\tError.captureStackTrace(this, SqliteError);\n\tthis.code = code;\n}\nObject.setPrototypeOf(SqliteError, Error);\nObject.setPrototypeOf(SqliteError.prototype, Error.prototype);\nObject.defineProperty(SqliteError.prototype, 'name', descriptor);\nmodule.exports = SqliteError;\n","\n/**\n * Module dependencies.\n */\n\nvar sep = require('path').sep || '/';\n\n/**\n * Module exports.\n */\n\nmodule.exports = fileUriToPath;\n\n/**\n * File URI to Path function.\n *\n * @param {String} uri\n * @return {String} path\n * @api public\n */\n\nfunction fileUriToPath (uri) {\n if ('string' != typeof uri ||\n uri.length <= 7 ||\n 'file://' != uri.substring(0, 7)) {\n throw new TypeError('must pass in a file:// URI to convert to a file path');\n }\n\n var rest = decodeURI(uri.substring(7));\n var firstSlash = rest.indexOf('/');\n var host = rest.substring(0, firstSlash);\n var path = rest.substring(firstSlash + 1);\n\n // 2. Scheme Definition\n // As a special case, <host> can be the string \"localhost\" or the empty\n // string; this is interpreted as \"the machine from which the URL is\n // being interpreted\".\n if ('localhost' == host) host = '';\n\n if (host) {\n host = sep + sep + host;\n }\n\n // 3.2 Drives, drive letters, mount points, file system root\n // Drive letters are mapped into the top of a file URI in various ways,\n // depending on the implementation; some applications substitute\n // vertical bar (\"|\") for the colon after the drive letter, yielding\n // \"file:///c|/tmp/test.txt\". In some cases, the colon is left\n // unchanged, as in \"file:///c:/tmp/test.txt\". In other cases, the\n // colon is simply omitted, as in \"file:///c/tmp/test.txt\".\n path = path.replace(/^(.+)\\|/, '$1:');\n\n // for Windows, we need to invert the path separators from what a URI uses\n if (sep == '\\\\') {\n path = path.replace(/\\//g, '\\\\');\n }\n\n if (/^.+\\:/.test(path)) {\n // has Windows drive at beginning of path\n } else {\n // unix path…\n path = sep + path;\n }\n\n return host + path;\n}\n","/**\n * Module dependencies.\n */\n\nvar fs = require('fs'),\n path = require('path'),\n fileURLToPath = require('file-uri-to-path'),\n join = path.join,\n dirname = path.dirname,\n exists =\n (fs.accessSync &&\n function(path) {\n try {\n fs.accessSync(path);\n } catch (e) {\n return false;\n }\n return true;\n }) ||\n fs.existsSync ||\n path.existsSync,\n defaults = {\n arrow: process.env.NODE_BINDINGS_ARROW || ' → ',\n compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled',\n platform: process.platform,\n arch: process.arch,\n nodePreGyp:\n 'node-v' +\n process.versions.modules +\n '-' +\n process.platform +\n '-' +\n process.arch,\n version: process.versions.node,\n bindings: 'bindings.node',\n try: [\n // node-gyp's linked version in the \"build\" dir\n ['module_root', 'build', 'bindings'],\n // node-waf and gyp_addon (a.k.a node-gyp)\n ['module_root', 'build', 'Debug', 'bindings'],\n ['module_root', 'build', 'Release', 'bindings'],\n // Debug files, for development (legacy behavior, remove for node v0.9)\n ['module_root', 'out', 'Debug', 'bindings'],\n ['module_root', 'Debug', 'bindings'],\n // Release files, but manually compiled (legacy behavior, remove for node v0.9)\n ['module_root', 'out', 'Release', 'bindings'],\n ['module_root', 'Release', 'bindings'],\n // Legacy from node-waf, node <= 0.4.x\n ['module_root', 'build', 'default', 'bindings'],\n // Production \"Release\" buildtype binary (meh...)\n ['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'],\n // node-qbs builds\n ['module_root', 'addon-build', 'release', 'install-root', 'bindings'],\n ['module_root', 'addon-build', 'debug', 'install-root', 'bindings'],\n ['module_root', 'addon-build', 'default', 'install-root', 'bindings'],\n // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}\n ['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings']\n ]\n };\n\n/**\n * The main `bindings()` function loads the compiled bindings for a given module.\n * It uses V8's Error API to determine the parent filename that this function is\n * being invoked from, which is then used to find the root directory.\n */\n\nfunction bindings(opts) {\n // Argument surgery\n if (typeof opts == 'string') {\n opts = { bindings: opts };\n } else if (!opts) {\n opts = {};\n }\n\n // maps `defaults` onto `opts` object\n Object.keys(defaults).map(function(i) {\n if (!(i in opts)) opts[i] = defaults[i];\n });\n\n // Get the module root\n if (!opts.module_root) {\n opts.module_root = exports.getRoot(exports.getFileName());\n }\n\n // Ensure the given bindings name ends with .node\n if (path.extname(opts.bindings) != '.node') {\n opts.bindings += '.node';\n }\n\n // https://github.com/webpack/webpack/issues/4175#issuecomment-342931035\n var requireFunc =\n typeof __webpack_require__ === 'function'\n ? __non_webpack_require__\n : require;\n\n var tries = [],\n i = 0,\n l = opts.try.length,\n n,\n b,\n err;\n\n for (; i < l; i++) {\n n = join.apply(\n null,\n opts.try[i].map(function(p) {\n return opts[p] || p;\n })\n );\n tries.push(n);\n try {\n b = opts.path ? requireFunc.resolve(n) : requireFunc(n);\n if (!opts.path) {\n b.path = n;\n }\n return b;\n } catch (e) {\n if (e.code !== 'MODULE_NOT_FOUND' &&\n e.code !== 'QUALIFIED_PATH_RESOLUTION_FAILED' &&\n !/not find/i.test(e.message)) {\n throw e;\n }\n }\n }\n\n err = new Error(\n 'Could not locate the bindings file. Tried:\\n' +\n tries\n .map(function(a) {\n return opts.arrow + a;\n })\n .join('\\n')\n );\n err.tries = tries;\n throw err;\n}\nmodule.exports = exports = bindings;\n\n/**\n * Gets the filename of the JavaScript file that invokes this function.\n * Used to help find the root directory of a module.\n * Optionally accepts an filename argument to skip when searching for the invoking filename\n */\n\nexports.getFileName = function getFileName(calling_file) {\n var origPST = Error.prepareStackTrace,\n origSTL = Error.stackTraceLimit,\n dummy = {},\n fileName;\n\n Error.stackTraceLimit = 10;\n\n Error.prepareStackTrace = function(e, st) {\n for (var i = 0, l = st.length; i < l; i++) {\n fileName = st[i].getFileName();\n if (fileName !== __filename) {\n if (calling_file) {\n if (fileName !== calling_file) {\n return;\n }\n } else {\n return;\n }\n }\n }\n };\n\n // run the 'prepareStackTrace' function above\n Error.captureStackTrace(dummy);\n dummy.stack;\n\n // cleanup\n Error.prepareStackTrace = origPST;\n Error.stackTraceLimit = origSTL;\n\n // handle filename that starts with \"file://\"\n var fileSchema = 'file://';\n if (fileName.indexOf(fileSchema) === 0) {\n fileName = fileURLToPath(fileName);\n }\n\n return fileName;\n};\n\n/**\n * Gets the root directory of a module, given an arbitrary filename\n * somewhere in the module tree. The \"root directory\" is the directory\n * containing the `package.json` file.\n *\n * In: /home/nate/node-native-module/lib/index.js\n * Out: /home/nate/node-native-module\n */\n\nexports.getRoot = function getRoot(file) {\n var dir = dirname(file),\n prev;\n while (true) {\n if (dir === '.') {\n // Avoids an infinite loop in rare cases, like the REPL\n dir = process.cwd();\n }\n if (\n exists(join(dir, 'package.json')) ||\n exists(join(dir, 'node_modules'))\n ) {\n // Found the 'package.json' file or 'node_modules' dir; we're done\n return dir;\n }\n if (prev === dir) {\n // Got to the top\n throw new Error(\n 'Could not find module root given file: \"' +\n file +\n '\". Do you have a `package.json` file? '\n );\n }\n // Try the parent dir next\n prev = dir;\n dir = join(dir, '..');\n }\n};\n","'use strict';\nconst { cppdb } = require('../util');\n\nexports.prepare = function prepare(sql) {\n\treturn this[cppdb].prepare(sql, this, false);\n};\n\nexports.exec = function exec(sql) {\n\tthis[cppdb].exec(sql);\n\treturn this;\n};\n\nexports.close = function close() {\n\tthis[cppdb].close();\n\treturn this;\n};\n\nexports.loadExtension = function loadExtension(...args) {\n\tthis[cppdb].loadExtension(...args);\n\treturn this;\n};\n\nexports.defaultSafeIntegers = function defaultSafeIntegers(...args) {\n\tthis[cppdb].defaultSafeIntegers(...args);\n\treturn this;\n};\n\nexports.unsafeMode = function unsafeMode(...args) {\n\tthis[cppdb].unsafeMode(...args);\n\treturn this;\n};\n\nexports.getters = {\n\tname: {\n\t\tget: function name() { return this[cppdb].name; },\n\t\tenumerable: true,\n\t},\n\topen: {\n\t\tget: function open() { return this[cppdb].open; },\n\t\tenumerable: true,\n\t},\n\tinTransaction: {\n\t\tget: function inTransaction() { return this[cppdb].inTransaction; },\n\t\tenumerable: true,\n\t},\n\treadonly: {\n\t\tget: function readonly() { return this[cppdb].readonly; },\n\t\tenumerable: true,\n\t},\n\tmemory: {\n\t\tget: function memory() { return this[cppdb].memory; },\n\t\tenumerable: true,\n\t},\n};\n","'use strict';\nconst { cppdb } = require('../util');\nconst controllers = new WeakMap();\n\nmodule.exports = function transaction(fn) {\n\tif (typeof fn !== 'function') throw new TypeError('Expected first argument to be a function');\n\n\tconst db = this[cppdb];\n\tconst controller = getController(db, this);\n\tconst { apply } = Function.prototype;\n\n\t// Each version of the transaction function has these same properties\n\tconst properties = {\n\t\tdefault: { value: wrapTransaction(apply, fn, db, controller.default) },\n\t\tdeferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },\n\t\timmediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },\n\t\texclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },\n\t\tdatabase: { value: this, enumerable: true },\n\t};\n\n\tObject.defineProperties(properties.default.value, properties);\n\tObject.defineProperties(properties.deferred.value, properties);\n\tObject.defineProperties(properties.immediate.value, properties);\n\tObject.defineProperties(properties.exclusive.value, properties);\n\n\t// Return the default version of the transaction function\n\treturn properties.default.value;\n};\n\n// Return the database's cached transaction controller, or create a new one\nconst getController = (db, self) => {\n\tlet controller = controllers.get(db);\n\tif (!controller) {\n\t\tconst shared = {\n\t\t\tcommit: db.prepare('COMMIT', self, false),\n\t\t\trollback: db.prepare('ROLLBACK', self, false),\n\t\t\tsavepoint: db.prepare('SAVEPOINT `\\t_bs3.\\t`', self, false),\n\t\t\trelease: db.prepare('RELEASE `\\t_bs3.\\t`', self, false),\n\t\t\trollbackTo: db.prepare('ROLLBACK TO `\\t_bs3.\\t`', self, false),\n\t\t};\n\t\tcontrollers.set(db, controller = {\n\t\t\tdefault: Object.assign({ begin: db.prepare('BEGIN', self, false) }, shared),\n\t\t\tdeferred: Object.assign({ begin: db.prepare('BEGIN DEFERRED', self, false) }, shared),\n\t\t\timmediate: Object.assign({ begin: db.prepare('BEGIN IMMEDIATE', self, false) }, shared),\n\t\t\texclusive: Object.assign({ begin: db.prepare('BEGIN EXCLUSIVE', self, false) }, shared),\n\t\t});\n\t}\n\treturn controller;\n};\n\n// Return a new transaction function by wrapping the given function\nconst wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {\n\tlet before, after, undo;\n\tif (db.inTransaction) {\n\t\tbefore = savepoint;\n\t\tafter = release;\n\t\tundo = rollbackTo;\n\t} else {\n\t\tbefore = begin;\n\t\tafter = commit;\n\t\tundo = rollback;\n\t}\n\tbefore.run();\n\ttry {\n\t\tconst result = apply.call(fn, this, arguments);\n\t\tif (result && typeof result.then === 'function') {\n\t\t\tthrow new TypeError('Transaction function cannot return a promise');\n\t\t}\n\t\tafter.run();\n\t\treturn result;\n\t} catch (ex) {\n\t\tif (db.inTransaction) {\n\t\t\tundo.run();\n\t\t\tif (undo !== rollback) after.run();\n\t\t}\n\t\tthrow ex;\n\t}\n};\n","'use strict';\nconst { getBooleanOption, cppdb } = require('../util');\n\nmodule.exports = function pragma(source, options) {\n\tif (options == null) options = {};\n\tif (typeof source !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\tconst simple = getBooleanOption(options, 'simple');\n\n\tconst stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);\n\treturn simple ? stmt.pluck().get() : stmt.all();\n};\n","'use strict';\nconst fs = require('fs');\nconst path = require('path');\nconst { promisify } = require('util');\nconst { cppdb } = require('../util');\nconst fsAccess = promisify(fs.access);\n\nmodule.exports = async function backup(filename, options) {\n\tif (options == null) options = {};\n\n\t// Validate arguments\n\tif (typeof filename !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\n\t// Interpret options\n\tfilename = filename.trim();\n\tconst attachedName = 'attached' in options ? options.attached : 'main';\n\tconst handler = 'progress' in options ? options.progress : null;\n\n\t// Validate interpreted options\n\tif (!filename) throw new TypeError('Backup filename cannot be an empty string');\n\tif (filename === ':memory:') throw new TypeError('Invalid backup filename \":memory:\"');\n\tif (typeof attachedName !== 'string') throw new TypeError('Expected the \"attached\" option to be a string');\n\tif (!attachedName) throw new TypeError('The \"attached\" option cannot be an empty string');\n\tif (handler != null && typeof handler !== 'function') throw new TypeError('Expected the \"progress\" option to be a function');\n\n\t// Make sure the specified directory exists\n\tawait fsAccess(path.dirname(filename)).catch(() => {\n\t\tthrow new TypeError('Cannot save backup because the directory does not exist');\n\t});\n\n\tconst isNewFile = await fsAccess(filename).then(() => false, () => true);\n\treturn runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);\n};\n\nconst runBackup = (backup, handler) => {\n\tlet rate = 0;\n\tlet useDefault = true;\n\n\treturn new Promise((resolve, reject) => {\n\t\tsetImmediate(function step() {\n\t\t\ttry {\n\t\t\t\tconst progress = backup.transfer(rate);\n\t\t\t\tif (!progress.remainingPages) {\n\t\t\t\t\tbackup.close();\n\t\t\t\t\tresolve(progress);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (useDefault) {\n\t\t\t\t\tuseDefault = false;\n\t\t\t\t\trate = 100;\n\t\t\t\t}\n\t\t\t\tif (handler) {\n\t\t\t\t\tconst ret = handler(progress);\n\t\t\t\t\tif (ret !== undefined) {\n\t\t\t\t\t\tif (typeof ret === 'number' && ret === ret) rate = Math.max(0, Math.min(0x7fffffff, Math.round(ret)));\n\t\t\t\t\t\telse throw new TypeError('Expected progress callback to return a number or undefined');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsetImmediate(step);\n\t\t\t} catch (err) {\n\t\t\t\tbackup.close();\n\t\t\t\treject(err);\n\t\t\t}\n\t\t});\n\t});\n};\n","'use strict';\nconst { cppdb } = require('../util');\n\nmodule.exports = function serialize(options) {\n\tif (options == null) options = {};\n\n\t// Validate arguments\n\tif (typeof options !== 'object') throw new TypeError('Expected first argument to be an options object');\n\n\t// Interpret and validate options\n\tconst attachedName = 'attached' in options ? options.attached : 'main';\n\tif (typeof attachedName !== 'string') throw new TypeError('Expected the \"attached\" option to be a string');\n\tif (!attachedName) throw new TypeError('The \"attached\" option cannot be an empty string');\n\n\treturn this[cppdb].serialize(attachedName);\n};\n","'use strict';\nconst { getBooleanOption, cppdb } = require('../util');\n\nmodule.exports = function defineFunction(name, options, fn) {\n\t// Apply defaults\n\tif (options == null) options = {};\n\tif (typeof options === 'function') { fn = options; options = {}; }\n\n\t// Validate arguments\n\tif (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof fn !== 'function') throw new TypeError('Expected last argument to be a function');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\tif (!name) throw new TypeError('User-defined function name cannot be an empty string');\n\n\t// Interpret options\n\tconst safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;\n\tconst deterministic = getBooleanOption(options, 'deterministic');\n\tconst directOnly = getBooleanOption(options, 'directOnly');\n\tconst varargs = getBooleanOption(options, 'varargs');\n\tlet argCount = -1;\n\n\t// Determine argument count\n\tif (!varargs) {\n\t\targCount = fn.length;\n\t\tif (!Number.isInteger(argCount) || argCount < 0) throw new TypeError('Expected function.length to be a positive integer');\n\t\tif (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');\n\t}\n\n\tthis[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);\n\treturn this;\n};\n","'use strict';\nconst { getBooleanOption, cppdb } = require('../util');\n\nmodule.exports = function defineAggregate(name, options) {\n\t// Validate arguments\n\tif (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object' || options === null) throw new TypeError('Expected second argument to be an options object');\n\tif (!name) throw new TypeError('User-defined function name cannot be an empty string');\n\n\t// Interpret options\n\tconst start = 'start' in options ? options.start : null;\n\tconst step = getFunctionOption(options, 'step', true);\n\tconst inverse = getFunctionOption(options, 'inverse', false);\n\tconst result = getFunctionOption(options, 'result', false);\n\tconst safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;\n\tconst deterministic = getBooleanOption(options, 'deterministic');\n\tconst directOnly = getBooleanOption(options, 'directOnly');\n\tconst varargs = getBooleanOption(options, 'varargs');\n\tlet argCount = -1;\n\n\t// Determine argument count\n\tif (!varargs) {\n\t\targCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);\n\t\tif (argCount > 0) argCount -= 1;\n\t\tif (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');\n\t}\n\n\tthis[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);\n\treturn this;\n};\n\nconst getFunctionOption = (options, key, required) => {\n\tconst value = key in options ? options[key] : null;\n\tif (typeof value === 'function') return value;\n\tif (value != null) throw new TypeError(`Expected the \"${key}\" option to be a function`);\n\tif (required) throw new TypeError(`Missing required option \"${key}\"`);\n\treturn null;\n};\n\nconst getLength = ({ length }) => {\n\tif (Number.isInteger(length) && length >= 0) return length;\n\tthrow new TypeError('Expected function.length to be a positive integer');\n};\n","'use strict';\nconst { cppdb } = require('../util');\n\nmodule.exports = function defineTable(name, factory) {\n\t// Validate arguments\n\tif (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (!name) throw new TypeError('Virtual table module name cannot be an empty string');\n\n\t// Determine whether the module is eponymous-only or not\n\tlet eponymous = false;\n\tif (typeof factory === 'object' && factory !== null) {\n\t\teponymous = true;\n\t\tfactory = defer(parseTableDefinition(factory, 'used', name));\n\t} else {\n\t\tif (typeof factory !== 'function') throw new TypeError('Expected second argument to be a function or a table definition object');\n\t\tfactory = wrapFactory(factory);\n\t}\n\n\tthis[cppdb].table(factory, name, eponymous);\n\treturn this;\n};\n\nfunction wrapFactory(factory) {\n\treturn function virtualTableFactory(moduleName, databaseName, tableName, ...args) {\n\t\tconst thisObject = {\n\t\t\tmodule: moduleName,\n\t\t\tdatabase: databaseName,\n\t\t\ttable: tableName,\n\t\t};\n\n\t\t// Generate a new table definition by invoking the factory\n\t\tconst def = apply.call(factory, thisObject, args);\n\t\tif (typeof def !== 'object' || def === null) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" did not return a table definition object`);\n\t\t}\n\n\t\treturn parseTableDefinition(def, 'returned', moduleName);\n\t};\n}\n\nfunction parseTableDefinition(def, verb, moduleName) {\n\t// Validate required properties\n\tif (!hasOwnProperty.call(def, 'rows')) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition without a \"rows\" property`);\n\t}\n\tif (!hasOwnProperty.call(def, 'columns')) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition without a \"columns\" property`);\n\t}\n\n\t// Validate \"rows\" property\n\tconst rows = def.rows;\n\tif (typeof rows !== 'function' || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"rows\" property (should be a generator function)`);\n\t}\n\n\t// Validate \"columns\" property\n\tlet columns = def.columns;\n\tif (!Array.isArray(columns) || !(columns = [...columns]).every(x => typeof x === 'string')) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"columns\" property (should be an array of strings)`);\n\t}\n\tif (columns.length !== new Set(columns).size) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with duplicate column names`);\n\t}\n\tif (!columns.length) {\n\t\tthrow new RangeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with zero columns`);\n\t}\n\n\t// Validate \"parameters\" property\n\tlet parameters;\n\tif (hasOwnProperty.call(def, 'parameters')) {\n\t\tparameters = def.parameters;\n\t\tif (!Array.isArray(parameters) || !(parameters = [...parameters]).every(x => typeof x === 'string')) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"parameters\" property (should be an array of strings)`);\n\t\t}\n\t} else {\n\t\tparameters = inferParameters(rows);\n\t}\n\tif (parameters.length !== new Set(parameters).size) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with duplicate parameter names`);\n\t}\n\tif (parameters.length > 32) {\n\t\tthrow new RangeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with more than the maximum number of 32 parameters`);\n\t}\n\tfor (const parameter of parameters) {\n\t\tif (columns.includes(parameter)) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with column \"${parameter}\" which was ambiguously defined as both a column and parameter`);\n\t\t}\n\t}\n\n\t// Validate \"safeIntegers\" option\n\tlet safeIntegers = 2;\n\tif (hasOwnProperty.call(def, 'safeIntegers')) {\n\t\tconst bool = def.safeIntegers;\n\t\tif (typeof bool !== 'boolean') {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"safeIntegers\" property (should be a boolean)`);\n\t\t}\n\t\tsafeIntegers = +bool;\n\t}\n\n\t// Validate \"directOnly\" option\n\tlet directOnly = false;\n\tif (hasOwnProperty.call(def, 'directOnly')) {\n\t\tdirectOnly = def.directOnly;\n\t\tif (typeof directOnly !== 'boolean') {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"directOnly\" property (should be a boolean)`);\n\t\t}\n\t}\n\n\t// Generate SQL for the virtual table definition\n\tconst columnDefinitions = [\n\t\t...parameters.map(identifier).map(str => `${str} HIDDEN`),\n\t\t...columns.map(identifier),\n\t];\n\treturn [\n\t\t`CREATE TABLE x(${columnDefinitions.join(', ')});`,\n\t\twrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),\n\t\tparameters,\n\t\tsafeIntegers,\n\t\tdirectOnly,\n\t];\n}\n\nfunction wrapGenerator(generator, columnMap, moduleName) {\n\treturn function* virtualTable(...args) {\n\t\t/*\n\t\t\tWe must defensively clone any buffers in the arguments, because\n\t\t\totherwise the generator could mutate one of them, which would cause\n\t\t\tus to return incorrect values for hidden columns, potentially\n\t\t\tcorrupting the database.\n\t\t */\n\t\tconst output = args.map(x => Buffer.isBuffer(x) ? Buffer.from(x) : x);\n\t\tfor (let i = 0; i < columnMap.size; ++i) {\n\t\t\toutput.push(null); // Fill with nulls to prevent gaps in array (v8 optimization)\n\t\t}\n\t\tfor (const row of generator(...args)) {\n\t\t\tif (Array.isArray(row)) {\n\t\t\t\textractRowArray(row, output, columnMap.size, moduleName);\n\t\t\t\tyield output;\n\t\t\t} else if (typeof row === 'object' && row !== null) {\n\t\t\t\textractRowObject(row, output, columnMap, moduleName);\n\t\t\t\tyield output;\n\t\t\t} else {\n\t\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded something that isn't a valid row object`);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction extractRowArray(row, output, columnCount, moduleName) {\n\tif (row.length !== columnCount) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded a row with an incorrect number of columns`);\n\t}\n\tconst offset = output.length - columnCount;\n\tfor (let i = 0; i < columnCount; ++i) {\n\t\toutput[i + offset] = row[i];\n\t}\n}\n\nfunction extractRowObject(row, output, columnMap, moduleName) {\n\tlet count = 0;\n\tfor (const key of Object.keys(row)) {\n\t\tconst index = columnMap.get(key);\n\t\tif (index === undefined) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded a row with an undeclared column \"${key}\"`);\n\t\t}\n\t\toutput[index] = row[key];\n\t\tcount += 1;\n\t}\n\tif (count !== columnMap.size) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded a row with missing columns`);\n\t}\n}\n\nfunction inferParameters({ length }) {\n\tif (!Number.isInteger(length) || length < 0) {\n\t\tthrow new TypeError('Expected function.length to be a positive integer');\n\t}\n\tconst params = [];\n\tfor (let i = 0; i < length; ++i) {\n\t\tparams.push(`$${i + 1}`);\n\t}\n\treturn params;\n}\n\nconst { hasOwnProperty } = Object.prototype;\nconst { apply } = Function.prototype;\nconst GeneratorFunctionPrototype = Object.getPrototypeOf(function*(){});\nconst identifier = str => `\"${str.replace(/\"/g, '\"\"')}\"`;\nconst defer = x => () => x;\n","'use strict';\nconst DatabaseInspection = function Database() {};\n\nmodule.exports = function inspect(depth, opts) {\n\treturn Object.assign(new DatabaseInspection(), this);\n};\n\n","'use strict';\nconst fs = require('fs');\nconst path = require('path');\nconst util = require('./util');\nconst SqliteError = require('./sqlite-error');\n\nlet DEFAULT_ADDON;\n\nfunction Database(filenameGiven, options) {\n\tif (new.target == null) {\n\t\treturn new Database(filenameGiven, options);\n\t}\n\n\t// Apply defaults\n\tlet buffer;\n\tif (Buffer.isBuffer(filenameGiven)) {\n\t\tbuffer = filenameGiven;\n\t\tfilenameGiven = ':memory:';\n\t}\n\tif (filenameGiven == null) filenameGiven = '';\n\tif (options == null) options = {};\n\n\t// Validate arguments\n\tif (typeof filenameGiven !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\tif ('readOnly' in options) throw new TypeError('Misspelled option \"readOnly\" should be \"readonly\"');\n\tif ('memory' in options) throw new TypeError('Option \"memory\" was removed in v7.0.0 (use \":memory:\" filename instead)');\n\n\t// Interpret options\n\tconst filename = filenameGiven.trim();\n\tconst anonymous = filename === '' || filename === ':memory:';\n\tconst readonly = util.getBooleanOption(options, 'readonly');\n\tconst fileMustExist = util.getBooleanOption(options, 'fileMustExist');\n\tconst timeout = 'timeout' in options ? options.timeout : 5000;\n\tconst verbose = 'verbose' in options ? options.verbose : null;\n\tconst nativeBinding = 'nativeBinding' in options ? options.nativeBinding : null;\n\n\t// Validate interpreted options\n\tif (readonly && anonymous && !buffer) throw new TypeError('In-memory/temporary databases cannot be readonly');\n\tif (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the \"timeout\" option to be a positive integer');\n\tif (timeout > 0x7fffffff) throw new RangeError('Option \"timeout\" cannot be greater than 2147483647');\n\tif (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the \"verbose\" option to be a function');\n\tif (nativeBinding != null && typeof nativeBinding !== 'string' && typeof nativeBinding !== 'object') throw new TypeError('Expected the \"nativeBinding\" option to be a string or addon object');\n\n\t// Load the native addon\n\tlet addon;\n\tif (nativeBinding == null) {\n\t\taddon = DEFAULT_ADDON || (DEFAULT_ADDON = require('bindings')('better_sqlite3.node'));\n\t} else if (typeof nativeBinding === 'string') {\n\t\t// See <https://webpack.js.org/api/module-variables/#__non_webpack_require__-webpack-specific>\n\t\tconst requireFunc = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : require;\n\t\taddon = requireFunc(path.resolve(nativeBinding).replace(/(\\.node)?$/, '.node'));\n\t} else {\n\t\t// See <https://github.com/WiseLibs/better-sqlite3/issues/972>\n\t\taddon = nativeBinding;\n\t}\n\n\tif (!addon.isInitialized) {\n\t\taddon.setErrorConstructor(SqliteError);\n\t\taddon.isInitialized = true;\n\t}\n\n\t// Make sure the specified directory exists\n\tif (!anonymous && !fs.existsSync(path.dirname(filename))) {\n\t\tthrow new TypeError('Cannot open database because the directory does not exist');\n\t}\n\n\tObject.defineProperties(this, {\n\t\t[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },\n\t\t...wrappers.getters,\n\t});\n}\n\nconst wrappers = require('./methods/wrappers');\nDatabase.prototype.prepare = wrappers.prepare;\nDatabase.prototype.transaction = require('./methods/transaction');\nDatabase.prototype.pragma = require('./methods/pragma');\nDatabase.prototype.backup = require('./methods/backup');\nDatabase.prototype.serialize = require('./methods/serialize');\nDatabase.prototype.function = require('./methods/function');\nDatabase.prototype.aggregate = require('./methods/aggregate');\nDatabase.prototype.table = require('./methods/table');\nDatabase.prototype.loadExtension = wrappers.loadExtension;\nDatabase.prototype.exec = wrappers.exec;\nDatabase.prototype.close = wrappers.close;\nDatabase.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;\nDatabase.prototype.unsafeMode = wrappers.unsafeMode;\nDatabase.prototype[util.inspect] = require('./methods/inspect');\n\nmodule.exports = Database;\n","'use strict';\nmodule.exports = require('./database');\nmodule.exports.SqliteError = require('./sqlite-error');\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 // --port 0 表示\"自动从 9090 开始找空闲端口\"\n if (port === 0) port = 9090;\n\n // startServer 内部 findFreePort:port 被占自动找空闲端口。\n const server = await startServer(host, port);\n console.log(`Listening on http://${host}:${server.port}`);\n // 必须 await serve():其内部 honoServe 起阻塞循环让进程常驻,\n // 未 await 时 main() 返回后 Node 见无 pending 任务直接 exit 0。\n await 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 try {\n execSync('sudo -n true', { stdio: 'ignore', timeout: 5000 });\n } catch {\n console.log('⚠️ 无 sudo 权限,跳过 systemd service 安装');\n console.log(' 手动启动:agent-moss server --port 0');\n process.exit(0);\n }\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\n// Only run the CLI when this file is the entry point, so the package can also\n// be imported as a library (see `exports` in package.json) without triggering\n// main() and process.exit().\nimport { fileURLToPath } from 'node:url';\nimport { realpathSync } from 'node:fs';\nconst isMain = (() => {\n try {\n if (!process.argv[1]) return false;\n // 兼容两种 spawn 方式:\n // ① node /path/to/cli.js — argv[1] 是普通路径\n // ② node file:///path/to/cli.js — argv[1] 是 file:// URL(少见)\n // realpath 规范化两端,规避 symlink / 大小写 / file:// 协议差异导致的误判。\n const thisFile = realpathSync(fileURLToPath(import.meta.url));\n const argv1 = realpathSync(\n process.argv[1].startsWith('file://') ? fileURLToPath(process.argv[1]) : process.argv[1]\n );\n return thisFile === argv1;\n } catch {\n return false;\n }\n})();\n\nif (isMain) {\n main().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n });\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: () => Promise<void>; port: number }> {\n const actualPort = await findFreePort(port, host);\n const app = createApp();\n return {\n port: actualPort,\n serve: async () => {\n console.log(`AgentMoss HTTP server on ${host}:${actualPort}`);\n // @hono/node-server 动态 import(ESM 下 require 不可用)\n // 必须 await:honoServe 会起阻塞循环让进程常驻,未 await 时 main() 返回后 Node\n // 见无 pending 任务直接 exit 0,server 起不来。\n const { serve: honoServe } = await import('@hono/node-server');\n honoServe({ fetch: app.fetch, hostname: host, port: actualPort });\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 instance: process.env.AGENT_MOSS_INSTANCE || '',\n }));\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 // agent_id 透传:优先顶层;为空兜底 metadata.agent_type(AgentGate V1\n // normalizer 历史上只把 agent_type 塞进 metadata,顶层 agent_id 为空 →\n // 定制规则不生效。AgentGate 已修,此处兜底防御其他只传 metadata 的调用方)。\n agentId: req.agent_id || (req.metadata as any)?.agent_type || '',\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 // 归属实例标识:值来自 env AGENT_MOSS_INSTANCE(spawn/systemd 注入),默认空串。\n // 多个 agentmoss 同机并存时,调用方按 instance 过滤避免连到别人的进程。\n // 空=未配置(独立部署或旧版),调用方可选择兼容或严格过滤。\n instance: z.string().default(''),\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 getAgentRules, updateAgentRuleEnabled, addAgentRule, deleteAgentRule,\n updateAgentCategoryEnabled,\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, env_overrides: getEnvOverrides() });\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, env_overrides: getEnvOverrides() });\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(rc);\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(rc);\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(rc);\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(rc);\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(rc);\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(rc);\n });\n\n // ==================== Skill 管理 ====================\n console.get('/api/skills', (c) => {\n const rc = loadRuntimeConfig();\n return c.json(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(rc);\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(rc);\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(rc);\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(rc);\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 // ==================== agent 定制规则 ====================\n console.get('/api/agents', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.put('/api/agents/rules/enabled', async (c) => {\n const b = await c.req.json();\n const fp: Record<string, string> = {};\n if (b.value) fp.value = b.value;\n if (b.pattern) fp.pattern = b.pattern;\n if (b.keyword) fp.keyword = b.keyword;\n if (b.path) fp.path = b.path;\n const rc = updateAgentRuleEnabled(b.agent_id, b.category, fp, b.enabled);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.post('/api/agents/rules', async (c) => {\n const b = await c.req.json();\n const rule: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(b)) {\n if (!['agent_id', 'category'].includes(k) && v !== undefined && v !== null) rule[k] = v;\n }\n const rc = addAgentRule(b.agent_id, b.category, rule);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.delete('/api/agents/rules', async (c) => {\n const b = await c.req.json();\n const fp: Record<string, string> = {};\n if (b.value) fp.value = b.value;\n if (b.pattern) fp.pattern = b.pattern;\n if (b.keyword) fp.keyword = b.keyword;\n if (b.path) fp.path = b.path;\n const rc = deleteAgentRule(b.agent_id, b.category, fp);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.put('/api/agents/categories/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateAgentCategoryEnabled(b.agent_id, b.category, b.enabled);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n // ==================== 配置 / env / reset ====================\n // 契约对齐:Python console/router.py 的 /api/config 直接返回完整 runtime config\n // (顶层含 L1_rules/L2_rules/L3_skills/layers),前端 state.config 读取顶层字段。\n // 之前 TS 返回 {config, config_path} 包装导致前端 L1/L2/L3 标签页全空(数据丢)。\n console.get('/api/config', (c) => {\n const rc = loadRuntimeConfig();\n return c.json(rc);\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(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 // 与 Python 契约一致:返回裸数组(前端按 records.length 读)\n return c.json(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","OpenAI","fs","path","READ_KEYWORDS","WRITE_KEYWORDS","readFileSync","readdirSync","existsSync","fileURLToPath","__filename","__dirname","readFileSync","existsSync","readdirSync","join","fileURLToPath","dirname","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","hasRuntimeConfig","loadRuntimeConfig","getEnabledAgentExtensions","__filename","__dirname","path","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","join","readFileSync","existsSync","resolve","join","dirname","homedir","path","scanScriptForKeywords","SUSPICIOUS_PATTERNS","assessKeywordCombinationRisk","KEYWORD_COMBINATION_RISKS","SINGLE_KEYWORD_RISKS","LEVEL_ORDER","extractScriptPath","SCRIPT_EXEC_PATTERNS","readScriptContent","node","analyzeScriptContent","parts","readFileSync","writeFileSync","existsSync","mkdirSync","unlinkSync","recordTokenUsage","resolve","main","analyzeScriptContent","getDisabledL2RulesWithSkipL3","getLLMFailMode","path","fs","path","fileURLToPath","join","dirname","i","fs","path","resolve","fs","path","Hono","require","fs","readFileSync","existsSync","join","dirname","fileURLToPath","__dirname","console","Hono","resolve","fileURLToPath","fs","path","runAnalysis","__filename","__dirname","version","resolve"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/infra/paths.ts","../src/config.ts","../src/engine/inline-analyzer.ts","../src/engine/logic-rules.ts","../src/engine/skill-loader.ts","../src/infra/runtime-config.ts","../src/agents/index.ts","../src/engine/heuristic.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/engine/coordinator.ts","../node_modules/better-sqlite3/lib/util.js","../node_modules/better-sqlite3/lib/sqlite-error.js","../node_modules/file-uri-to-path/index.js","../node_modules/bindings/bindings.js","../node_modules/better-sqlite3/lib/methods/wrappers.js","../node_modules/better-sqlite3/lib/methods/transaction.js","../node_modules/better-sqlite3/lib/methods/pragma.js","../node_modules/better-sqlite3/lib/methods/backup.js","../node_modules/better-sqlite3/lib/methods/serialize.js","../node_modules/better-sqlite3/lib/methods/function.js","../node_modules/better-sqlite3/lib/methods/aggregate.js","../node_modules/better-sqlite3/lib/methods/table.js","../node_modules/better-sqlite3/lib/methods/inspect.js","../node_modules/better-sqlite3/lib/database.js","../node_modules/better-sqlite3/lib/index.js","../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","/**\n * Path resolution — unified data root + multi-instance (instance) isolation.\n *\n * Mirrors Python agent_moss/infra/paths.py.\n *\n * Solves two problems:\n * 1. Data-owner user directory: even when the service runs as root/systemd\n * (started via `sudo systemctl`), AGENT_MOSS_DATA_DIR can point it at the\n * \"current user\"'s data dir, so config / runtime / token all land in that\n * user's directory instead of root's /root. Falls back to\n * ~/.config/agentmoss (legacy behavior) when unset.\n *\n * 2. Token isolation by instance: services started by different agents\n * (AGENT_MOSS_INSTANCE) don't share token-usage files. With an instance,\n * tokens go to <data_root>/<instance>/agent_moss_token_stats.json; without\n * one, to <data_root>/agent_moss_token_stats.json (default location).\n *\n * config / runtime are NOT split by instance (rules/config are shared); they\n * only follow the data root.\n */\n\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { readFileSync } from 'fs';\n\nconst ENV_DATA_ROOT = 'AGENT_MOSS_DATA_DIR';\nconst ENV_INSTANCE = 'AGENT_MOSS_INSTANCE';\n\nconst DEFAULT_DATA_ROOT = join(homedir(), '.config', 'agentmoss');\n\n/** True when the process runs as root (systemd `sudo systemctl`). */\nexport function isRoot(): boolean {\n const getuid = (process as any).getuid;\n return typeof getuid === 'function' && getuid() === 0;\n}\n\n/** Resolve the \"real user\"'s home when running as root.\n * Priority: SUDO_USER (sudo invoker) > LOGNAME/USER (login user) >\n * first UID>=1000 ordinary user in /etc/passwd. Returns null if none found. */\nexport function resolveOwnerHome(): string | null {\n for (const name of [process.env.SUDO_USER, process.env.LOGNAME, process.env.USER]) {\n if (name && name !== 'root' && name !== '') {\n const home = homeOf(name);\n if (home) return home;\n }\n }\n // /etc/passwd fallback: first UID>=1000 ordinary user\n try {\n const passwd = readFileSync('/etc/passwd', 'utf-8');\n for (const line of passwd.split('\\n')) {\n if (!line || line.startsWith('#')) continue;\n const parts = line.split(':');\n if (parts.length < 6) continue;\n const uid = parseInt(parts[2], 10);\n const name = parts[0];\n if (uid >= 1000 && name && !name.startsWith('_')) {\n return parts[5];\n }\n }\n } catch { /* ignore */ }\n return null;\n}\n\nfunction homeOf(name: string): string | null {\n try {\n const passwd = readFileSync('/etc/passwd', 'utf-8');\n for (const line of passwd.split('\\n')) {\n if (!line || line.startsWith('#')) continue;\n const parts = line.split(':');\n if (parts.length >= 6 && parts[0] === name) {\n return parts[5];\n }\n }\n } catch { /* ignore */ }\n return null;\n}\n\n/** Data root directory.\n * Priority: env AGENT_MOSS_DATA_DIR > ~/.config/agentmoss.\n * BUT when running as root (any `sudo systemctl` service), automatically\n * redirects to the real user's dir so config/runtime/token land there\n * instead of /root. */\nexport function getDataRoot(): string {\n const envPath = process.env[ENV_DATA_ROOT];\n if (envPath) return envPath;\n if (isRoot()) {\n const ownerHome = resolveOwnerHome();\n if (ownerHome) {\n return join(ownerHome, '.config', 'agentmoss');\n }\n }\n return DEFAULT_DATA_ROOT;\n}\n\n/** Instance identifier (empty string when unset). */\nexport function getInstance(): string {\n const v = process.env[ENV_INSTANCE] || '';\n return v.trim().replace(/^[/\\\\]+|[/\\\\]+$/g, '');\n}\n\n/** Config file directory (config.json). Not split by instance; follows data root. */\nexport function getConfigDir(): string {\n return getDataRoot();\n}\n\n/** Runtime config directory (agent_moss_runtime.json + skills dir). Not split by instance. */\nexport function getRuntimeConfigDir(): string {\n return getDataRoot();\n}\n\n/**\n * Token stats file path.\n * With instance → <data_root>/<instance>/agent_moss_token_stats.json\n * Without → <data_root>/agent_moss_token_stats.json\n */\nexport function getTokenStatsPath(): string {\n const instance = getInstance();\n if (instance) {\n return join(getDataRoot(), instance, 'agent_moss_token_stats.json');\n }\n return join(getDataRoot(), 'agent_moss_token_stats.json');\n}","import fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport type { LLMConfig, TimeoutConfig, RetryConfig } from './engine/types';\nimport { getConfigDir } from './infra/paths';\n\n/** Custom rule from user config */\nexport interface CustomRule {\n pattern: string;\n action: 'Allow' | 'Deny';\n severity: string;\n description?: 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(getConfigDir(), '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// 打包内 user_rules.json 路径(npm 安装自包含)+ dev 回退到仓库根 agent_moss/rules。\n// 对齐 skill-loader.ts 的 fileURLToPath(import.meta.url) 双路径解析:\n// - tsup 打包后 config.ts 被内联进 dist/{cli,server,engine/coordinator}.js,\n// import.meta.url 指向该 chunk(dist/engine/coordinator.js → __dirname=dist/engine/),\n// 故 dist 内 rules 在 ../rules(即 dist/rules/user_rules.json,copy-assets.cjs 复制)。\n// - dev(vitest) 模式 config.ts 源文件 __dirname=ts/src/,仓库根 agent_moss/rules\n// 在 ../../agent_moss/rules。三条候选路径覆盖 dist 与 dev 两种形态,命中即用。\nconst __configModuleDir = (() => {\n try { return path.dirname(fileURLToPath(import.meta.url)); }\n catch { return typeof __dirname !== 'undefined' ? __dirname : process.cwd(); }\n})();\nconst USER_RULES_PATHS = [\n path.join(__configModuleDir, 'rules', 'user_rules.json'), // 源在 ts/src/rules(一般不存在)\n path.join(__configModuleDir, '..', 'rules', 'user_rules.json'), // dist: dist/engine/../rules = dist/rules ✅\n path.join(__configModuleDir, '..', '..', 'agent_moss', 'rules', 'user_rules.json'), // dev src: ts/src/../../agent_moss\n];\n\nfunction wildcardToRegExp(pattern: string): string {\n // 对齐 Python UserRuleMatcher: re.escape(pattern).replace(r\"\\*\", \".*\")\n // JS 无 re.escape,手动转义所有正则元字符,再把转义后的 \\* 还原为 .*\n return pattern.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\\\\\*/g, '.*');\n}\n\nfunction loadCustomRules(): CustomRule[] {\n const rules: CustomRule[] = [];\n // 1. AGENT_MOSS_CUSTOM_RULES env var(运行时注入,最高优先)\n try {\n const raw = process.env.AGENT_MOSS_CUSTOM_RULES;\n if (raw) {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) {\n for (const r of parsed) {\n if (r && r.pattern && r.action) rules.push({ pattern: r.pattern, action: r.action, severity: r.severity || 'high' });\n }\n }\n }\n } catch { /* ignore env parse error */ }\n\n // 2. 打包内 agent_moss/rules/user_rules.json 的 sensitive_actions(通配符规则)。\n // 对齐 Python UserRuleMatcher(DEFAULT_RULES_PATH = agent_moss/rules/user_rules.json),\n // 含 crontab -e / crontab -r / * | crontab / iptables - 等用户敏感规则。\n // TS 此前只读 env 不读该文件,导致 crontab -e 等 L1 漏检(FN-2)。wildcard → RegExp。\n for (const rulesPath of USER_RULES_PATHS) {\n try {\n if (!fs.existsSync(rulesPath)) continue;\n const data = JSON.parse(fs.readFileSync(rulesPath, 'utf-8'));\n const actions = Array.isArray(data?.sensitive_actions) ? data.sensitive_actions : [];\n for (const r of actions) {\n const p = r?.pattern;\n if (!p) continue;\n rules.push({ pattern: wildcardToRegExp(p), action: 'Deny', severity: 'high' });\n }\n break; // 命中第一个存在的文件即可\n } catch { /* ignore user_rules.json read/parse error */ }\n }\n return rules;\n}\n\n/** Custom rules loaded from AGENT_MOSS_CUSTOM_RULES env var + packaged user_rules.json */\nlet customRules: CustomRule[] = loadCustomRules();\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 * Probe LLM connectivity with a minimal max_tokens=1 request.\n * Mirrors Python _probe_llm (tests/conftest.py): same source of truth\n * (getLLMConfig / get_default_config), so a passing probe means the actual\n * L3 call in tests uses the same key/endpoint and will succeed.\n *\n * Returns true on any successful response (finish_reason length/stop both ok);\n * false on timeout / 401 / network error. Used by L3 tests to skip rather than\n * let a dead key fail-open and false-pass.\n */\nexport async function probeLLMConnection(timeoutMs: number = 8000): Promise<boolean> {\n if (!isLLMAvailable()) return false;\n const OpenAI = (await import('openai')).default;\n const config = getLLMConfig();\n const provider = detectProvider(config.baseUrl, config.provider);\n const extraHeaders = getProviderHeaders(provider);\n const client = new OpenAI({\n baseURL: config.baseUrl,\n apiKey: config.apiKey,\n timeout: timeoutMs,\n maxRetries: 0,\n defaultHeaders: Object.keys(extraHeaders).length > 0 ? extraHeaders : undefined,\n });\n try {\n const resp = await client.chat.completions.create({\n model: config.model,\n messages: [{ role: 'user', content: 'ping' } as any],\n max_tokens: 1,\n } as any);\n return !!(resp && resp.choices && resp.choices[0]);\n } catch {\n return false;\n }\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 * 内联脚本静态语义判定 — 区分敏感路径是\"被当作文本\"还是\"被当作读写目标\"。\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 等纯文本输出命令(敏感路径可能作为字符串字面量出现)。\n\n echo/printf 含真实文件重定向(> /path,非 /dev/null 丢弃、非 >& fd)时返回 false——\n 重定向目标是真实写文件,路径不是字面量,不当文本命令(否则 echo x > '~/.bashrc'\n 被当文本命令 → inline_analyzer 把引号内路径当字面量 → 漏报敏感路径写)。 */\nexport function isLiteralTextCommand(command: string): boolean {\n ECHO_CMD_RE.lastIndex = 0;\n if (!ECHO_CMD_RE.test(command)) return false;\n // 含真实文件重定向 → 不是纯文本输出\n if (command.includes('>')) {\n let d = command.replace(/<=>|>=|<=|<>|=>/g, ' ');\n d = d.replace(/(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/g, '');\n // 摘引号重定向目标(去引号保留路径,支持 / 或 ~ 开头)\n d = d.replace(new RegExp(\">{1,2}\\\\s*(['\\\"])([~./][^'\\\"]+)\\\\1\", \"g\"), (_m, _q, p) => '>' + p);\n d = d.replace(/'[^']*'|\"[^\"]*\"/g, '');\n if (/>{1,2}\\s*(?!&)\\S/.test(d)) {\n return false;\n }\n }\n return true;\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 不进此判定)\n// 对齐 Python inline_analyzer._build_redirect_to_sensitive_re(profile):Python 按\n// profile.sensitive_paths 动态编译(其中含 ~/.bashrc)。TS 无 profile 运行时注入,\n// 故在 ROOT/HOME/CREDENTIAL 静态列表基础上,额外补 shell rc 文件名片段,\n// 让 `echo 'x' >> ~/.bashrc`、`echo 'x' >> /storage/Users/currentUser/.bashrc`\n//(鸿蒙 home 形态)都能被识别为真实重定向写入 → Deny,而非落到\"文本字面量\"放行。\n// 注意:shell rc 片段用文件名匹配(不带 ~ 前缀),可命中任意 home 绝对路径下的 rc 文件。\nconst SHELL_RC_FRAGMENTS = [\n '.bashrc', '.zshrc', '.profile', '.bash_profile', '.zprofile',\n];\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 ...SHELL_RC_FRAGMENTS,\n];\nconst REDIRECT_TO_SENSITIVE_RE = new RegExp(`>{1,2}\\\\s*(?:\\\\S*/)?(${SENSITIVE_PATH_FRAGMENTS.map((p) => p.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')).join('|')})(?:\\\\s|$)`, '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: '物理内存访问设备(读写均危险)', credential: true },\n { path: '/dev/kmsg', riskLevel: 'high', desc: '内核消息缓冲区' },\n // SSH 主机私钥\n // SSH 主机私钥(排除 .pub 公钥变体,对齐 Python .ssh/id_rsa(?!\\.pub) 范式)\n { path: '/etc/ssh/ssh_host_rsa_key(?!\\\\.pub)', riskLevel: 'critical', desc: 'SSH 主机 RSA 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ed25519_key(?!\\\\.pub)', riskLevel: 'critical', desc: 'SSH 主机 Ed25519 私钥', credential: true },\n { path: '/etc/ssh/ssh_host_ecdsa_key(?!\\\\.pub)', riskLevel: 'critical', desc: 'SSH 主机 ECDSA 私钥', credential: true },\n // Nginx 配置(仅拦截写入,对齐 Python linux.py sensitive_paths)\n { path: '/etc/nginx/nginx.conf', riskLevel: 'high', desc: 'Nginx 主配置' },\n { path: '/etc/nginx/conf.d/', riskLevel: 'high', desc: 'Nginx 子配置目录' },\n { path: '/etc/nginx/sites-enabled/', riskLevel: 'high', desc: 'Nginx 启用站点配置目录' },\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// 只读工具精确名(豁免 read_before_write;与 coordinator READONLY_SENSITIVE_TOOLS/FULLY_SAFE_TOOLS 对齐)。\n// 注意:不含 filemgr-writefile/filemgr-editfile/filemgr-searchreplace(这些是真写)。\nconst NON_WRITE_TOOLS = new Set([\n 'ask_user_question', 'glob', 'grep', 'list_dir', 'count_text_length', 'search',\n // filemgr 只读三件套(globfiles 在 coordinator FULLY_SAFE_TOOLS 提前放行,此处兜底防御非 coordinator 入口)\n 'filemgr-globfiles', 'filemgr-readfile', 'filemgr-grepfiles',\n // 通用只读工具名\n 'read', 'read_file', 'file_read', 'head', 'tail', 'cat',\n]);\n\n// 非 bash/terminal 类工具前缀豁免 read_before_write。\n// 仅保留通用基线前缀(与 EXCLUDED_PREFIXES / SENSITIVE_EXCLUDED_PREFIXES 一致):\n// memory-/skill-manager-/mailbox-/app- 是数据/编排/通信工具,read_before_write(写文件前先读)对其\n// 无意义,且工具名含 remove/update(memory-removeMemory/memory-updateUserPortrait)会命中\n// WRITE_KEYWORDS 子串 → 误判为写。L2 层独立豁免,不再仅依赖 coordinator opendesk 白名单。\n// 不含 skill-(任意能力,coordinator 故意保留 L3)、todomgr-/planning-(opendesk 专属命名空间,\n// 经 opendesk/rules.json builtin_safe_action_types 在 coordinator 层豁免 L2+L3,不到 L2)。\n// mailbox-sendEmail/replyEmail 的外传风险由 L3 LLM 管,不归 L2 read_before_write。\nconst NON_WRITE_TOOL_PREFIXES = ['memory-', 'skill-manager-', 'mailbox-', 'app-'];\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 (also used by L1 SensitivePathChecker)\nexport const WRITE_KEYWORDS = ['write', '写入', 'save', '保存', 'modify', '修改', 'update', '更新', 'delete', '删除', 'remove', '移除', 'create', '创建', 'append', '追加', 'truncate', '截断', 'overwrite', '覆盖', 'replace', '替换', 'edit'];\n\n// 写/删命令词边界正则(对齐 Python _WRITE_COMMAND_RES)。\n// 子串匹配无法可靠识别 rm/cp/dd(\"rm\" 误命中 arm/form),故用词边界。\nexport const WRITE_COMMAND_RES: RegExp[] = [\n /\\brm\\b/, /\\bunlink\\b/, /\\brmdir\\b/, /\\bshred\\b/, /\\bcp\\b/, /\\bmv\\b/,\n /\\binstall\\b/, /\\btee\\b/, /\\bdd\\b/, /\\bmkfs\\b/,\n /\\b(fdisk|parted|cfdisk|sfdisk)\\b/, /\\bchmod\\b/, /\\bchown\\b/, /\\btruncate\\b/,\n];\n\n// 只读命令集合(重定向写判定用,对齐 Python READ_ONLY_COMMANDS)。\n// 这些命令带 > 也是输出重定向非写文件意图(如 cat file > /dev/null)。\nexport const 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 // NEW-FP-I: echo/printf 是文本输出命令,参数是字面量非写目标。加入此集让\n // read_before_write 的 echo 段走只读命令分支(只提取重定向目标,不提取参数路径),\n // 避免 echo \"cat /etc/shadow\" > /tmp/x.sh 的引号内 /etc/shadow 被当写目标误报。\n // echo \"x\" > /tmp/x.sh 的重定向目标 /tmp/x.sh 仍被提取(真实写不漏报)。\n 'echo', 'printf',\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 的丢弃写法(对齐 Python _DEVNULL_REDIRECT_RE)。\n// 注意带 g 标志:一条诊断命令常含多个 2>/dev/null(cd ... && ls ... 2>/dev/null; find ... 2>/dev/null),\n// JS String.replace 无 g 只替换首个,残留的 2>/dev/null 仍带 `>` 会触发重定向写误判(FP)。\n// Python 端用 re.sub 全局替换,此处对齐之。\nconst DEVNULL_REDIRECT_RE = /(?:2|&|1)?\\s*>\\s*\\/dev\\/null\\b/g;\n\n/**\n * 综合判定是否为写/删操作(对齐 Python _is_write_operation,单一事实源)。\n * 供 L2 read_before_write 与 L1 sensitive_path 共用,避免手写复刻漂移。\n *\n * 1. WRITE_KEYWORDS 子串匹配 actionType+actionDetail(与 Python 一致,不加词边界以保持双端同步)\n * 2. WRITE_COMMAND_RES 词边界正则(rm/cp/dd/tee/truncate/...)\n * 3. sed -i 原地编辑\n * 4. 重定向写入:剥 devnull 后有 `>` 且首词非只读命令\n */\nexport function isWriteOperation(actionType: string, actionDetail: string, writeKeywords: string[] = WRITE_KEYWORDS): boolean {\n // 1. 关键词子串匹配(actionType 或 actionDetail)\n if (writeKeywords.some(kw => actionType.includes(kw) || actionDetail.includes(kw))) return true;\n // 2. 写/删命令词边界\n if (WRITE_COMMAND_RES.some(rx => rx.test(actionDetail))) return true;\n // 3. sed -i 原地编辑\n if (/\\bsed\\s+-[a-zA-Z]*i/i.test(actionDetail)) return true;\n // 3b. wget/curl + -O/-o/--output 下载写入(无 > 重定向,漏判 → 漏报,且可写 shell 后门绕过敏感路径)\n // 3c. rsync 同步写 dest(非 --list-only/--dry-run/-n 只读模式)\n // 两类都按命令段判定首词(排除 echo/printf 字面量)\n for (const seg of actionDetail.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const parts = trimmed.split(/\\s+/);\n const fw = parts[0]?.toLowerCase() || '';\n if (fw === 'wget' || fw === 'curl') {\n // NEW-FP-C: -O- / -o- / --output-document=- / --output=- 是 stdout(值为 -),不算文件写\n const isStdout = /\\s(?:-O|-o)-(?:\\s|$)/.test(trimmed) ||\n /\\s--output-document=-(?:\\s|$)/i.test(trimmed) ||\n /\\s--output=-(?:\\s|$)/i.test(trimmed);\n if (isStdout) continue;\n // NEW-FP-N: -o /dev/null / --output=/dev/null 是丢弃响应体只测状态码,非真实写文件\n const isDevnull = /\\s(?:-O|--output-document|--output)\\s*\\/dev\\/null(?:\\s|$)/i.test(trimmed) ||\n /\\s(?:-O|--output-document|--output)=[/]?dev\\/null(?:\\s|$)/i.test(trimmed);\n if (isDevnull) continue;\n if (/\\s(?:-O|--output-document|--output)(?:=|\\s|$)/i.test(trimmed) || /\\s-O\\S/.test(trimmed)) {\n return true;\n }\n }\n if (fw === 'rsync' && !/--list-only|--dry-run/i.test(trimmed) && !/(^|[^a-zA-Z])-n([^a-zA-Z]|$)/.test(trimmed)) {\n return true;\n }\n }\n // 4. 重定向写入:先排除 /dev/null 丢弃和比较运算符,再看是否还有真实文件重定向。\n // NEW-FN-D 修复:不再用「整条命令首词是否只读」判断——`cat in > out` 里 cat 是\n // 只读命令但其重定向目标 out 是真实写文件(覆写/追加),应判写。只读命令的「安全\n // 重定向」只指 `> /dev/null`(丢弃输出,已剥)。改为只读命令带真实文件重定向也算写。\n // fd 重定向(>&N / N>&M / 2>&1)不是写文件,用「> 后紧跟 &」排除。\n // grep/awk 搜索模式里的 > 字面量(如 grep \"a>b\" file)不是重定向——剥引号内容后再判。\n if (actionDetail.includes('>')) {\n // 先剥掉比较运算符(>=, <=, <>, <=>, =>),避免 Python 代码里的 `r.get('seq',0) >= 28`\n // 被当成重定向写(`>=` 含 `>`)。这些是表达式而非重定向,不应计入写判定。\n const detailWithoutCompare = actionDetail.replace(/<=>|>=|<=|<>|=>/g, ' ');\n const detailWithoutDevnull = detailWithoutCompare.replace(DEVNULL_REDIRECT_RE, '');\n // 先摘「> '引号路径'」为裸路径(支持引号包裹的重定向目标,如 echo x > '/tmp/file'),\n // 否则下一步剥引号内容会把重定向目标路径也删掉 → 漏判写(漏报)。\n const detailUnquotedRedirect = detailWithoutDevnull.replace(\n />{1,2}\\s*(['\"])([~./][^'\"]+)\\1/g,\n (_m, _q, p) => '>' + p,\n );\n // 剥掉剩余引号内内容(grep/awk 搜索模式、python -c 代码里的 > 字面量),只看引号外\n // 是否还有真实文件重定向。\n const detailWithoutQuotes = detailUnquotedRedirect.replace(/'[^']*'|\"[^\"]*\"/g, '');\n // 真实文件重定向:> 或 >> 后紧跟非空白、非 & 的文件目标字符。\n // `>{1,2}\\s*(?!&)\\S` 匹配 echo x > /file、cat in >file、sort in >> /file;\n // 排除 ls 2>&1、echo >&2(>& 紧邻或 > 后 & 是 fd 合并,非写文件)。\n if (/>{1,2}\\s*(?!&)\\S/.test(detailWithoutQuotes)) {\n return true;\n }\n }\n return false;\n}\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\n/**\n * 匹配危险动作词。中文用子串(无词边界歧义),英文用词边界正则。\n *\n * 裸 includes() 会在 actionDetail 参数/搜索模式里误报:\n * - `git log --format=` 含 \"format\" → 误判\"格式化磁盘\"\n * - grep 搜索模式 `NON_WRITE|non_write` 含 \"write\" → 误判\"修改\"\n * - `pip install --update` 含 \"update\" → 误判\"修改\"\n * 英文词用 `(?<!-)\\bWORD\\b`:\n * - 前面不是 `-`(排除 --format / --update / -delete 等参数形态)\n * - 词边界(排除 NON_WRITE 里的 write、arm 里的 rm 等)\n */\nfunction matchDangerousAction(actionDetail: string, action: string): boolean {\n // 中文词(含非 ASCII)走子串匹配\n if (/[^\\x00-\\x7f]/.test(action)) {\n return actionDetail.includes(action);\n }\n // 英文词走词边界 + 排除参数前缀\n const escaped = action.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const re = new RegExp(`(?<![-\\\\w])${escaped}\\\\b`, 'i');\n return re.test(actionDetail);\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 // 内联脚本命令(python -c / perl -e 等)跳过 intent 的 dangerousAction 词匹配。\n // 内联脚本代码内容里的英文词(print(delete this) 的 delete)是字符串字面量,\n // 不是真实动作;词边界 (?<![-\\w])delete\\b 能挡 print 里的 rm(短词),但挡不住\n // delete(长词独立词)→ intent 误报(Bug4)。内联脚本的「危险」由 L1.2\n // inline-analyzer 专门管(区分字面量 vs 真实调用),intent 不重复管。\n if (INLINE_SCRIPT_RE.test(actionDetail)) {\n // fall through to next rule, skip intent\n } else {\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 => matchDangerousAction(actionDetail, 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\n // 注:敏感路径访问检测 (checkSensitivePath) / 危险操作模式检测 / 横向移动检测\n // 已按\"L1 只看这一步\"原则搬至 heuristic.ts 的 runHeuristicCheck。\n // 本函数仅保留需要 action_history / prompt_session / cwd 的 L2 规则。\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 // 判据:sudo 后跟的命令本身是包管理/服务管理(apt/systemctl/yum/...)→ 合法运维\n // 直接放行,不要求历史先有一次 admin(新会话首次 sudo apt install 是合法高频运维)。\n // sudo + 非运维命令才查历史有无 admin 上下文;历史也无则视为异常提权。\n // 注意:剥掉 sudo 前缀再匹配 admin 关键词,否则 actionDetail 必含 sudo 导致永远放行。\n // 注:admin 关键词曾尝试词边界 \\b,但 grep apt / pip apt 里 apt 是独立词,\\bapt\\b 仍命中,\n // 词边界无法区分\"命令位置\"vs\"参数位置\",故暂保留子串匹配。提权漏检(grep apt 误当 admin\n // 上下文放行 sudo cat)是已知问题,待用命令位置匹配专项处理。\n // 内联脚本命令(python -c / perl -e 等)跳过提权词匹配:代码内容里的词\n // (print(\"chmod u+s\") 的 chmod u+s)是字符串字面量,不是真实动作,提权子串匹配\n // 会误报(FP-2 变体)。内联脚本的「危险」由 inline-analyzer 管,提权检测不重复管。\n if (INLINE_SCRIPT_RE.test(actionDetail)) {\n // fall through to next rule, skip privilege escalation\n // NEW-FP-J: 提权关键词改为「命令位置」判定。旧逻辑对整个 actionDetail 做子串匹配,\n // grep -rn \"sudo\" file、awk '/sudo/'、echo \"sudo make install\" 里参数/搜索模式/字面量\n // 位置的 sudo 被误判为真实提权。仅当段首词是提权命令(sudo/su/setuid,或 chmod+u+s)\n // 才认为存在提权意图。\n } else if (containsPrivilegeEscalation(actionDetail)) {\n const detailAfterSudo = actionDetail.replace(/(^|\\|\\||&&|\\s)sudo\\s+/g, ' ');\n const isAdminCmd = ['apt', 'systemctl', 'yum', 'dnf', 'pacman', 'zypper', 'apk'].some(kw => detailAfterSudo.includes(kw));\n if (!isAdminCmd) {\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\n // 注:横向移动检测已搬至 heuristic.ts (runHeuristicCheck)。\n // Rule 6: Non-interactive password modification consent check\n const pwdResult = checkPasswordConsent(actionType, actionDetail, actionHistory);\n if (pwdResult) return pwdResult;\n\n // Rule 7: 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)\nexport function 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 // key=value 语法的路径:of=/path、if=/path、--output=/path 等。\n // 现有 unixPaths 正则要求路径前是行首或空白,`of=/tmp/x` 里 / 前是 = 不匹配 →\n // dd of=/path 等漏报(NEW-FN-A)。此正则匹配 `=` 后紧跟的 / 路径。\n // NEW-FP-H: 先剥掉引号内容,避免 echo \"of=/dev/null done\" 这类输出文本里的\n // of=/dev/null 被误当真实写目标。引号内纯路径(dd of=\"/tmp/file\")由下方\n // quotedPaths 独立提取(要求引号内以 / 开头),故剥引号不会漏报真实写。\n const textNoQuotes = text.replace(/'[^']*'|\"[^\"]*\"/g, '');\n const kvPaths = textNoQuotes.match(/(?:=)(\\/[^\\s;|&><'\"]+)/g);\n if (kvPaths) paths.push(...kvPaths.map(p => p.replace(/^=/, '')));\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 // 豁免非文件类工具前缀(memory-/skill-/mailbox-/todomgr-...)与只读工具,\n // 避免 memory-removeMemory(工具名含 remove)/ filemgr-grepfiles(搜索模式含 write)等误判为写。\n // L2 层独立保护,不再仅依赖 coordinator opendesk 白名单(非 opendesk agent / 单测直调也安全)。\n if (NON_WRITE_TOOL_PREFIXES.some(p => actionType.startsWith(p))) return null;\n if (NON_WRITE_TOOLS.has(actionType)) return null;\n\n // 写判定按工具类型分流:\n // - bash/executebash/terminal-executebash:用 isWriteOperation(对齐 Python\n // _is_write_operation 单一事实源:WRITE_KEYWORDS 子串 + WRITE_COMMAND_RES 词边界\n // rm/cp/dd + sed -i + 重定向(剥 devnull+只读首词保护))。比手写 WRITE_KEYWORDS.includes\n // 多了词边界命令识别,能抓 `rm`/`cp`/`dd` 等;重定向/2>/dev/null 由它统一处理。\n // - 其他工具:只匹配 actionType,不看 actionDetail 内容。\n // 理由:非 shell 工具的写意图只能从工具名体现(filemgr-writefile/write/edit),\n // 参数内容里的中文\"更新\"\"移除\"是业务语义不是文件写语义;\n // grep 搜索模式里的 write/update/remove 子串绝不能算写意图(误报根因)。\n const isBashLike = actionType === 'bash' || actionType === 'executebash' || actionType === 'terminal-executebash';\n const isWrite = isBashLike\n ? isWriteOperation(actionType, actionDetail)\n : WRITE_KEYWORDS.some(kw => actionType.includes(kw));\n\n if (!isWrite) return null;\n\n // 删除/安全命令复合(无真正写命令)不触发 read_before_write。\n // read_before_write 的语义是「写文件前先读内容」,对删除不适用——删除不需要读文件字节,\n // 且删除的元数据预检(rm -rf /etc 等敏感路径、递归)由 L1 命令模式负责(/tmp 清理 L1\n // 判定安全放行,rm -rf /etc L1 拦截)。这是「rm 豁免狭义读内容」而非「跳过 RBW」——\n // 广义元数据预检仍由 L1 完成。判定:命令链无「写命令段」即跳过。写命令段 = 段首词是\n // 写命令(cp/mv/install/tee/dd/truncate/mkfs/sed -i)或含真实重定向写。\n // 注意:chmod/chown 不在此列——改元数据不改文件内容,「写前先读」对其无意义,\n // `chmod 644 /tmp/已有未读` 不应误报。危险 chmod 形态(777/u+s/4755 提权、chmod /敏感路径)\n // 由 L1 专门模式和 sensitive_path 检测负责(WRITE_COMMAND_RES 仍保留 chmod/chown 供敏感路径写判定)。\n // `rm ... && echo done` 豁免,`rm /a && echo x > /b` 仍走 rbw,\n // `chmod 644 /tmp/x`(普通)豁免,`chmod u+s /tmp/x`(提权)由 L1 拦。\n const WRITE_CMDS = new Set(['cp', 'mv', 'install', 'tee', 'dd', 'truncate', 'mkfs', 'fdisk', 'parted']);\n if (isBashLike) {\n const detailNoCompare = actionDetail.replace(/<=>|>=|<=|<>|=>/g, ' ');\n const detailNoDevnull = detailNoCompare.replace(DEVNULL_REDIRECT_RE, '');\n // 先摘「> '引号路径'」为裸路径(支持引号包裹重定向目标),再剥剩余引号内容,\n // 与 isWriteOperation 的重定向判定保持一致(避免两处漂移)。\n const detailUnquotedRedirect = detailNoDevnull.replace(\n />{1,2}\\s*(['\"])([~./][^'\"]+)\\1/g,\n (_m, _q, p) => '>' + p,\n );\n const detailNoQuotes = detailUnquotedRedirect.replace(/'[^']*'|\"[^\"]*\"/g, '');\n const hasRedirectWrite = />{1,2}\\s*(?!&)\\S/.test(detailNoQuotes);\n let hasWriteSeg = hasRedirectWrite;\n if (!hasWriteSeg) {\n for (const seg of actionDetail.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const fw = trimmed.split(/\\s+/)[0]?.toLowerCase() || '';\n if (WRITE_CMDS.has(fw) || /\\bsed\\s+-[a-zA-Z]*i/i.test(trimmed)) {\n hasWriteSeg = true;\n break;\n }\n // wget/curl + -O/-o/--output 下载写入\n if ((fw === 'wget' || fw === 'curl') &&\n (/\\s(?:-O|--output-document|--output)(?:=|\\s|$)/i.test(trimmed) || /\\s-O\\S/.test(trimmed))) {\n hasWriteSeg = true;\n break;\n }\n // rsync 同步写 dest(非 --list-only/--dry-run/-n 只读模式)\n if (fw === 'rsync' && !/--list-only|--dry-run/i.test(trimmed) && !/(^|[^a-zA-Z])-n([^a-zA-Z]|$)/.test(trimmed)) {\n hasWriteSeg = true;\n break;\n }\n }\n }\n if (!hasWriteSeg) return null;\n }\n\n // Extract target file paths,过滤掉非写目标的参数路径。\n // - cd 是目录切换不是写操作,cd /path 的 /path 不应作为写目标(否则 `cd /敏感 && ls` 误报)。\n // - 读命令(cat/head/tail/grep/find/less/more/wc/cut 等 READ_ONLY_COMMANDS)的文件参数是\n // 读取目标不是写目标,`echo x > /tmp/t1; cat /tmp/t2` 里 t2 是 cat 的读目标却会被\n // extractFilePaths 当写目标提取 → read_before_write 误报(Bug5)。过滤之。\n // - 写命令的源文件参数(cp/mv/install 的首个路径参数)是读取目标不是写目标,\n // `cp /src /dst` 里 /src 是读目标不是写目标 → 误报(NEW-FP-1)。过滤首个路径参数。\n // - dd 的 if=/path 是输入源(读目标),of=/path 才是输出目标(写目标)。\n // `dd if=/dev/zero of=/tmp/x` 里 if= 的 /dev/zero 是读源,必须排除否则误报;\n // of= 的 /tmp/x 是写目标保留(NEW-FN-A:此前 of= 路径根本提取不到 → 漏报)。\n // 逐段法(per-segment):按 &&/||/;/换行 拆命令段,每段独立计算写目标——\n // cd → 无写目标(切目录);\n // 只读命令(cat/grep/sort/head 等)→ 命令参数是读目标,但重定向目标(> /path)\n // 是写目标,需提取(NEW-FN-D:此前整段排除把重定向目标也丢了 → `cat in > out` 漏检 out);\n // cp/mv/install → 排除首个路径(源文件),其余为写目标;\n // dd → 排除 if= 路径(输入源),of= 为写目标;\n // 其他段 → 所有路径为写目标。\n // 关键:排除是 per-segment 局部的,不是全局——否则 `cp /a /b && cp /b /c` 里\n // /b 既是第一段 dest(写目标)又是第二段 source(读目标),全局排除会让第一段\n // 对 /b 的覆写漏检(NEW-FN-B)。逐段计算确保 /b 在第一段仍被作为写目标检查。\n const SOURCE_ARG_CMDS = new Set(['cp', 'mv', 'install', 'rsync']);\n // 重定向写目标正则:> 或 >> 后紧跟文件路径(裸路径或引号包裹,排除 >& fd)。\n // 用 RegExp 构造避免正则字面量里 / 与路径分隔符冲突。\n const REDIRECT_TARGET_RE = new RegExp(\">{1,2}\\\\s*(?!&)(?:'(/[^']+)'|\\\"(/[^\\\\\\\"]+)\\\"|(/[^\\\\s;|&><'\\\\\\\"]+))\");\n const targetPaths: string[] = [];\n for (const seg of actionDetail.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const firstWord = trimmed.split(/\\s+/)[0]?.toLowerCase() || '';\n if (firstWord === 'cd') {\n continue;\n }\n if (READ_ONLY_COMMANDS.has(firstWord)) {\n // 只读命令:文件参数是读目标,但重定向目标是写目标(NEW-FN-D)。\n // 先摘引号重定向目标(去引号保留路径),再剥剩余引号内容(grep 模式),再提取目标。\n // NEW-FP-M: 先剥 /dev/null 重定向(cat f 2>/dev/null 的 /dev/null 是 stderr 丢弃\n // 非写目标),否则 REDIRECT_TARGET_RE 把 2>/dev/null 提取为写目标误报。\n const segUnquoted = trimmed.replace(new RegExp(\">{1,2}\\\\s*(['\\\"])([~./][^'\\\"]+)\\\\1\", \"g\"), (_m, _q: string, p: string) => '>' + p);\n const segNoDevnull = segUnquoted.replace(DEVNULL_REDIRECT_RE, '');\n const segNoQuotes = segNoDevnull.replace(/'[^']*'|\"[^\"]*\"/g, '');\n const m = segNoQuotes.match(REDIRECT_TARGET_RE);\n if (m) targetPaths.push(m[1] || m[2] || m[3]);\n continue;\n }\n const segPaths = extractFilePaths(trimmed);\n // NEW-FP-N: curl/wget 的 -o /dev/null 是丢弃响应体非真实写文件,排除 /dev/null\n // 路径(extractFilePaths 会把 -o /dev/null 的 /dev/null 提取为写目标 → 误报)。\n const segPathsFiltered = (firstWord === 'wget' || firstWord === 'curl')\n ? segPaths.filter(p => p !== '/dev/null')\n : segPaths;\n if (SOURCE_ARG_CMDS.has(firstWord)) {\n // 排除首个路径(源文件),其余为写目标\n if (segPathsFiltered.length > 1) targetPaths.push(...segPathsFiltered.slice(1));\n } else if (firstWord === 'dd') {\n // dd 的 if= 是输入源(读目标),of= 是输出目标(写目标)。\n // 排除 if= 的路径,保留 of= 的路径作为写目标。\n // NEW-FP-G: of=/dev/null 是丢弃输出非真实写文件(dd if=/dev/zero\n // of=/dev/null 是丢弃测试),与重定向 >/dev/null 同语义,排除避免\n // read_before_write 误报 /dev/null。/dev/zero/urandom 同理(设备文件)。\n const ifSourceMatches = trimmed.match(/\\bif=(\\/[^\\s;|&><'\"]+)/g);\n const ifSourcePaths = new Set(ifSourceMatches ? ifSourceMatches.map((m: string) => m.replace(/^if=/, '')) : []);\n const devNullMatches = trimmed.match(/\\bof=(\\/dev\\/\\S+)/g);\n const devNullTargets = new Set(devNullMatches ? devNullMatches.map((m: string) => m.replace(/^of=/, '')) : []);\n for (const sp of segPaths) {\n if (!ifSourcePaths.has(sp) && !devNullTargets.has(sp)) targetPaths.push(sp);\n }\n } else {\n // 其他段(含重定向写 echo > file、tee、truncate 等):该段所有路径为写目标\n targetPaths.push(...segPathsFiltered);\n }\n }\n // 去重\n const uniqueTargetPaths = [...new Set(targetPaths)];\n if (uniqueTargetPaths.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 uniqueTargetPaths) {\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 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// NEW-FP-J: 提权关键词「命令位置」判定。仅当段首词是提权命令(sudo/su/setuid,\n// 或 chmod+u+s setuid 位)才认为存在提权意图。引号感知分段:echo \"a; sudo rm\" 的\n// ; 在引号内不分段,整段首词 echo 不触发。grep/awk/echo 首词段的参数是搜索模式/字面量。\nfunction containsPrivilegeEscalation(actionDetail: string): boolean {\n const ad = actionDetail.toLowerCase();\n for (const seg of ad.split(/&&|\\|\\||;|\\n/)) {\n const trimmed = seg.trim();\n if (!trimmed) continue;\n const parts = trimmed.split(/\\s+/);\n const fw = parts[0]?.toLowerCase() || '';\n if (fw === 'sudo' || fw === 'su' || fw === 'setuid') return true;\n if (fw === 'chmod' && /\\bu\\s*\\+\\s*s\\b/.test(trimmed)) return true;\n }\n return false;\n}\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","/**\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, readdirSync } from 'fs';\nimport { join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\nimport { getRuntimeConfigDir } from './paths';\nconst __dirname = dirname(fileURLToPath(import.meta.url));\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// type-only import:避免 agents ↔ runtime-config 循环依赖(运行时用 require 取 resolveAgentsDir)\nimport type { AgentExtensions } from '../agents/types';\n\nconst ENV_RUNTIME_CONFIG_PATH = 'AGENT_MOSS_RUNTIME_CONFIG_PATH';\n\nfunction runtimeDir(): string {\n return getRuntimeConfigDir();\n}\n\nconst RUNTIME_CONFIG_DIR = runtimeDir();\nconst RUNTIME_CONFIG_PATH = join(RUNTIME_CONFIG_DIR, 'agent_moss_runtime.json');\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 /** builtin_safe_action_types / builtin_safe_skills 项的值(前缀或精确工具名) */\n value?: 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 /** agent 定制规则(按 agent_id 分区,每 agent 内按类别组织) */\n agent_rules?: Record<string, 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 agent_rules: {},\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 agent_rules: merged.agent_rules || {},\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 // 优先读 L1_rules.sensitive_path_access(重分类后归属 L1);\n // 回退 L2_rules.sensitive_path_access(兼容迁移前老配置)。函数名保留 l2 前缀仅为兼容。\n let cat = runtime.L1_rules?.sensitive_path_access;\n if (!cat || !cat.rules || cat.rules.length === 0) {\n cat = runtime.L2_rules?.sensitive_path_access || { category_enabled: true, rules: [] };\n }\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 // 敏感路径已重分类到 L1,遍历 L1_rules + L2_rules 两层。函数名保留 l2 前缀仅为兼容。\n for (const layerKey of ['L1_rules', 'L2_rules'] as const) {\n const layer = runtime[layerKey] || {};\n for (const [catName, cat] of Object.entries(layer)) {\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 }\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/** 扫描 agent_moss/agents/<id>/rules.json,转为 agent_rules 分区结构(出厂种子)。\n * 每个 agent 的 rules.json 字段 → agent_rules[<id>] 的 Category 结构(与 L1/L2 同形)。\n * builtin_safe_action_types / builtin_safe_skills 原为 string[],转成 [{value, enabled, builtin}]。\n * 路径内联解析(不 import agents/index.ts 避免 ESM 循环依赖),与 agents/index.ts resolveAgentsDir 同策略。 */\nconst _AGENTS_DIR_PROD = join(__dirname, 'agents');\nconst _AGENTS_DIR_DEV = join(__dirname, '..', '..', '..', 'agent_moss', 'agents');\nfunction _agentRulesToDefaults(): Record<string, Record<string, Category>> {\n const out: Record<string, Record<string, Category>> = {};\n const agentsDir = existsSync(_AGENTS_DIR_PROD) ? _AGENTS_DIR_PROD\n : existsSync(_AGENTS_DIR_DEV) ? _AGENTS_DIR_DEV : _AGENTS_DIR_PROD;\n if (!existsSync(agentsDir)) return out;\n let entries: string[];\n try {\n entries = readdirSync(agentsDir, { withFileTypes: true })\n .filter(d => d.isDirectory()).map(d => d.name);\n } catch {\n return out;\n }\n for (const agentId of entries) {\n const rulesFile = join(agentsDir, agentId, 'rules.json');\n if (!existsSync(rulesFile)) continue;\n let data: any;\n try { data = JSON.parse(readFileSync(rulesFile, 'utf-8')); } catch { continue; }\n out[agentId] = {\n builtin_safe_action_types: {\n category_enabled: true,\n category_desc: 'agent 完全安全操作白名单(前缀尾随 - 或精确名,命中跳 L2+L3)',\n rules: (data.builtin_safe_action_types || []).map((v: string) =>\n ({ value: v, enabled: true, builtin: true })),\n },\n builtin_safe_skills: {\n category_enabled: true,\n category_desc: 'agent 信任的内置 Skill(命中跳 L2+L3)',\n rules: (data.builtin_safe_skills || []).map((v: string) =>\n ({ value: v, enabled: true, builtin: true })),\n },\n extra_command_patterns: {\n category_enabled: true,\n category_desc: 'agent 专属危险命令正则(L1 末尾追加)',\n rules: (data.extra_command_patterns || []).map((p: any) =>\n ({ ...p, enabled: true, builtin: true })),\n },\n extra_injection_keywords: {\n category_enabled: true,\n category_desc: 'agent 专属注入关键词(L1 末尾追加)',\n rules: (data.extra_injection_keywords || []).map((k: any) =>\n ({ ...k, enabled: true, builtin: true })),\n },\n extra_sensitive_paths: {\n category_enabled: true,\n category_desc: 'agent 专属敏感路径(L1 末尾追加)',\n rules: (data.extra_sensitive_paths || []).map((sp: any) =>\n ({ ...sp, enabled: true, builtin: true })),\n },\n };\n }\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 sensitive_path_access: {\n category_enabled: true,\n category_desc: '敏感路径访问检测(deny_both/deny_read/deny_write)',\n rules: _l2SensitivePathsToRules(),\n },\n user_custom: { category_enabled: true, category_desc: '用户自定义命令规则', rules: [] },\n },\n L2_rules: {\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 user_custom: { category_enabled: true, category_desc: '用户自定义 L2 逻辑规则', rules: [] },\n },\n L3_skills: _l3SkillsToRules(),\n agent_rules: _agentRulesToDefaults(),\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 // builtin_safe_action_types / builtin_safe_skills 项用 value 字段\n if (rule.value) return JSON.stringify([rule.value]);\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 // 清理源码已移除的类目:保留 user_custom(用户自定义壳),删除其余不在 src 的类目\n // (如本次重构删除的 dangerous_patterns / lateral_movement,老配置落盘仍残留)。\n for (const catName of Object.keys(userLayer)) {\n if (catName === 'user_custom') continue;\n if (!(catName in srcLayer)) delete userLayer[catName];\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/** 合并 agent_rules 分区(按 agent_id 分区,每个 agent 内复用类别合并逻辑)。\n * 新出厂 agent → 整体加入;已有 agent → 每类别走 _mergeRuleCategories 同套\n * (指纹去重 + 保留 enabled + 新 builtin 追加 + 删除标记 source_removed)。 */\nfunction _mergeAgentRules(userCfg: RuntimeConfig, srcDefaults: RuntimeConfig): void {\n const userAgent = (userCfg.agent_rules || (userCfg.agent_rules = {})) as Record<string, Record<string, Category>>;\n const srcAgent = srcDefaults.agent_rules || {};\n for (const [agentId, srcCats] of Object.entries(srcAgent)) {\n if (!(agentId in userAgent)) {\n userAgent[agentId] = JSON.parse(JSON.stringify(srcCats));\n continue;\n }\n const userCats = userAgent[agentId];\n for (const [catName, srcCat] of Object.entries(srcCats)) {\n if (!(catName in userCats)) {\n userCats[catName] = JSON.parse(JSON.stringify(srcCat));\n continue;\n }\n const userCat: Category = userCats[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 Object.keys(existing).forEach(k => delete (existing as any)[k]);\n Object.assign(existing, srcR);\n existing.enabled = userEnabled;\n } else {\n userRules.push({ ...srcR, enabled: true });\n }\n }\n for (const r of userRules) {\n if (r.builtin && !srcFps.has(_ruleFingerprint(r))) {\n r.source_removed = true;\n r.enabled = false;\n }\n }\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 // 跨层迁移:敏感路径已从 L2 重分类到 L1。老配置 sensitive_path_access 还在\n // L2_rules 下,搬到 L1_rules(保留用户 enabled/deny_mode/自定义项),L2 删除该分类。\n // 注:dangerous_patterns / lateral_movement 检测是硬编码子检测器,不读 runtime\n // config rules,故老配置 L2 里这两类的 rules 不迁移(默认种子已删除该类目)。\n _migrateCategoriesAcrossLayers(cfg, 'L2_rules', 'L1_rules',\n ['sensitive_path_access']);\n _mergeRuleCategories(cfg, srcDefaults, 'L1_rules');\n _mergeRuleCategories(cfg, srcDefaults, 'L2_rules');\n _mergeSkillCategories(cfg, srcDefaults, 'L3_skills');\n _mergeAgentRules(cfg, srcDefaults);\n return cfg;\n}\n\n/** 把指定分类从 srcLayer 搬到 dstLayer(保留分类内全部内容,按指纹去重合并)。 */\nfunction _migrateCategoriesAcrossLayers(cfg: RuntimeConfig, srcLayer: 'L1_rules' | 'L2_rules', dstLayer: 'L1_rules' | 'L2_rules', catNames: string[]): void {\n const src = (cfg as any)[srcLayer] || {};\n const dst: any = cfg[dstLayer] || (cfg[dstLayer] = {} as RuntimeConfig['L1_rules']);\n for (const catName of catNames) {\n if (!(catName in src)) continue;\n const srcCat = src[catName];\n if (!dst[catName]) {\n dst[catName] = { category_enabled: true, category_desc: '', rules: [] };\n }\n const dstCat = dst[catName];\n if (!dstCat.category_desc && srcCat.category_desc) dstCat.category_desc = srcCat.category_desc;\n if (dstCat.category_enabled === undefined) dstCat.category_enabled = srcCat.category_enabled;\n // 合并 rules:dst 已有的按指纹保留,src 独有的追加\n if (srcCat.rules && srcCat.rules.length > 0) {\n const dstFps = new Set((dstCat.rules || []).map((r: any) => _ruleFingerprint(r)));\n for (const r of srcCat.rules) {\n const fp = _ruleFingerprint(r);\n if (!dstFps.has(fp)) {\n (dstCat.rules = dstCat.rules || []).push(r);\n dstFps.add(fp);\n }\n }\n }\n delete src[catName];\n }\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 // 允许删:用户自定义(builtin=false)+ 已移除的(builtin=true 但 source_removed=true)。\n // 活跃 builtin 规则不允许删(用 enabled 开关)。\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 const r = rules[idx];\n if (r.builtin && !r.source_removed) 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\n// ==================== agent 定制规则(runtime_config 统一治理)====================\n\nexport function getAgentRules(runtime: RuntimeConfig): Record<string, Record<string, Category>> {\n return runtime.agent_rules || {};\n}\n\nfunction _agentCategoryEnabledRules(cat: Category | undefined): Rule[] {\n if (!cat || cat.category_enabled === false) return [];\n return (cat.rules || []).filter(r => r.enabled !== false);\n}\n\n/** 从 runtime_config 的 agent_rules[agent_id] 构造 AgentExtensions(应用 enabled 过滤)。\n * 供 getAgentExtensions 在 hasRuntimeConfig() 时调用。无该 agent 分区返回 null。 */\nexport function getEnabledAgentExtensions(runtime: RuntimeConfig, agentId: string): AgentExtensions | null {\n const agentData = runtime.agent_rules?.[agentId];\n if (!agentData) return null;\n const safeAction = _agentCategoryEnabledRules(agentData.builtin_safe_action_types);\n const safeSkills = _agentCategoryEnabledRules(agentData.builtin_safe_skills);\n const cmdPatterns = _agentCategoryEnabledRules(agentData.extra_command_patterns)\n .filter(r => r.pattern).map(r => ({\n pattern: r.pattern!, risk_level: r.risk_level || '',\n risk_type: r.risk_type || '', reason: r.reason || '',\n }));\n const injKeywords = _agentCategoryEnabledRules(agentData.extra_injection_keywords)\n .filter(r => r.keyword).map(r => ({\n keyword: r.keyword!, risk_level: r.risk_level || '', lang: r.lang || 'en',\n }));\n const sensitivePaths = _agentCategoryEnabledRules(agentData.extra_sensitive_paths)\n .filter(r => r.path).map(r => ({\n path: r.path!, risk_level: r.risk_level || '', desc: r.desc || '',\n credential: r.credential, read_only: r.read_only, deny_mode: r.deny_mode,\n }));\n return {\n agent_id: agentId,\n description: '',\n extra_command_patterns: cmdPatterns,\n extra_injection_keywords: injKeywords,\n extra_sensitive_paths: sensitivePaths,\n builtin_safe_skills: safeSkills.filter(r => r.value).map(r => r.value!),\n builtin_safe_action_types: safeAction.filter(r => r.value).map(r => r.value!),\n extra_skills: [],\n };\n}\n\nexport function updateAgentRuleEnabled(agentId: string, category: string, ruleFp: Partial<Rule>, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.agent_rules?.[agentId]?.[category];\n if (cat) {\n const targetFp = _ruleFingerprint(ruleFp);\n for (const r of (cat.rules || [])) {\n if (_ruleFingerprint(r) === targetFp) { r.enabled = enabled; break; }\n }\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function addAgentRule(agentId: string, category: string, rule: Record<string, unknown>): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n if (!runtime.agent_rules) runtime.agent_rules = {};\n if (!runtime.agent_rules[agentId]) runtime.agent_rules[agentId] = {};\n const cats = runtime.agent_rules[agentId];\n if (!cats[category]) cats[category] = { category_enabled: true, category_desc: '', rules: [] };\n (cats[category].rules || (cats[category].rules = [])).push({ ...rule, enabled: true, builtin: false } as Rule);\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\nexport function deleteAgentRule(agentId: string, category: string, ruleFp: Partial<Rule>): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.agent_rules?.[agentId]?.[category];\n if (cat) {\n const targetFp = _ruleFingerprint(ruleFp);\n cat.rules = (cat.rules || []).filter(r => _ruleFingerprint(r) !== targetFp);\n }\n saveRuntimeConfig(runtime);\n return runtime;\n}\n\n/** 切换某 agent 某类别的 category_enabled(整类开关,与通用规则分类开关同范式)。 */\nexport function updateAgentCategoryEnabled(agentId: string, category: string, enabled: boolean): RuntimeConfig {\n const runtime = loadRuntimeConfig();\n const cat = runtime.agent_rules?.[agentId]?.[category];\n if (cat) cat.category_enabled = enabled;\n saveRuntimeConfig(runtime);\n return runtime;\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\nexport function 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 let ext: AgentExtensions | null = null;\n // 统一存储:优先读 runtime_config 的 agent_rules 分区(用户可在 console\n // 查看/编辑/禁用/新增,享受与通用规则一致的合并升级)。回退 rules.json\n // (无 runtime_config 时,如直接起服务未 seed、或旧部署)。\n try {\n const { hasRuntimeConfig, loadRuntimeConfig, getEnabledAgentExtensions } = require('../infra/runtime-config');\n if (hasRuntimeConfig()) {\n ext = getEnabledAgentExtensions(loadRuntimeConfig(), agentId);\n }\n } catch { /* runtime-config 不可用时回退 rules.json */ }\n\n if (ext === null) {\n const agentsDir = resolveAgentsDir();\n const rulesFile = resolve(agentsDir, agentId, 'rules.json');\n if (!existsSync(rulesFile)) {\n cache.set(agentId, null);\n return null;\n }\n try {\n const raw = readFileSync(rulesFile, 'utf-8');\n 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 } 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 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 `${ext.builtin_safe_action_types?.length ?? 0} builtin safe action types`\n );\n return ext;\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';\nimport {\n ROOT_SENSITIVE_PATHS,\n HOME_SENSITIVE_PATHS,\n CREDENTIAL_PATHS,\n isWriteOperation,\n} from './logic-rules';\n\n/**\n * Layer 1: Feature-matching 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 — var 分支排除 /var/tmp/(合法清理)\n { pattern: /\\brm\\s+-[a-zA-Z]*[rf][a-zA-Z]*\\s+\\/(etc|var(?!\\/tmp)|home|usr|boot|root|opt|srv|sys|proc)\\b/i, severity: 'critical', description: '删除关键系统目录', riskType: 'script_execution' },\n // 3. rm -r absolute path (no -f) — 排除 /tmp/ /var/tmp/ /run/ /dev/shm/(CI/开发高频合法清理)\n { pattern: /\\brm\\s+-[a-zA-Z]*r[a-zA-Z]*\\s+\\/(?!tmp\\/|var\\/tmp\\/|run\\/|dev\\/shm\\/)/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+\\/(?!tmp\\/|var\\/tmp\\/|run\\/|dev\\/shm\\/)/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 // curl|bash 优先匹配 user_rules(high/sensitive_action),见下方 UserRuleMatcher 段;\n // 非 bash 的 curl|sh/zsh/dash 走 CommandPatternScanner critical。两条分流由\n // runHeuristicCheck 的规则顺序保证(bash 在前 high,其余 fall-through 到 critical)。\n { pattern: /curl\\s+.*\\|\\s*bash/i, severity: 'high', description: 'curl pipe bash 执行 (user_rules)', riskType: 'sensitive_action' },\n { pattern: /curl\\s+.*\\|\\s*(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: 'high', description: 'base64 解码执行 (user_rules)', riskType: 'sensitive_action' },\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(?!\\.pub)/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 // --- Critical: dangerous permissions / ownership (提权 / 权限敞口) ---\n // 修正「只拦 777、xx7 漏放」的缺口:\n // 1) 八进制末位 7:other 位含写+执行敞口(chmod 777/647/007/4777 等);644/755/1700 不命中\n // 2) 八进制 setuid/setgid 位:首位 4(setuid)/2(setgid) 的 4 位八进制(chmod 4755/2755)\n // 3) 符号 setuid/setgid:chmod u+s / g+s / a+s\n // 普通权限修改(chmod 644)不在此列——L2 read_before_write 已豁免 chmod/chown(不写内容),\n // 危险形态在此 L1 专门拦,以「提权」正确理由拦截,不再靠 RBW 误打误撞。\n { pattern: /chmod\\s+[0-7]{0,3}7\\b/i, severity: 'critical', description: '危险权限设置 (chmod ...7, other 位含写+执行敞口)', riskType: 'privilege_escalation' },\n { pattern: /chmod\\s+[24][0-7]{3}\\b/i, severity: 'critical', description: 'setuid/setgid 位设置 (chmod 4xxx/2xxx, 提权)', riskType: 'privilege_escalation' },\n { pattern: /chmod\\s+[ugoa]\\+s\\b/i, severity: 'critical', description: '符号 setuid/setgid 设置 (chmod u+s/g+s/a+s, 提权)', riskType: 'privilege_escalation' },\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 // > /etc/ 重定向覆盖:对齐 Python CommandPatternScanner `>\\s*/etc/`(不兼容引号路径),\n // 引号包裹的重定向目标(cat > '/etc/ssh/sshd_config')走 checkSensitivePath 敏感路径 high。\n { pattern: />\\s*\\/etc\\//i, severity: 'critical', description: '覆盖写入系统配置目录', riskType: 'file_access' },\n { pattern: />\\s*\\/boot\\//i, severity: 'critical', description: '覆盖写入启动引导目录', riskType: 'file_access' },\n // 注:/proc/ 重定向覆盖走 checkSensitivePath 的 high(内核参数 /proc/sys/),此处不拦 /proc/ 避免遮蔽(对齐 Python)。\n // --- High: download script + execute risk ---\n // curl -X POST 外传敏感信息(对齐 Python linux.py: curl POST env/key/token)\n { pattern: /curl\\s+.*-X\\s+POST.*\\b(env|environment|secret|key|token|password)\\b/i, severity: 'high', description: '检测到通过 curl POST 外传可能包含敏感信息的请求', riskType: 'data_exfiltration' },\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+.*\\b(?:chmod|chown)\\s+\\+x\\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 // 两条规则:第一条匹配 ~ 与 /home/<user>/ 形态;第二条按文件名兜底,\n // 覆盖非标准 home 路径(如鸿蒙 /storage/Users/currentUser/.bashrc、\n // /root/.bashrc),避免按 home 前缀枚举导致漏检持久化后门。\n { pattern: />>\\s*(~|\\/home\\/[^/]+)\\/(\\.bashrc|\\.zshrc|\\.profile|\\.bash_profile|\\.zprofile)/, severity: 'high', description: '检测到修改 Shell 配置文件(~/.bashrc 等),可能用于持久化后门', riskType: 'persistence' },\n { pattern: />>\\s*\\S*\\/(\\.bashrc|\\.zshrc|\\.profile|\\.bash_profile|\\.zprofile)\\b/, 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(对齐 Python UserRuleMatcher 命中即短路返回,\n // 不让后续 CommandPatternScanner/SensitivePathChecker 叠加取最高遮蔽 user rules 的判定)。\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 return {\n allowed: false,\n reason: `命中用户敏感动作规则: ${rule.description || rule.pattern}`,\n riskLevel: rule.severity as SecurityJudgment['riskLevel'],\n riskType: 'sensitive_action',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // Allow rules just pass through\n }\n } catch { /* invalid regex, skip */ }\n }\n\n // Check built-in dangerous patterns\n // NEW-FP-I: echo/printf 引号内参数是字面量非真实命令,剥掉引号内容后再匹配,\n // 避免 echo \"rm -rf /tmp\" 的输出文本被当真实命令误报。引号外的重定向 > 和管道 |\n // 后的真实操作保留(echo \"x\" > /etc/passwd 仍被 >/etc/ 检测,echo pass | passwd\n // 的 passwd 仍被匹配)。非 echo/printf 段(rm -rf; echo done 的 rm 段)不剥。\n const scanDetail = stripLiteralTextSegments(input.aNext.actionDetail);\n const scanCommand = `${input.aNext.actionType}: ${scanDetail}`;\n let topRiskType = '';\n for (const rule of DANGEROUS_PATTERNS) {\n if (rule.pattern.test(scanCommand)) {\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(scanCommand)) {\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 // ===== 从 L2 搬入的静态子检测器(只看 a_next)=====\n const actionTypeL = input.aNext.actionType.toLowerCase();\n const detailL = input.aNext.actionDetail.toLowerCase();\n const isExcludedType = SENSITIVE_EXCLUDED_PREFIXES.some(p => actionTypeL.startsWith(p));\n\n // 危险操作模式检测优先(对应 Python CommandPatternScanner 第2检测器,先于 SensitivePathChecker):\n // 含 > /etc/ > /boot/ 重定向覆盖 critical——echo >> /etc/passwd 命中 critical 短路,\n // 不走后面的 checkSensitivePath high(对齐 Python ground truth)。\n const dangerousResult = checkDangerousPatterns(actionTypeL, detailL);\n if (dangerousResult) return dangerousResult;\n\n // 敏感路径访问检测:deny_both/deny_read/deny_write + 凭据边界匹配。\n // 排除 memory-/skill- 等非文件工具前缀,避免参数关键词误报。\n if (!isExcludedType) {\n const pathResult = checkSensitivePath(detailL, input.cwd || '/', agentExt);\n if (pathResult) return pathResult;\n }\n\n // 用户敏感规则命中(custom_rule)须先于敏感路径和横向移动检测:\n // - 避免 ssh -o StrictHostKeyChecking=no 被 checkLateralMovement 标 lateral medium 遮蔽\n // (Python UserRuleMatcher 先于 LateralMovementChecker)。\n // - 避免 ssh ... 'cat /etc/shadow' 被 checkSensitivePath 的 /etc/shadow critical 遮蔽\n // (Python UserRuleMatcher 先于 SensitivePathChecker,user rules high 优先于敏感路径 critical)。\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 // 横向移动检测:ssh/scp/rsync 到非本机主机\n const lateralResult = checkLateralMovement(detailL);\n if (lateralResult) return lateralResult;\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\n/**\n * NEW-FP-I: 对首词 echo/printf 的命令段剥掉引号内容(字面量参数)。\n *\n * echo/printf 是文本输出命令,其引号内参数是被打印的字面量而非真实命令——\n * `echo \"rm -rf /tmp\"` 是打印这串文本不是执行删除。但 DANGEROUS_PATTERNS 旧实现\n * 对整个 actionDetail 做正则匹配,引号内的 rm/chmod/mkfs 等危险命令模式被误当\n * 真实命令匹配 → 误报(NEW-FP-I)。\n *\n * 修复:按 &&/||/;/换行 分段,首词是 echo/printf 的段,剥掉引号内容(字面量),\n * 保留引号外的重定向 >/>> 和管道 | 后的真实操作:\n * - `echo \"rm -rf /tmp\"` → `echo `(rm 模式不匹配,误报消除)\n * - `echo \"x\" > /etc/passwd` → `echo > /etc/passwd`(重定向 >/etc/ 仍匹配,真实写不漏报)\n * - `rm -rf /tmp; echo done` → rm 段不剥,echo 段剥,rm 仍匹配(真实危险不漏报)\n * - `echo pass | passwd` → passwd 无引号在管道后,剥后仍保留(管道注入不漏报)\n */\nexport function stripLiteralTextSegments(actionDetail: string): string {\n // 旁路(NEW-FN-H 待修):含\"写脚本 + 后续执行\"或\"管道喂解释器\"绕过链时整条不剥离。\n // 保留引号内路径让 L1 凭据检测兜底,避免剥离后绕过链漏检(inline-09/10 依赖)。\n // - inline-09: echo \"cat /etc/shadow\" > /tmp/x.sh && bash /tmp/x.sh(写脚本+执行)\n // - inline-10: printf 'cat /etc/shadow' | bash(管道喂解释器)\n const writeScriptExec = />\\s*[/~]\\S*\\.(sh|py|pl|rb)\\b/.test(actionDetail) &&\n /(?:&&|\\|\\||;|\\n|\\|)\\s*(?:bash|sh|zsh|dash|python|perl|ruby|node)/.test(actionDetail);\n const pipeToInterpreter = /\\|\\s*(?:bash|sh|zsh|dash|python|perl|ruby|node)\\b/.test(actionDetail);\n if (writeScriptExec || pipeToInterpreter) {\n return actionDetail;\n }\n // 按命令分隔符分段,但跳过引号内的分隔符(echo \"a; b\" 的 ; 在引号内不分段)\n const resultParts: string[] = [];\n for (const seg of splitCommandSegments(actionDetail)) {\n const fw = (seg.trim().split(/\\s+/)[0] || '').toLowerCase();\n if (fw === 'echo' || fw === 'printf') {\n // 先摘重定向目标的引号路径为裸路径(保留真实写目标),再剥剩余引号内容\n const segUnquotedRedirect = seg.replace(\n />{1,2}\\s*(['\"])([~./][^'\"]+)\\1/g,\n (_m, _q, p: string) => '>' + p,\n );\n resultParts.push(segUnquotedRedirect.replace(/'[^']*'|\"[^\"]*\"/g, ''));\n } else {\n resultParts.push(seg);\n }\n }\n return resultParts.join('');\n}\n\n/**\n * 剥离 heredoc 文档字面量内容(<<EOF ... EOF / <<'EOF' ... EOF)。\n * heredoc 是文档正文不是命令,其中的 `*`/`?`/`rm`/`删除` 是文本而非删除操作。\n * 不剥离会导致 checkDangerousPatterns 的「通配符+删除」误判写文档为批量删除\n * (NEW-FP:写含 markdown 加粗 / 三元表达式 / 描述含 rm 的周报即误报)。\n * 支持 <<EOF / <<-EOF / <<'EOF' / <<\"EOF\",匹配到行首结束标记,替换为 <<heredoc>>。\n */\nexport function stripHeredocContent(actionDetail: string): string {\n return actionDetail.replace(\n /<<-?\\s*(?:['\"]?)([A-Za-z_][A-Za-z0-9_]*)(?:['\"]?)[^\\n]*\\n[\\s\\S]*?\\n\\s*\\1\\s*(?:\\n|$)/g,\n '<<heredoc>>\\n',\n );\n}\n\n/**\n * 按命令分隔符分段,跳过引号内的分隔符(对齐 Python _split_command_segments)。\n * echo \"a; b && c\" 的引号内分隔符是字面量非命令分隔,不能分段——否则\n * 引号内 chmod/mkfs 等词会脱离 echo 段被当独立命令首词误匹配(NEW-FP-I)。\n */\nfunction splitCommandSegments(actionDetail: string): string[] {\n const segments: string[] = [];\n let cur = '';\n let quote: string | null = null;\n for (let i = 0; i < actionDetail.length; i++) {\n const ch = actionDetail[i];\n if (quote) {\n cur += ch;\n if (ch === quote) quote = null;\n continue;\n }\n if (ch === \"'\" || ch === '\"') {\n quote = ch;\n cur += ch;\n continue;\n }\n if (ch === ';' || ch === '\\n') {\n segments.push(cur); segments.push(ch); cur = '';\n continue;\n }\n if (ch === '&' && actionDetail[i + 1] === '&') {\n segments.push(cur); segments.push('&&'); cur = '';\n i++; continue;\n }\n if (ch === '|' && actionDetail[i + 1] === '|') {\n segments.push(cur); segments.push('||'); cur = '';\n i++; continue;\n }\n cur += ch;\n }\n if (cur) segments.push(cur);\n return segments;\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// ==================== 从 L2 搬入 L1 的静态子检测器 ====================\n// 以下三个检测器只看 a_next(不看 action_history),按\"L1 只看这一步\"原则\n// 从 logic-rules.ts 搬入。逻辑原样保留,source 改为 'heuristic'、\n// violatedLayers 改为 ['1.1'],对齐 L1 命令模式/注入关键词的层号。\n\n// 敏感路径检测排除的非文件工具前缀(避免 memory-searchMemory 等误报)\nconst SENSITIVE_EXCLUDED_PREFIXES = ['memory-', 'skill-', 'skill-manager-', 'mailbox-', 'app-'];\n\n/**\n * 敏感路径访问检测(从 L2 搬入)。\n * deny_both(凭据):无论读写都拦截,isCredential=true\n * deny_read:只拦截读取(如 /dev/random)\n * deny_write:只拦截写入/删除\n */\nexport function checkSensitivePath(\n command: string,\n cwd: string,\n agentExt?: import('../agents').AgentExtensions | null,\n): SecurityJudgment | null {\n const expandedCwd = cwd.replace(/^~/, process.env.HOME || '/home/user');\n\n // 写判定统一用 isWriteOperation(对齐 Python _is_write_operation 单一事实源),\n // 替代原手写 isWriteOpFlag(含 ''.includes(kw) 笔误、重定向逻辑矛盾)。\n // command 在此 = actionDetail 小写(调用方 :231 传 detailL),actionType 留空——\n // isWriteOperation 的 actionType.includes 走空串无影响,actionDetail 部分覆盖 command。\n const isWriteOpFlag = isWriteOperation('', command);\n\n // NEW-FP-I: echo/printf 引号内参数是字面量,其中的敏感路径不应被当真实访问。\n // 对首词 echo/printf 的段剥引号内容后再做路径匹配。非 echo/printf 段(cat \"/etc/shadow\")\n // 不剥,引号内真实路径参数仍匹配。引号外的重定向(echo \"x\" > /etc/passwd)保留。\n const pathScanText = stripLiteralTextSegments(command);\n\n // 边界路径匹配(对齐 Python heuristic.py:121-132,避免子串误报)。\n // 裸 command.includes(sp.path) 会把 /etc/passwd 命中到 /tmp/etc_passwd_backup、\n // /boot/ 命中到 /boot-log。改用边界正则:/ 开头路径前导用 ^|空白|/|反斜杠|引号,\n // 其余用 \\b;尾随 \\b。凭据(deny_both)尤其需要边界(如 .env 不能命中 .environment)。\n const pathMatches = (text: string, path: string): boolean => {\n // 含正则前瞻语法(如 (?!\\\\.pub) 排除公钥变体)时保留前瞻不转义,仅转义其余元字符。\n // 把路径切成「前瞻块 / 其余」分段处理,前瞻块原样保留,其余分段转义元字符。\n const parts = path.split(/(\\(\\?!.*?\\))/);\n const escaped = parts.map(part => {\n if (part.startsWith('(?!')) return part; // 前瞻块原样\n return part.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }).join('');\n const re = path.startsWith('.') || path.startsWith('/')\n ? new RegExp(`(?:^|[\\\\s/\\\\\\\\'\"])${escaped}\\\\b`, 'i')\n : new RegExp(`\\\\b${escaped}\\\\b`, 'i');\n return re.test(text);\n };\n\n for (const sp of ROOT_SENSITIVE_PATHS) {\n if (pathMatches(pathScanText, 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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n isCredential: !!sp.credential,\n };\n }\n }\n\n for (const sp of HOME_SENSITIVE_PATHS) {\n const expanded = `${expandedCwd}/${sp.path}`;\n // 私钥路径(不以 .pub 结尾)排除公钥变体:.ssh/id_rsa 不应命中 .ssh/id_rsa.pub(公钥公开)\n const pathRe = sp.path.endsWith('.pub')\n ? new RegExp(sp.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'i')\n : new RegExp(sp.path.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + '(?!\\\\.pub)', 'i');\n const expandedRe = sp.path.endsWith('.pub')\n ? new RegExp(expanded.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'i')\n : new RegExp(expanded.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') + '(?!\\\\.pub)', 'i');\n if (pathRe.test(pathScanText) || expandedRe.test(pathScanText)) {\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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n isCredential: !!sp.credential,\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 (pathMatches(command, spPath) || pathMatches(command, 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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n isCredential: !!sp.credential,\n };\n }\n }\n }\n\n // 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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\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: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n\n return null;\n}\n\n/** 危险操作模式检测(从 L2 搬入):通配符+删除、重定向覆盖 /etc /boot /proc */\nexport function checkDangerousPatterns(actionType: string, actionDetail: string): SecurityJudgment | null {\n if (actionType === 'file_write' || actionType === 'file_edit') return null;\n\n // Wildcard + delete — 排除 /tmp 等临时目录的清理操作\n // 用边界正则匹配目录名本身(/tmp 和 /tmp/ 都算),避免 `find /tmp -delete`\n // 因 \"/tmp/\" 子串不匹配(/tmp 后是空格)而 isTempPath=false 误报(Bug6)。\n // NEW-FP(鸿蒙写周报误报):先剥离 heredoc 文档字面量内容——文档正文里的\n // `*`/`?`/`rm`/`删除` 是文本不是真实删除命令,不剥离会误判为批量删除。\n const scan = stripHeredocContent(actionDetail);\n const TEMP_DIRS = ['/tmp', '/var/tmp', '/run', '/dev/shm'];\n const isTempPath = TEMP_DIRS.some(td =>\n new RegExp(`(?:^|[\\\\s/])${td.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}(?:[\\\\s/]|$)`).test(actionDetail)\n );\n // 通配符必须紧邻删除命令(真实命令 token),而非任意位置子串。\n // 收紧:`*`/`?` 出现在删除命令(rm/del/delete/remove/删除/移除)附近——\n // 匹配「删除命令 + 通配符路径」组合,如 `rm -rf /tmp/*`、`rm *`、`find . -delete`。\n // 不再用 actionDetail.includes('*') && includes('rm') 的宽泛子串匹配,\n // 避免文档正文/heredoc/grep 模式里的字面量误报。\n const wildcardDeleteRe =\n /(?:\\brm\\b|\\b(r?mdir|del|delete|remove|rmdir|unlink)\\b|\\b删除\\b|\\b移除\\b)[\\s\\S]{0,40}?[*?]|[*?][\\s\\S]{0,40}?\\b(?:rm|del|delete|remove|rmdir|unlink)\\b|rm\\s+-[a-zA-Z]*[rf][a-zA-Z]*\\s+\\S*[*?]/i;\n if (!isTempPath && wildcardDeleteRe.test(scan)) {\n return {\n allowed: false,\n reason: '检测到通配符结合删除操作,可能造成批量误删',\n riskLevel: 'high',\n riskType: 'script_execution',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // find -exec <写命令> / find | xargs <写命令> — find 在 READ_ONLY_COMMANDS 导致整段\n // 被当只读,-exec 或 | xargs 后的 chmod/cp/mv/rm/sed -i 等写命令漏检(NEW-FN-C: -exec;\n // NEW-FN-E: | xargs 等价变体未覆盖)。find 遍历出的文件被批量执行写操作,静态无法确定\n // 具体目标文件,但「find + 写命令」组合本身就是批量写意图,此处识别 -exec/-execdir/-ok\n // 后紧跟写命令、或 | xargs 后紧跟写命令即拦截。只匹配写命令首词,避免 -exec grep /\n // | xargs ls 等只读误报。xargs 后的 sed -i 单独匹配(sed -i 是 sed + -i 参数)。\n const findWriteMatch = actionDetail.match(\n /\\bfind\\b.*?(?:(?:^|\\s)-exec(?:dir)?\\s+(chmod|chown|cp|mv|rm|dd|tee|truncate|mkfs|shred|rmdir|unlink)\\b|(?:^|\\s)\\|\\s*xargs\\s+(?:sed\\s+-[a-zA-Z]*i|chmod|chown|cp|mv|rm|dd|tee|truncate|mkfs|shred|rmdir|unlink)\\b)/i\n );\n if (findWriteMatch) {\n const cmdHit = findWriteMatch[1] || 'xargs';\n return {\n allowed: false,\n reason: `检测到 find 批量执行写操作 (${cmdHit}),可能批量修改/删除文件`,\n riskLevel: 'high',\n riskType: 'script_execution',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // Redirect overwrite to system directories(对齐 Python CommandPatternScanner `>\\s*/etc/` critical,不排除敏感路径)。\n // echo >> /etc/passwd、cat > /etc/ssh/sshd_config 均命中 critical 短路(Python ground truth)。\n if (/>\\s*\\/etc\\//.test(actionDetail) || />\\s*\\/boot\\//.test(actionDetail)) {\n return {\n allowed: false,\n reason: '检测到重定向覆盖写入关键系统目录',\n riskLevel: 'critical',\n riskType: 'file_access',\n confidence: 95,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n // A16: 重定向覆盖设备文件(对齐 Python linux.py:180 `>\\s*/dev/(sd|hd|nvme|vd|loop|mem|kmsg|port|zero|random|urandom|full|core)`)。\n // high/file_access。须先于 checkSensitivePath 的 /dev/mem critical 命中,避免写 /dev/mem 被标 critical(Python 是 high)。\n if (/>\\s*\\/dev\\/(sd|hd|nvme|vd|loop|mem|kmsg|port|zero|random|urandom|full|core)/i.test(actionDetail)) {\n return {\n allowed: false,\n reason: '检测到重定向写入设备文件',\n riskLevel: 'high',\n riskType: 'file_access',\n confidence: 90,\n source: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n return null;\n}\n\n\nfunction extractRemoteHost(command: string): string | null {\n // NEW-FN-G: 旧正则 (?:ssh|scp|rsync)\\s+(?:-[\\w]+\\s+)*(\\S+@\\S+|\\b(?!-)[\\w.-]+\\b)\n // 的 (?:-[\\w]+\\s+)* 只匹配单选项不匹配带参数值选项(-p 2222、-L 8080:...、\n // -D 1080、-e ssh),导致 host 提取取到端口号或选项参数。token 化三策略更可靠。\n // NEW-FP-E: bash -c/sh -c \"ssh user@host\" 的 user@host 被引号包裹成 \"user@host\"\n // 正则不匹配(\" 非 \\w)→ 漏报。bash -c 内联命令是真实调用,应检测。\n // 剥 token 首尾引号后再匹配(python -c 已在 checkLateralMovement 开头 INLINE_SCRIPT_RE 跳过)。\n const tokens = command.split(/\\s+/).map(t => t.replace(/^[\"']|[\"']$/g, ''));\n // 策略1:优先找 user@host 或 user@host: 模式(最可靠,带值选项参数值如\n // -L 8080:localhost:80 的 localhost 会被 isLocalHost 排除,不会误匹配)。\n for (const tok of tokens) {\n const am = tok.match(/^([\\w.-]+)@([\\w.-]+)(:.*)?$/);\n if (am && am[2] && !isLocalHost(am[2])) {\n return `${am[1]}@${am[2]}`;\n }\n }\n // 策略2:host: 模式(rsync/scp 远程路径 host:/path,无 user@)\n for (const tok of tokens) {\n const hm = tok.match(/^([\\w.-]+):\\/(.*)?$/);\n if (hm && hm[1] && !isLocalHost(hm[1])) {\n return hm[1];\n }\n }\n // 策略3:回退\"第一个非选项 token\"(ssh host 无 @ 无 :,如 ssh 10.0.0.5)。\n // 跳过 - 开头选项及其参数值(-p 2222 / -e ssh / -L 8080:...)。\n const skipValueOpts = new Set([\n '-p', '-l', '-i', '-o', '-b', '-c', '-m', '-F',\n '-e', '-S', '-W', '-J', '-I', '-T', '-B',\n '-L', '-R', '-D', '-E', '-M', '-O', '-P', '-q',\n ]);\n let foundCmd = false;\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i];\n if (t === 'ssh' || t === 'scp' || t === 'rsync') {\n foundCmd = true;\n continue;\n }\n if (!foundCmd) continue;\n if (t.startsWith('-')) {\n // 带值选项:跳过下一个 token(-p 2222 / -e ssh / -L 8080:...)\n if (skipValueOpts.has(t) && i + 1 < tokens.length) {\n i++;\n }\n continue;\n }\n // 非选项 token:候选主机。排除纯路径(/ 开头本地路径非主机名)。\n if (t.startsWith('/')) continue;\n return t;\n }\n return 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\n/** 横向移动检测(从 L2 括入):ssh/scp/rsync 到非本机主机 */\nexport function checkLateralMovement(actionDetail: string): SecurityJudgment | null {\n // NEW-FP-D: 内联脚本(python -c / perl -e 等)里的 ssh/scp/rsync 是字面量非真调用,\n // 跳过交 inline-analyzer 专门管,与 intent/privilege 一致\n if (/\\b(?:python|python3|perl|ruby|node|php|lua)\\b\\s+.*-[cer][a-zA-Z]*\\s/.test(actionDetail)) return null;\n\n // NEW-FP-D: echo/printf �首词的参数是字面量非真调用(echo ssh user@host 是打印字面量)\n // 按命令段判定:首词 echo/printf 跳过,与 isWriteOperation 的 wget/curl 字面量判定一致\n const segments = actionDetail.split(/&&|\\|\\||;|\\n/).map(s => s.trim()).filter(Boolean);\n let hasRealCall = false;\n for (const seg of segments) {\n const parts = seg.split(/\\s+/);\n const fw = (parts[0] || '').toLowerCase();\n if (fw === 'echo' || fw === 'printf') continue;\n if (/(?:ssh|scp|rsync)\\s+/.test(seg)) { hasRealCall = true; break; }\n }\n if (!hasRealCall) return null;\n\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: 'heuristic',\n violatedLayers: ['1.1'],\n };\n }\n }\n return null;\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 <data_root>/agent_moss_token_stats.json\n * (default ~/.config/agentmoss). With AGENT_MOSS_INSTANCE the file is isolated\n * to <data_root>/<instance>/ (see infra/paths.ts). env override\n * AGENT_MOSS_TOKEN_STATS_PATH wins. Whole-file rewrite per record (not append).\n * Max 10000 records, oldest trimmed.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'fs';\nimport { join } from 'path';\nimport { getTokenStatsPath } from '../infra/paths';\n\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 if (envPath) return envPath;\n return getTokenStatsPath();\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 } as any);\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 // LLM 回 JSON 字段名可能是 camelCase(riskLevel)或 snake_case(risk_level),\n // 两种都兼容避免拿不到 risk_level 走兜底 'low'(双端对齐 Python 字段名)\n const riskLevel = parsed.riskLevel ?? parsed.risk_level;\n const riskType = parsed.riskType ?? parsed.risk_type;\n return {\n allowed: parsed.allowed !== false,\n reason: parsed.reason || 'LLM 分析完成',\n riskLevel: ['low', 'medium', 'high', 'critical'].includes(riskLevel) ? riskLevel : 'low',\n riskType: 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","import { SecurityJudgment } from './types';\nimport { runHeuristicCheck, isInlineScriptCommand, DANGEROUS_PATTERNS } from './heuristic';\nimport { runLogicCheck, isWriteOperation } 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: Feature-matching 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 // 对齐 py coordinator.py:172-176 should_deny_l1:\n // high/critical 直接 Deny;\n // medium + file_access(敏感路径写)确定性拦截;\n // 其他 medium(如 git push --force / rm -f 单文件 / prompt 注入 repeat-instructions)\n // 不直接 Deny,fall-through 到 L2/L3。\n const shouldDenyL1 =\n heuristicResult.riskLevel === 'high' ||\n heuristicResult.riskLevel === 'critical' ||\n (heuristicResult.riskLevel === 'medium' && heuristicResult.riskType === 'file_access');\n if (shouldDenyL1) {\n return heuristicResult;\n }\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 // agent 专属扩展(agent_moss/agents/<id>/rules.json),取一次供 fast-pass 各白名单复用\n const agentExt = getAgentExtensions(input.agentId);\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 // agent 专属完全安全操作白名单(精确名或前缀,来自 rules.json builtin_safe_action_types)。\n // 前缀以 '-' 结尾 → startswith 匹配(如 \"memory-\");否则精确名匹配(如 \"mailbox-getEmailList\")。\n // 命中即跳过 L2+L3,与 builtin_safe_skills 同范式。仅对该 agent_id 生效,不污染其他 agent。\n // OpenDesk 的 memory-*/todomgr-*/planning-* 是纯数据/只读操作,走 L3 LLM 耗时 1~137s 无意义。\n if (agentExt?.builtin_safe_action_types && agentExt.builtin_safe_action_types.length > 0) {\n // actionType 已小写化(:143);rules.json 精确名可能是驼峰(如 mailbox-getEmailList),\n // 故比较时对白名单项也 lower。前缀项(尾随 '-')同样 lower 后 startswith。\n const hit = agentExt.builtin_safe_action_types.some(t => {\n const tl = t.toLowerCase();\n return tl.endsWith('-') ? actionType.startsWith(tl) : actionType === tl;\n });\n if (hit) {\n return {\n allowed: true,\n reason: `agent 内部安全操作,跳过深度分析: ${actionType}`,\n riskLevel: (heuristicResult?.riskLevel || 'low') as SecurityJudgment['riskLevel'],\n riskType: '',\n confidence: 95,\n source: 'whitelist_bypass',\n violatedLayers: [],\n };\n }\n }\n\n // 内置安全 Skill 直接放行(通用 baseline + agent_ext.builtin_safe_skills)\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 // 安全兜底 1:检查完整命令是否命中高危模式(如 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 // 安全兜底 2:检查是否含真实重定向写(echo x > file / printf >> file)。\n // is_fully_safe_bash_command 只看首命令名(echo),会忽略 >/>> 重定向,\n // 导致 `echo x > /tmp/existing.txt` 覆写已存在文件被白名单放行跳过 L2(Bug3)。\n // 复用 isWriteOperation 的重定向判定(已剥 devnull + 比较运算符 + 只读首词保护)。\n const hasRedirectWrite = isWriteOperation(firstCmd, lowerDetail);\n if (!fullCmdHit && !hasRedirectWrite) {\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 // file_access 命中合并:敏感路径/危险模式现已在 L1(heuristicResult),\n // 间接文件访问仍在 L2(logicResult)。两者任一命中 file_access 都需进入\n // inline/credential 包装判定。优先采用 logicResult,退而取 heuristicResult。\n const l1FileAccessHit = !!(heuristicResult && !heuristicResult.allowed && heuristicResult.riskType === 'file_access');\n const effectiveResult = (logicResult && !logicResult.allowed) ? logicResult\n : (l1FileAccessHit ? heuristicResult : null);\n if (effectiveResult) {\n // 凭据文件:无论读写、无论是否 inline,都直接拒绝。\n // 来源:L1 sensitive path(isCredential)或 L2 indirect_file_access\n const isCredentialPath = !!effectiveResult.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) && effectiveResult.riskType === 'file_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 ((effectiveResult.riskLevel === 'high' || effectiveResult.riskLevel === 'critical') && (!skipInlineFileAccess || isCredentialPath)) {\n return effectiveResult;\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","'use strict';\n\nexports.getBooleanOption = (options, key) => {\n\tlet value = false;\n\tif (key in options && typeof (value = options[key]) !== 'boolean') {\n\t\tthrow new TypeError(`Expected the \"${key}\" option to be a boolean`);\n\t}\n\treturn value;\n};\n\nexports.cppdb = Symbol();\nexports.inspect = Symbol.for('nodejs.util.inspect.custom');\n","'use strict';\nconst descriptor = { value: 'SqliteError', writable: true, enumerable: false, configurable: true };\n\nfunction SqliteError(message, code) {\n\tif (new.target !== SqliteError) {\n\t\treturn new SqliteError(message, code);\n\t}\n\tif (typeof code !== 'string') {\n\t\tthrow new TypeError('Expected second argument to be a string');\n\t}\n\tError.call(this, message);\n\tdescriptor.value = '' + message;\n\tObject.defineProperty(this, 'message', descriptor);\n\tError.captureStackTrace(this, SqliteError);\n\tthis.code = code;\n}\nObject.setPrototypeOf(SqliteError, Error);\nObject.setPrototypeOf(SqliteError.prototype, Error.prototype);\nObject.defineProperty(SqliteError.prototype, 'name', descriptor);\nmodule.exports = SqliteError;\n","\n/**\n * Module dependencies.\n */\n\nvar sep = require('path').sep || '/';\n\n/**\n * Module exports.\n */\n\nmodule.exports = fileUriToPath;\n\n/**\n * File URI to Path function.\n *\n * @param {String} uri\n * @return {String} path\n * @api public\n */\n\nfunction fileUriToPath (uri) {\n if ('string' != typeof uri ||\n uri.length <= 7 ||\n 'file://' != uri.substring(0, 7)) {\n throw new TypeError('must pass in a file:// URI to convert to a file path');\n }\n\n var rest = decodeURI(uri.substring(7));\n var firstSlash = rest.indexOf('/');\n var host = rest.substring(0, firstSlash);\n var path = rest.substring(firstSlash + 1);\n\n // 2. Scheme Definition\n // As a special case, <host> can be the string \"localhost\" or the empty\n // string; this is interpreted as \"the machine from which the URL is\n // being interpreted\".\n if ('localhost' == host) host = '';\n\n if (host) {\n host = sep + sep + host;\n }\n\n // 3.2 Drives, drive letters, mount points, file system root\n // Drive letters are mapped into the top of a file URI in various ways,\n // depending on the implementation; some applications substitute\n // vertical bar (\"|\") for the colon after the drive letter, yielding\n // \"file:///c|/tmp/test.txt\". In some cases, the colon is left\n // unchanged, as in \"file:///c:/tmp/test.txt\". In other cases, the\n // colon is simply omitted, as in \"file:///c/tmp/test.txt\".\n path = path.replace(/^(.+)\\|/, '$1:');\n\n // for Windows, we need to invert the path separators from what a URI uses\n if (sep == '\\\\') {\n path = path.replace(/\\//g, '\\\\');\n }\n\n if (/^.+\\:/.test(path)) {\n // has Windows drive at beginning of path\n } else {\n // unix path…\n path = sep + path;\n }\n\n return host + path;\n}\n","/**\n * Module dependencies.\n */\n\nvar fs = require('fs'),\n path = require('path'),\n fileURLToPath = require('file-uri-to-path'),\n join = path.join,\n dirname = path.dirname,\n exists =\n (fs.accessSync &&\n function(path) {\n try {\n fs.accessSync(path);\n } catch (e) {\n return false;\n }\n return true;\n }) ||\n fs.existsSync ||\n path.existsSync,\n defaults = {\n arrow: process.env.NODE_BINDINGS_ARROW || ' → ',\n compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled',\n platform: process.platform,\n arch: process.arch,\n nodePreGyp:\n 'node-v' +\n process.versions.modules +\n '-' +\n process.platform +\n '-' +\n process.arch,\n version: process.versions.node,\n bindings: 'bindings.node',\n try: [\n // node-gyp's linked version in the \"build\" dir\n ['module_root', 'build', 'bindings'],\n // node-waf and gyp_addon (a.k.a node-gyp)\n ['module_root', 'build', 'Debug', 'bindings'],\n ['module_root', 'build', 'Release', 'bindings'],\n // Debug files, for development (legacy behavior, remove for node v0.9)\n ['module_root', 'out', 'Debug', 'bindings'],\n ['module_root', 'Debug', 'bindings'],\n // Release files, but manually compiled (legacy behavior, remove for node v0.9)\n ['module_root', 'out', 'Release', 'bindings'],\n ['module_root', 'Release', 'bindings'],\n // Legacy from node-waf, node <= 0.4.x\n ['module_root', 'build', 'default', 'bindings'],\n // Production \"Release\" buildtype binary (meh...)\n ['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'],\n // node-qbs builds\n ['module_root', 'addon-build', 'release', 'install-root', 'bindings'],\n ['module_root', 'addon-build', 'debug', 'install-root', 'bindings'],\n ['module_root', 'addon-build', 'default', 'install-root', 'bindings'],\n // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}\n ['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings']\n ]\n };\n\n/**\n * The main `bindings()` function loads the compiled bindings for a given module.\n * It uses V8's Error API to determine the parent filename that this function is\n * being invoked from, which is then used to find the root directory.\n */\n\nfunction bindings(opts) {\n // Argument surgery\n if (typeof opts == 'string') {\n opts = { bindings: opts };\n } else if (!opts) {\n opts = {};\n }\n\n // maps `defaults` onto `opts` object\n Object.keys(defaults).map(function(i) {\n if (!(i in opts)) opts[i] = defaults[i];\n });\n\n // Get the module root\n if (!opts.module_root) {\n opts.module_root = exports.getRoot(exports.getFileName());\n }\n\n // Ensure the given bindings name ends with .node\n if (path.extname(opts.bindings) != '.node') {\n opts.bindings += '.node';\n }\n\n // https://github.com/webpack/webpack/issues/4175#issuecomment-342931035\n var requireFunc =\n typeof __webpack_require__ === 'function'\n ? __non_webpack_require__\n : require;\n\n var tries = [],\n i = 0,\n l = opts.try.length,\n n,\n b,\n err;\n\n for (; i < l; i++) {\n n = join.apply(\n null,\n opts.try[i].map(function(p) {\n return opts[p] || p;\n })\n );\n tries.push(n);\n try {\n b = opts.path ? requireFunc.resolve(n) : requireFunc(n);\n if (!opts.path) {\n b.path = n;\n }\n return b;\n } catch (e) {\n if (e.code !== 'MODULE_NOT_FOUND' &&\n e.code !== 'QUALIFIED_PATH_RESOLUTION_FAILED' &&\n !/not find/i.test(e.message)) {\n throw e;\n }\n }\n }\n\n err = new Error(\n 'Could not locate the bindings file. Tried:\\n' +\n tries\n .map(function(a) {\n return opts.arrow + a;\n })\n .join('\\n')\n );\n err.tries = tries;\n throw err;\n}\nmodule.exports = exports = bindings;\n\n/**\n * Gets the filename of the JavaScript file that invokes this function.\n * Used to help find the root directory of a module.\n * Optionally accepts an filename argument to skip when searching for the invoking filename\n */\n\nexports.getFileName = function getFileName(calling_file) {\n var origPST = Error.prepareStackTrace,\n origSTL = Error.stackTraceLimit,\n dummy = {},\n fileName;\n\n Error.stackTraceLimit = 10;\n\n Error.prepareStackTrace = function(e, st) {\n for (var i = 0, l = st.length; i < l; i++) {\n fileName = st[i].getFileName();\n if (fileName !== __filename) {\n if (calling_file) {\n if (fileName !== calling_file) {\n return;\n }\n } else {\n return;\n }\n }\n }\n };\n\n // run the 'prepareStackTrace' function above\n Error.captureStackTrace(dummy);\n dummy.stack;\n\n // cleanup\n Error.prepareStackTrace = origPST;\n Error.stackTraceLimit = origSTL;\n\n // handle filename that starts with \"file://\"\n var fileSchema = 'file://';\n if (fileName.indexOf(fileSchema) === 0) {\n fileName = fileURLToPath(fileName);\n }\n\n return fileName;\n};\n\n/**\n * Gets the root directory of a module, given an arbitrary filename\n * somewhere in the module tree. The \"root directory\" is the directory\n * containing the `package.json` file.\n *\n * In: /home/nate/node-native-module/lib/index.js\n * Out: /home/nate/node-native-module\n */\n\nexports.getRoot = function getRoot(file) {\n var dir = dirname(file),\n prev;\n while (true) {\n if (dir === '.') {\n // Avoids an infinite loop in rare cases, like the REPL\n dir = process.cwd();\n }\n if (\n exists(join(dir, 'package.json')) ||\n exists(join(dir, 'node_modules'))\n ) {\n // Found the 'package.json' file or 'node_modules' dir; we're done\n return dir;\n }\n if (prev === dir) {\n // Got to the top\n throw new Error(\n 'Could not find module root given file: \"' +\n file +\n '\". Do you have a `package.json` file? '\n );\n }\n // Try the parent dir next\n prev = dir;\n dir = join(dir, '..');\n }\n};\n","'use strict';\nconst { cppdb } = require('../util');\n\nexports.prepare = function prepare(sql) {\n\treturn this[cppdb].prepare(sql, this, false);\n};\n\nexports.exec = function exec(sql) {\n\tthis[cppdb].exec(sql);\n\treturn this;\n};\n\nexports.close = function close() {\n\tthis[cppdb].close();\n\treturn this;\n};\n\nexports.loadExtension = function loadExtension(...args) {\n\tthis[cppdb].loadExtension(...args);\n\treturn this;\n};\n\nexports.defaultSafeIntegers = function defaultSafeIntegers(...args) {\n\tthis[cppdb].defaultSafeIntegers(...args);\n\treturn this;\n};\n\nexports.unsafeMode = function unsafeMode(...args) {\n\tthis[cppdb].unsafeMode(...args);\n\treturn this;\n};\n\nexports.getters = {\n\tname: {\n\t\tget: function name() { return this[cppdb].name; },\n\t\tenumerable: true,\n\t},\n\topen: {\n\t\tget: function open() { return this[cppdb].open; },\n\t\tenumerable: true,\n\t},\n\tinTransaction: {\n\t\tget: function inTransaction() { return this[cppdb].inTransaction; },\n\t\tenumerable: true,\n\t},\n\treadonly: {\n\t\tget: function readonly() { return this[cppdb].readonly; },\n\t\tenumerable: true,\n\t},\n\tmemory: {\n\t\tget: function memory() { return this[cppdb].memory; },\n\t\tenumerable: true,\n\t},\n};\n","'use strict';\nconst { cppdb } = require('../util');\nconst controllers = new WeakMap();\n\nmodule.exports = function transaction(fn) {\n\tif (typeof fn !== 'function') throw new TypeError('Expected first argument to be a function');\n\n\tconst db = this[cppdb];\n\tconst controller = getController(db, this);\n\tconst { apply } = Function.prototype;\n\n\t// Each version of the transaction function has these same properties\n\tconst properties = {\n\t\tdefault: { value: wrapTransaction(apply, fn, db, controller.default) },\n\t\tdeferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },\n\t\timmediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },\n\t\texclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },\n\t\tdatabase: { value: this, enumerable: true },\n\t};\n\n\tObject.defineProperties(properties.default.value, properties);\n\tObject.defineProperties(properties.deferred.value, properties);\n\tObject.defineProperties(properties.immediate.value, properties);\n\tObject.defineProperties(properties.exclusive.value, properties);\n\n\t// Return the default version of the transaction function\n\treturn properties.default.value;\n};\n\n// Return the database's cached transaction controller, or create a new one\nconst getController = (db, self) => {\n\tlet controller = controllers.get(db);\n\tif (!controller) {\n\t\tconst shared = {\n\t\t\tcommit: db.prepare('COMMIT', self, false),\n\t\t\trollback: db.prepare('ROLLBACK', self, false),\n\t\t\tsavepoint: db.prepare('SAVEPOINT `\\t_bs3.\\t`', self, false),\n\t\t\trelease: db.prepare('RELEASE `\\t_bs3.\\t`', self, false),\n\t\t\trollbackTo: db.prepare('ROLLBACK TO `\\t_bs3.\\t`', self, false),\n\t\t};\n\t\tcontrollers.set(db, controller = {\n\t\t\tdefault: Object.assign({ begin: db.prepare('BEGIN', self, false) }, shared),\n\t\t\tdeferred: Object.assign({ begin: db.prepare('BEGIN DEFERRED', self, false) }, shared),\n\t\t\timmediate: Object.assign({ begin: db.prepare('BEGIN IMMEDIATE', self, false) }, shared),\n\t\t\texclusive: Object.assign({ begin: db.prepare('BEGIN EXCLUSIVE', self, false) }, shared),\n\t\t});\n\t}\n\treturn controller;\n};\n\n// Return a new transaction function by wrapping the given function\nconst wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {\n\tlet before, after, undo;\n\tif (db.inTransaction) {\n\t\tbefore = savepoint;\n\t\tafter = release;\n\t\tundo = rollbackTo;\n\t} else {\n\t\tbefore = begin;\n\t\tafter = commit;\n\t\tundo = rollback;\n\t}\n\tbefore.run();\n\ttry {\n\t\tconst result = apply.call(fn, this, arguments);\n\t\tif (result && typeof result.then === 'function') {\n\t\t\tthrow new TypeError('Transaction function cannot return a promise');\n\t\t}\n\t\tafter.run();\n\t\treturn result;\n\t} catch (ex) {\n\t\tif (db.inTransaction) {\n\t\t\tundo.run();\n\t\t\tif (undo !== rollback) after.run();\n\t\t}\n\t\tthrow ex;\n\t}\n};\n","'use strict';\nconst { getBooleanOption, cppdb } = require('../util');\n\nmodule.exports = function pragma(source, options) {\n\tif (options == null) options = {};\n\tif (typeof source !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\tconst simple = getBooleanOption(options, 'simple');\n\n\tconst stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);\n\treturn simple ? stmt.pluck().get() : stmt.all();\n};\n","'use strict';\nconst fs = require('fs');\nconst path = require('path');\nconst { promisify } = require('util');\nconst { cppdb } = require('../util');\nconst fsAccess = promisify(fs.access);\n\nmodule.exports = async function backup(filename, options) {\n\tif (options == null) options = {};\n\n\t// Validate arguments\n\tif (typeof filename !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\n\t// Interpret options\n\tfilename = filename.trim();\n\tconst attachedName = 'attached' in options ? options.attached : 'main';\n\tconst handler = 'progress' in options ? options.progress : null;\n\n\t// Validate interpreted options\n\tif (!filename) throw new TypeError('Backup filename cannot be an empty string');\n\tif (filename === ':memory:') throw new TypeError('Invalid backup filename \":memory:\"');\n\tif (typeof attachedName !== 'string') throw new TypeError('Expected the \"attached\" option to be a string');\n\tif (!attachedName) throw new TypeError('The \"attached\" option cannot be an empty string');\n\tif (handler != null && typeof handler !== 'function') throw new TypeError('Expected the \"progress\" option to be a function');\n\n\t// Make sure the specified directory exists\n\tawait fsAccess(path.dirname(filename)).catch(() => {\n\t\tthrow new TypeError('Cannot save backup because the directory does not exist');\n\t});\n\n\tconst isNewFile = await fsAccess(filename).then(() => false, () => true);\n\treturn runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);\n};\n\nconst runBackup = (backup, handler) => {\n\tlet rate = 0;\n\tlet useDefault = true;\n\n\treturn new Promise((resolve, reject) => {\n\t\tsetImmediate(function step() {\n\t\t\ttry {\n\t\t\t\tconst progress = backup.transfer(rate);\n\t\t\t\tif (!progress.remainingPages) {\n\t\t\t\t\tbackup.close();\n\t\t\t\t\tresolve(progress);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (useDefault) {\n\t\t\t\t\tuseDefault = false;\n\t\t\t\t\trate = 100;\n\t\t\t\t}\n\t\t\t\tif (handler) {\n\t\t\t\t\tconst ret = handler(progress);\n\t\t\t\t\tif (ret !== undefined) {\n\t\t\t\t\t\tif (typeof ret === 'number' && ret === ret) rate = Math.max(0, Math.min(0x7fffffff, Math.round(ret)));\n\t\t\t\t\t\telse throw new TypeError('Expected progress callback to return a number or undefined');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsetImmediate(step);\n\t\t\t} catch (err) {\n\t\t\t\tbackup.close();\n\t\t\t\treject(err);\n\t\t\t}\n\t\t});\n\t});\n};\n","'use strict';\nconst { cppdb } = require('../util');\n\nmodule.exports = function serialize(options) {\n\tif (options == null) options = {};\n\n\t// Validate arguments\n\tif (typeof options !== 'object') throw new TypeError('Expected first argument to be an options object');\n\n\t// Interpret and validate options\n\tconst attachedName = 'attached' in options ? options.attached : 'main';\n\tif (typeof attachedName !== 'string') throw new TypeError('Expected the \"attached\" option to be a string');\n\tif (!attachedName) throw new TypeError('The \"attached\" option cannot be an empty string');\n\n\treturn this[cppdb].serialize(attachedName);\n};\n","'use strict';\nconst { getBooleanOption, cppdb } = require('../util');\n\nmodule.exports = function defineFunction(name, options, fn) {\n\t// Apply defaults\n\tif (options == null) options = {};\n\tif (typeof options === 'function') { fn = options; options = {}; }\n\n\t// Validate arguments\n\tif (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof fn !== 'function') throw new TypeError('Expected last argument to be a function');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\tif (!name) throw new TypeError('User-defined function name cannot be an empty string');\n\n\t// Interpret options\n\tconst safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;\n\tconst deterministic = getBooleanOption(options, 'deterministic');\n\tconst directOnly = getBooleanOption(options, 'directOnly');\n\tconst varargs = getBooleanOption(options, 'varargs');\n\tlet argCount = -1;\n\n\t// Determine argument count\n\tif (!varargs) {\n\t\targCount = fn.length;\n\t\tif (!Number.isInteger(argCount) || argCount < 0) throw new TypeError('Expected function.length to be a positive integer');\n\t\tif (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');\n\t}\n\n\tthis[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);\n\treturn this;\n};\n","'use strict';\nconst { getBooleanOption, cppdb } = require('../util');\n\nmodule.exports = function defineAggregate(name, options) {\n\t// Validate arguments\n\tif (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object' || options === null) throw new TypeError('Expected second argument to be an options object');\n\tif (!name) throw new TypeError('User-defined function name cannot be an empty string');\n\n\t// Interpret options\n\tconst start = 'start' in options ? options.start : null;\n\tconst step = getFunctionOption(options, 'step', true);\n\tconst inverse = getFunctionOption(options, 'inverse', false);\n\tconst result = getFunctionOption(options, 'result', false);\n\tconst safeIntegers = 'safeIntegers' in options ? +getBooleanOption(options, 'safeIntegers') : 2;\n\tconst deterministic = getBooleanOption(options, 'deterministic');\n\tconst directOnly = getBooleanOption(options, 'directOnly');\n\tconst varargs = getBooleanOption(options, 'varargs');\n\tlet argCount = -1;\n\n\t// Determine argument count\n\tif (!varargs) {\n\t\targCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);\n\t\tif (argCount > 0) argCount -= 1;\n\t\tif (argCount > 100) throw new RangeError('User-defined functions cannot have more than 100 arguments');\n\t}\n\n\tthis[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);\n\treturn this;\n};\n\nconst getFunctionOption = (options, key, required) => {\n\tconst value = key in options ? options[key] : null;\n\tif (typeof value === 'function') return value;\n\tif (value != null) throw new TypeError(`Expected the \"${key}\" option to be a function`);\n\tif (required) throw new TypeError(`Missing required option \"${key}\"`);\n\treturn null;\n};\n\nconst getLength = ({ length }) => {\n\tif (Number.isInteger(length) && length >= 0) return length;\n\tthrow new TypeError('Expected function.length to be a positive integer');\n};\n","'use strict';\nconst { cppdb } = require('../util');\n\nmodule.exports = function defineTable(name, factory) {\n\t// Validate arguments\n\tif (typeof name !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (!name) throw new TypeError('Virtual table module name cannot be an empty string');\n\n\t// Determine whether the module is eponymous-only or not\n\tlet eponymous = false;\n\tif (typeof factory === 'object' && factory !== null) {\n\t\teponymous = true;\n\t\tfactory = defer(parseTableDefinition(factory, 'used', name));\n\t} else {\n\t\tif (typeof factory !== 'function') throw new TypeError('Expected second argument to be a function or a table definition object');\n\t\tfactory = wrapFactory(factory);\n\t}\n\n\tthis[cppdb].table(factory, name, eponymous);\n\treturn this;\n};\n\nfunction wrapFactory(factory) {\n\treturn function virtualTableFactory(moduleName, databaseName, tableName, ...args) {\n\t\tconst thisObject = {\n\t\t\tmodule: moduleName,\n\t\t\tdatabase: databaseName,\n\t\t\ttable: tableName,\n\t\t};\n\n\t\t// Generate a new table definition by invoking the factory\n\t\tconst def = apply.call(factory, thisObject, args);\n\t\tif (typeof def !== 'object' || def === null) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" did not return a table definition object`);\n\t\t}\n\n\t\treturn parseTableDefinition(def, 'returned', moduleName);\n\t};\n}\n\nfunction parseTableDefinition(def, verb, moduleName) {\n\t// Validate required properties\n\tif (!hasOwnProperty.call(def, 'rows')) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition without a \"rows\" property`);\n\t}\n\tif (!hasOwnProperty.call(def, 'columns')) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition without a \"columns\" property`);\n\t}\n\n\t// Validate \"rows\" property\n\tconst rows = def.rows;\n\tif (typeof rows !== 'function' || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"rows\" property (should be a generator function)`);\n\t}\n\n\t// Validate \"columns\" property\n\tlet columns = def.columns;\n\tif (!Array.isArray(columns) || !(columns = [...columns]).every(x => typeof x === 'string')) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"columns\" property (should be an array of strings)`);\n\t}\n\tif (columns.length !== new Set(columns).size) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with duplicate column names`);\n\t}\n\tif (!columns.length) {\n\t\tthrow new RangeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with zero columns`);\n\t}\n\n\t// Validate \"parameters\" property\n\tlet parameters;\n\tif (hasOwnProperty.call(def, 'parameters')) {\n\t\tparameters = def.parameters;\n\t\tif (!Array.isArray(parameters) || !(parameters = [...parameters]).every(x => typeof x === 'string')) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"parameters\" property (should be an array of strings)`);\n\t\t}\n\t} else {\n\t\tparameters = inferParameters(rows);\n\t}\n\tif (parameters.length !== new Set(parameters).size) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with duplicate parameter names`);\n\t}\n\tif (parameters.length > 32) {\n\t\tthrow new RangeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with more than the maximum number of 32 parameters`);\n\t}\n\tfor (const parameter of parameters) {\n\t\tif (columns.includes(parameter)) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with column \"${parameter}\" which was ambiguously defined as both a column and parameter`);\n\t\t}\n\t}\n\n\t// Validate \"safeIntegers\" option\n\tlet safeIntegers = 2;\n\tif (hasOwnProperty.call(def, 'safeIntegers')) {\n\t\tconst bool = def.safeIntegers;\n\t\tif (typeof bool !== 'boolean') {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"safeIntegers\" property (should be a boolean)`);\n\t\t}\n\t\tsafeIntegers = +bool;\n\t}\n\n\t// Validate \"directOnly\" option\n\tlet directOnly = false;\n\tif (hasOwnProperty.call(def, 'directOnly')) {\n\t\tdirectOnly = def.directOnly;\n\t\tif (typeof directOnly !== 'boolean') {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" ${verb} a table definition with an invalid \"directOnly\" property (should be a boolean)`);\n\t\t}\n\t}\n\n\t// Generate SQL for the virtual table definition\n\tconst columnDefinitions = [\n\t\t...parameters.map(identifier).map(str => `${str} HIDDEN`),\n\t\t...columns.map(identifier),\n\t];\n\treturn [\n\t\t`CREATE TABLE x(${columnDefinitions.join(', ')});`,\n\t\twrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),\n\t\tparameters,\n\t\tsafeIntegers,\n\t\tdirectOnly,\n\t];\n}\n\nfunction wrapGenerator(generator, columnMap, moduleName) {\n\treturn function* virtualTable(...args) {\n\t\t/*\n\t\t\tWe must defensively clone any buffers in the arguments, because\n\t\t\totherwise the generator could mutate one of them, which would cause\n\t\t\tus to return incorrect values for hidden columns, potentially\n\t\t\tcorrupting the database.\n\t\t */\n\t\tconst output = args.map(x => Buffer.isBuffer(x) ? Buffer.from(x) : x);\n\t\tfor (let i = 0; i < columnMap.size; ++i) {\n\t\t\toutput.push(null); // Fill with nulls to prevent gaps in array (v8 optimization)\n\t\t}\n\t\tfor (const row of generator(...args)) {\n\t\t\tif (Array.isArray(row)) {\n\t\t\t\textractRowArray(row, output, columnMap.size, moduleName);\n\t\t\t\tyield output;\n\t\t\t} else if (typeof row === 'object' && row !== null) {\n\t\t\t\textractRowObject(row, output, columnMap, moduleName);\n\t\t\t\tyield output;\n\t\t\t} else {\n\t\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded something that isn't a valid row object`);\n\t\t\t}\n\t\t}\n\t};\n}\n\nfunction extractRowArray(row, output, columnCount, moduleName) {\n\tif (row.length !== columnCount) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded a row with an incorrect number of columns`);\n\t}\n\tconst offset = output.length - columnCount;\n\tfor (let i = 0; i < columnCount; ++i) {\n\t\toutput[i + offset] = row[i];\n\t}\n}\n\nfunction extractRowObject(row, output, columnMap, moduleName) {\n\tlet count = 0;\n\tfor (const key of Object.keys(row)) {\n\t\tconst index = columnMap.get(key);\n\t\tif (index === undefined) {\n\t\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded a row with an undeclared column \"${key}\"`);\n\t\t}\n\t\toutput[index] = row[key];\n\t\tcount += 1;\n\t}\n\tif (count !== columnMap.size) {\n\t\tthrow new TypeError(`Virtual table module \"${moduleName}\" yielded a row with missing columns`);\n\t}\n}\n\nfunction inferParameters({ length }) {\n\tif (!Number.isInteger(length) || length < 0) {\n\t\tthrow new TypeError('Expected function.length to be a positive integer');\n\t}\n\tconst params = [];\n\tfor (let i = 0; i < length; ++i) {\n\t\tparams.push(`$${i + 1}`);\n\t}\n\treturn params;\n}\n\nconst { hasOwnProperty } = Object.prototype;\nconst { apply } = Function.prototype;\nconst GeneratorFunctionPrototype = Object.getPrototypeOf(function*(){});\nconst identifier = str => `\"${str.replace(/\"/g, '\"\"')}\"`;\nconst defer = x => () => x;\n","'use strict';\nconst DatabaseInspection = function Database() {};\n\nmodule.exports = function inspect(depth, opts) {\n\treturn Object.assign(new DatabaseInspection(), this);\n};\n\n","'use strict';\nconst fs = require('fs');\nconst path = require('path');\nconst util = require('./util');\nconst SqliteError = require('./sqlite-error');\n\nlet DEFAULT_ADDON;\n\nfunction Database(filenameGiven, options) {\n\tif (new.target == null) {\n\t\treturn new Database(filenameGiven, options);\n\t}\n\n\t// Apply defaults\n\tlet buffer;\n\tif (Buffer.isBuffer(filenameGiven)) {\n\t\tbuffer = filenameGiven;\n\t\tfilenameGiven = ':memory:';\n\t}\n\tif (filenameGiven == null) filenameGiven = '';\n\tif (options == null) options = {};\n\n\t// Validate arguments\n\tif (typeof filenameGiven !== 'string') throw new TypeError('Expected first argument to be a string');\n\tif (typeof options !== 'object') throw new TypeError('Expected second argument to be an options object');\n\tif ('readOnly' in options) throw new TypeError('Misspelled option \"readOnly\" should be \"readonly\"');\n\tif ('memory' in options) throw new TypeError('Option \"memory\" was removed in v7.0.0 (use \":memory:\" filename instead)');\n\n\t// Interpret options\n\tconst filename = filenameGiven.trim();\n\tconst anonymous = filename === '' || filename === ':memory:';\n\tconst readonly = util.getBooleanOption(options, 'readonly');\n\tconst fileMustExist = util.getBooleanOption(options, 'fileMustExist');\n\tconst timeout = 'timeout' in options ? options.timeout : 5000;\n\tconst verbose = 'verbose' in options ? options.verbose : null;\n\tconst nativeBinding = 'nativeBinding' in options ? options.nativeBinding : null;\n\n\t// Validate interpreted options\n\tif (readonly && anonymous && !buffer) throw new TypeError('In-memory/temporary databases cannot be readonly');\n\tif (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the \"timeout\" option to be a positive integer');\n\tif (timeout > 0x7fffffff) throw new RangeError('Option \"timeout\" cannot be greater than 2147483647');\n\tif (verbose != null && typeof verbose !== 'function') throw new TypeError('Expected the \"verbose\" option to be a function');\n\tif (nativeBinding != null && typeof nativeBinding !== 'string' && typeof nativeBinding !== 'object') throw new TypeError('Expected the \"nativeBinding\" option to be a string or addon object');\n\n\t// Load the native addon\n\tlet addon;\n\tif (nativeBinding == null) {\n\t\taddon = DEFAULT_ADDON || (DEFAULT_ADDON = require('bindings')('better_sqlite3.node'));\n\t} else if (typeof nativeBinding === 'string') {\n\t\t// See <https://webpack.js.org/api/module-variables/#__non_webpack_require__-webpack-specific>\n\t\tconst requireFunc = typeof __non_webpack_require__ === 'function' ? __non_webpack_require__ : require;\n\t\taddon = requireFunc(path.resolve(nativeBinding).replace(/(\\.node)?$/, '.node'));\n\t} else {\n\t\t// See <https://github.com/WiseLibs/better-sqlite3/issues/972>\n\t\taddon = nativeBinding;\n\t}\n\n\tif (!addon.isInitialized) {\n\t\taddon.setErrorConstructor(SqliteError);\n\t\taddon.isInitialized = true;\n\t}\n\n\t// Make sure the specified directory exists\n\tif (!anonymous && !fs.existsSync(path.dirname(filename))) {\n\t\tthrow new TypeError('Cannot open database because the directory does not exist');\n\t}\n\n\tObject.defineProperties(this, {\n\t\t[util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },\n\t\t...wrappers.getters,\n\t});\n}\n\nconst wrappers = require('./methods/wrappers');\nDatabase.prototype.prepare = wrappers.prepare;\nDatabase.prototype.transaction = require('./methods/transaction');\nDatabase.prototype.pragma = require('./methods/pragma');\nDatabase.prototype.backup = require('./methods/backup');\nDatabase.prototype.serialize = require('./methods/serialize');\nDatabase.prototype.function = require('./methods/function');\nDatabase.prototype.aggregate = require('./methods/aggregate');\nDatabase.prototype.table = require('./methods/table');\nDatabase.prototype.loadExtension = wrappers.loadExtension;\nDatabase.prototype.exec = wrappers.exec;\nDatabase.prototype.close = wrappers.close;\nDatabase.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;\nDatabase.prototype.unsafeMode = wrappers.unsafeMode;\nDatabase.prototype[util.inspect] = require('./methods/inspect');\n\nmodule.exports = Database;\n","'use strict';\nmodule.exports = require('./database');\nmodule.exports.SqliteError = require('./sqlite-error');\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 // --port 0 表示\"自动从 9090 开始找空闲端口\"\n if (port === 0) port = 9090;\n\n // startServer 内部 findFreePort:port 被占自动找空闲端口。\n const server = await startServer(host, port);\n console.log(`Listening on http://${host}:${server.port}`);\n // 必须 await serve():其内部 honoServe 起阻塞循环让进程常驻,\n // 未 await 时 main() 返回后 Node 见无 pending 任务直接 exit 0。\n await 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 try {\n execSync('sudo -n true', { stdio: 'ignore', timeout: 5000 });\n } catch {\n console.log('⚠️ 无 sudo 权限,跳过 systemd service 安装');\n console.log(' 手动启动:agent-moss server --port 0');\n process.exit(0);\n }\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\n// Only run the CLI when this file is the entry point, so the package can also\n// be imported as a library (see `exports` in package.json) without triggering\n// main() and process.exit().\nimport { fileURLToPath } from 'node:url';\nimport { realpathSync } from 'node:fs';\nconst isMain = (() => {\n try {\n if (!process.argv[1]) return false;\n // 兼容两种 spawn 方式:\n // ① node /path/to/cli.js — argv[1] 是普通路径\n // ② node file:///path/to/cli.js — argv[1] 是 file:// URL(少见)\n // realpath 规范化两端,规避 symlink / 大小写 / file:// 协议差异导致的误判。\n const thisFile = realpathSync(fileURLToPath(import.meta.url));\n const argv1 = realpathSync(\n process.argv[1].startsWith('file://') ? fileURLToPath(process.argv[1]) : process.argv[1]\n );\n return thisFile === argv1;\n } catch {\n return false;\n }\n})();\n\nif (isMain) {\n main().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n });\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: () => Promise<void>; port: number }> {\n const actualPort = await findFreePort(port, host);\n const app = createApp();\n return {\n port: actualPort,\n serve: async () => {\n console.log(`AgentMoss HTTP server on ${host}:${actualPort}`);\n // @hono/node-server 动态 import(ESM 下 require 不可用)\n // 必须 await:honoServe 会起阻塞循环让进程常驻,未 await 时 main() 返回后 Node\n // 见无 pending 任务直接 exit 0,server 起不来。\n const { serve: honoServe } = await import('@hono/node-server');\n honoServe({ fetch: app.fetch, hostname: host, port: actualPort });\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 instance: process.env.AGENT_MOSS_INSTANCE || '',\n }));\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 // agent_id 透传:优先顶层;为空兜底 metadata.agent_type(AgentGate V1\n // normalizer 历史上只把 agent_type 塞进 metadata,顶层 agent_id 为空 →\n // 定制规则不生效。AgentGate 已修,此处兜底防御其他只传 metadata 的调用方)。\n agentId: req.agent_id || (req.metadata as any)?.agent_type || '',\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 // 归属实例标识:值来自 env AGENT_MOSS_INSTANCE(spawn/systemd 注入),默认空串。\n // 多个 agentmoss 同机并存时,调用方按 instance 过滤避免连到别人的进程。\n // 空=未配置(独立部署或旧版),调用方可选择兼容或严格过滤。\n instance: z.string().default(''),\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 getAgentRules, updateAgentRuleEnabled, addAgentRule, deleteAgentRule,\n updateAgentCategoryEnabled,\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, env_overrides: getEnvOverrides() });\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, env_overrides: getEnvOverrides() });\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(rc);\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(rc);\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(rc);\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(rc);\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(rc);\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(rc);\n });\n\n // ==================== Skill 管理 ====================\n console.get('/api/skills', (c) => {\n const rc = loadRuntimeConfig();\n return c.json(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(rc);\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(rc);\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(rc);\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(rc);\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 // ==================== agent 定制规则 ====================\n console.get('/api/agents', (c) => {\n const rc = loadRuntimeConfig();\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.put('/api/agents/rules/enabled', async (c) => {\n const b = await c.req.json();\n const fp: Record<string, string> = {};\n if (b.value) fp.value = b.value;\n if (b.pattern) fp.pattern = b.pattern;\n if (b.keyword) fp.keyword = b.keyword;\n if (b.path) fp.path = b.path;\n const rc = updateAgentRuleEnabled(b.agent_id, b.category, fp, b.enabled);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.post('/api/agents/rules', async (c) => {\n const b = await c.req.json();\n const rule: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(b)) {\n if (!['agent_id', 'category'].includes(k) && v !== undefined && v !== null) rule[k] = v;\n }\n const rc = addAgentRule(b.agent_id, b.category, rule);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.delete('/api/agents/rules', async (c) => {\n const b = await c.req.json();\n const fp: Record<string, string> = {};\n if (b.value) fp.value = b.value;\n if (b.pattern) fp.pattern = b.pattern;\n if (b.keyword) fp.keyword = b.keyword;\n if (b.path) fp.path = b.path;\n const rc = deleteAgentRule(b.agent_id, b.category, fp);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n console.put('/api/agents/categories/enabled', async (c) => {\n const b = await c.req.json();\n const rc = updateAgentCategoryEnabled(b.agent_id, b.category, b.enabled);\n return c.json({ agents: getAgentRules(rc) });\n });\n\n // ==================== 配置 / env / reset ====================\n // 契约对齐:Python console/router.py 的 /api/config 直接返回完整 runtime config\n // (顶层含 L1_rules/L2_rules/L3_skills/layers),前端 state.config 读取顶层字段。\n // 之前 TS 返回 {config, config_path} 包装导致前端 L1/L2/L3 标签页全空(数据丢)。\n console.get('/api/config', (c) => {\n const rc = loadRuntimeConfig();\n return c.json(rc);\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(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 // 与 Python 契约一致:返回裸数组(前端按 records.length 读)\n return c.json(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","OpenAI","fs","path","READ_KEYWORDS","WRITE_KEYWORDS","readFileSync","readdirSync","existsSync","fileURLToPath","__filename","__dirname","readFileSync","existsSync","readdirSync","join","fileURLToPath","dirname","__dirname","readFileSync","existsSync","resolve","dirname","fileURLToPath","hasRuntimeConfig","loadRuntimeConfig","getEnabledAgentExtensions","__filename","__dirname","path","readFileSync","existsSync","resolve","dirname","fileURLToPath","__filename","__dirname","readFileSync","resolve","join","readFileSync","existsSync","resolve","join","dirname","homedir","path","scanScriptForKeywords","SUSPICIOUS_PATTERNS","assessKeywordCombinationRisk","KEYWORD_COMBINATION_RISKS","SINGLE_KEYWORD_RISKS","LEVEL_ORDER","extractScriptPath","SCRIPT_EXEC_PATTERNS","readScriptContent","node","analyzeScriptContent","parts","readFileSync","writeFileSync","existsSync","mkdirSync","unlinkSync","recordTokenUsage","resolve","main","analyzeScriptContent","getDisabledL2RulesWithSkipL3","getLLMFailMode","path","fs","path","fileURLToPath","join","dirname","i","fs","path","resolve","fs","path","Hono","require","fs","readFileSync","existsSync","join","dirname","fileURLToPath","__dirname","console","Hono","resolve","fileURLToPath","fs","path","runAnalysis","__filename","__dirname","version","resolve"]}