@kenhkl/agent-moss 0.7.5 → 0.7.8

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 CHANGED
@@ -154,7 +154,7 @@ function isHeuristicEnabled() {
154
154
  function isLogicRulesEnabled() {
155
155
  return process.env.AGENT_MOSS_DISABLE_LOGIC_RULES !== "1";
156
156
  }
157
- var llmConfig, timeoutConfig, retryConfig, customRules, PROVIDER_HEADERS;
157
+ var timeoutConfig, retryConfig, llmConfig, customRules, PROVIDER_HEADERS;
158
158
  var init_config = __esm({
159
159
  "src/config.ts"() {
160
160
  "use strict";
@@ -596,7 +596,7 @@ function checkSensitivePath(command, cwd) {
596
596
  }
597
597
  for (const cp of CREDENTIAL_PATHS) {
598
598
  const escaped = cp.path.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
599
- const re = cp.path.startsWith(".") ? new RegExp(`(?:^|[\\s/\\\\])${escaped}\\b`) : new RegExp(`\\b${escaped}\\b`);
599
+ const re = cp.path.startsWith(".") ? new RegExp(`(?:^|[\\s/\\\\'"])${escaped}\\b`) : new RegExp(`\\b${escaped}\\b`);
600
600
  if (re.test(command)) {
601
601
  return {
602
602
  allowed: false,
@@ -605,7 +605,8 @@ function checkSensitivePath(command, cwd) {
605
605
  riskType: "sensitive_path_access",
606
606
  confidence: 90,
607
607
  source: "logic_rule",
608
- violatedLayers: ["2"]
608
+ violatedLayers: ["2"],
609
+ isCredential: true
609
610
  };
610
611
  }
611
612
  }
@@ -740,6 +741,170 @@ var init_logic_rules = __esm({
740
741
  }
741
742
  });
742
743
 
744
+ // src/engine/inline-analyzer.ts
745
+ function isLiteralTextCommand(command) {
746
+ ECHO_CMD_RE.lastIndex = 0;
747
+ return ECHO_CMD_RE.test(command);
748
+ }
749
+ function extractInlineCode(command) {
750
+ const parts = [];
751
+ let m;
752
+ INLINE_CODE_RE.lastIndex = 0;
753
+ while ((m = INLINE_CODE_RE.exec(command)) !== null) {
754
+ const code = m[1] ?? m[2];
755
+ if (code) parts.push(code);
756
+ }
757
+ ECHO_STRING_RE.lastIndex = 0;
758
+ while ((m = ECHO_STRING_RE.exec(command)) !== null) {
759
+ const code = m[1] ?? m[2];
760
+ if (code) parts.push(code);
761
+ }
762
+ return parts.join("\n");
763
+ }
764
+ function hasWriteExecChain(command) {
765
+ return WRITE_EXEC_CHAIN_PATTERNS.some((p) => {
766
+ p.lastIndex = 0;
767
+ return p.test(command);
768
+ });
769
+ }
770
+ function hasReadWriteKeyword(code) {
771
+ const lower = code.toLowerCase();
772
+ return READ_WRITE_KEYWORDS.some((kw) => lower.includes(kw));
773
+ }
774
+ function analyzeInlineScript(command) {
775
+ const code = extractInlineCode(command);
776
+ if (!code) {
777
+ return { actionable: false, allowed: true, reason: "", riskLevel: "low", riskType: "" };
778
+ }
779
+ if (hasWriteExecChain(command)) {
780
+ return {
781
+ actionable: true,
782
+ allowed: false,
783
+ reason: "\u5185\u8054\u811A\u672C\u542B\u5199\u5165\u6587\u4EF6\u540E\u6267\u884C\u7684\u6A21\u5F0F\uFF0C\u7591\u4F3C\u7ED5\u8FC7\u654F\u611F\u8DEF\u5F84\u68C0\u6D4B",
784
+ riskLevel: "critical",
785
+ riskType: "script_execution"
786
+ };
787
+ }
788
+ const redirMatch = command.match(REDIRECT_TO_SENSITIVE_RE);
789
+ if (redirMatch) {
790
+ return {
791
+ actionable: true,
792
+ allowed: false,
793
+ reason: `\u91CD\u5B9A\u5411\u5199\u5165\u654F\u611F\u8DEF\u5F84: ${redirMatch[1]}`,
794
+ riskLevel: "critical",
795
+ riskType: "file_access"
796
+ };
797
+ }
798
+ const isEchoOrPrintf = isLiteralTextCommand(command);
799
+ if (!isEchoOrPrintf && hasReadWriteKeyword(code)) {
800
+ return {
801
+ actionable: true,
802
+ allowed: false,
803
+ reason: "\u5185\u8054\u811A\u672C\u542B\u654F\u611F\u8DEF\u5F84\u4E14\u542B\u6587\u4EF6\u8BFB\u5199/\u547D\u4EE4\u6267\u884C\u8C03\u7528\uFF0C\u5224\u4E3A\u771F\u5B9E\u8BBF\u95EE",
804
+ riskLevel: "critical",
805
+ riskType: "file_access"
806
+ };
807
+ }
808
+ return {
809
+ actionable: true,
810
+ allowed: true,
811
+ reason: "\u654F\u611F\u8DEF\u5F84\u4EC5\u4F5C\u4E3A\u6587\u672C\u5B57\u9762\u91CF\u51FA\u73B0\uFF0C\u672A\u4F34\u968F\u8BFB\u5199\u64CD\u4F5C",
812
+ riskLevel: "low",
813
+ riskType: "file_access"
814
+ };
815
+ }
816
+ var INLINE_CODE_RE, ECHO_STRING_RE, ECHO_CMD_RE, READ_WRITE_KEYWORDS, WRITE_EXEC_CHAIN_PATTERNS, SENSITIVE_PATH_FRAGMENTS, REDIRECT_TO_SENSITIVE_RE;
817
+ var init_inline_analyzer = __esm({
818
+ "src/engine/inline-analyzer.ts"() {
819
+ "use strict";
820
+ init_esm_shims();
821
+ INLINE_CODE_RE = /(?:python|python3|perl|perl5|ruby|jruby|mruby|node|php|lua)\s+(?:-[a-zA-Z]*[cera][a-zA-Z]*\s+)"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'/gi;
822
+ ECHO_STRING_RE = /\b(?:echo|printf)\s+"([^"\\]*(?:\\.[^"\\]*)*)"|\b(?:echo|printf)\s+'([^'\\]*(?:\\.[^'\\]*)*)'/gi;
823
+ ECHO_CMD_RE = /(?:^|\s|;|&&|\|\|)(?:echo|printf)\s/gi;
824
+ READ_WRITE_KEYWORDS = [
825
+ // 函数调用形态(关键词后跟 '(')
826
+ "open(",
827
+ "read(",
828
+ "write(",
829
+ "fopen(",
830
+ "system(",
831
+ "exec(",
832
+ "eval(",
833
+ "popen(",
834
+ "load(",
835
+ "dump(",
836
+ // 文件读写(组合形态)
837
+ "readline",
838
+ "readlines",
839
+ "writelines",
840
+ "getpass",
841
+ "pickle.load",
842
+ "yaml.load",
843
+ "json.load",
844
+ "json.read",
845
+ "configparser",
846
+ "fread",
847
+ "fwrite",
848
+ "fgets",
849
+ // 子进程执行(组合形态)
850
+ "os.system",
851
+ "os.popen",
852
+ "subprocess",
853
+ "os.exec",
854
+ "os.spawn",
855
+ "import os",
856
+ "import subprocess",
857
+ "shell=true",
858
+ "check_output",
859
+ "check_call",
860
+ "run(",
861
+ // 绕过变体检测
862
+ "getattr(",
863
+ "__builtins__",
864
+ "globals(",
865
+ "locals(",
866
+ // PHP
867
+ "file_get_contents",
868
+ "file_put_contents",
869
+ "passthru",
870
+ "shell_exec",
871
+ "proc_open",
872
+ // Perl-Ruby
873
+ "<stdin>",
874
+ "open my"
875
+ ];
876
+ WRITE_EXEC_CHAIN_PATTERNS = [
877
+ // echo/cat/printf "..." > file && bash/sh/python file
878
+ /(?:echo|cat|printf)\b.*?>\s*\S+.*(?:&&|;|\|)\s*(?:bash|sh|zsh|python\d?|perl|ruby|node|php)\s/gis,
879
+ // ... | bash / | sh / | python(管道喂解释器执行)
880
+ /\|\s*(?:bash|sh|zsh|python\d?|perl|ruby|node|php)\b/gi,
881
+ // eval "$(cat ...)" / eval "$(echo ...)"
882
+ /eval\s+"\$\(/gi,
883
+ // xargs bash / xargs sh
884
+ /\|\s*xargs\s+(?:bash|sh|zsh)/gi
885
+ ];
886
+ SENSITIVE_PATH_FRAGMENTS = [
887
+ "/etc/shadow",
888
+ "/etc/gshadow",
889
+ "/etc/passwd",
890
+ "/etc/sudoers",
891
+ "/etc/hosts",
892
+ "/etc/crontab",
893
+ "/etc/systemd/",
894
+ "/etc/ssh/sshd_config",
895
+ "/boot/",
896
+ "/proc/sys/",
897
+ "/sys/",
898
+ "/dev/mem",
899
+ "/dev/kmsg",
900
+ ".ssh/id_rsa",
901
+ ".ssh/id_ed25519",
902
+ ".ssh/authorized_keys"
903
+ ];
904
+ REDIRECT_TO_SENSITIVE_RE = new RegExp(`>{1,2}\\s*(${SENSITIVE_PATH_FRAGMENTS.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")})`, "i");
905
+ }
906
+ });
907
+
743
908
  // src/engine/skill-loader.ts
744
909
  import { readFileSync, readdirSync, existsSync as existsSync2 } from "fs";
745
910
  import { resolve, dirname } from "path";
@@ -747,16 +912,17 @@ import { fileURLToPath as fileURLToPath2 } from "url";
747
912
  function loadAllSkills() {
748
913
  if (cachedSkills) return cachedSkills;
749
914
  cachedSkills = {};
750
- if (!existsSync2(SKILLS_DIR)) {
751
- console.warn("[AgentMoss] Skills directory not found:", SKILLS_DIR);
915
+ const dir = existsSync2(SKILLS_DIR) ? SKILLS_DIR : SKILLS_DIR_FALLBACK;
916
+ if (!existsSync2(dir)) {
917
+ console.warn("[AgentMoss] Skills directory not found:", SKILLS_DIR, "and fallback:", SKILLS_DIR_FALLBACK);
752
918
  return cachedSkills;
753
919
  }
754
- const files = readdirSync(SKILLS_DIR).filter((f) => f.endsWith(".md"));
920
+ const files = readdirSync(dir).filter((f) => f.endsWith(".md"));
755
921
  for (const f of files) {
756
922
  const name = f.replace(".md", "");
757
- cachedSkills[name] = readFileSync(resolve(SKILLS_DIR, f), "utf-8");
923
+ cachedSkills[name] = readFileSync(resolve(dir, f), "utf-8");
758
924
  }
759
- console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills`);
925
+ console.log(`[AgentMoss] Loaded ${Object.keys(cachedSkills).length} skills from ${dir}`);
760
926
  return cachedSkills;
761
927
  }
762
928
  function matchSkills(actionType, actionDetail, reason, maxSkills = 3) {
@@ -808,14 +974,15 @@ function formatSkillsForPrompt(skills) {
808
974
  ${s.skillContent}`
809
975
  ).join("\n\n---\n\n");
810
976
  }
811
- var __filename2, __dirname2, SKILLS_DIR, SKILL_KEYWORD_MAP, cachedSkills;
977
+ var __filename2, __dirname2, SKILLS_DIR, SKILLS_DIR_FALLBACK, SKILL_KEYWORD_MAP, cachedSkills;
812
978
  var init_skill_loader = __esm({
813
979
  "src/engine/skill-loader.ts"() {
814
980
  "use strict";
815
981
  init_esm_shims();
816
982
  __filename2 = fileURLToPath2(import.meta.url);
817
983
  __dirname2 = dirname(__filename2);
818
- SKILLS_DIR = resolve(__dirname2, "../../agent_moss/skills");
984
+ SKILLS_DIR = resolve(__dirname2, "../skills");
985
+ SKILLS_DIR_FALLBACK = resolve(__dirname2, "../../agent_moss/skills");
819
986
  SKILL_KEYWORD_MAP = {
820
987
  "file_access_guard": ["file", "\u6587\u4EF6", "path", "\u8DEF\u5F84", "read", "write", "cat", "open", "access", "\u8BBF\u95EE", "\u8BFB\u5199", "copy", "cp", "mv", "move"],
821
988
  "script_execution_guard": ["command", "shell", "bash", "exec", "execute", "\u6267\u884C", "\u547D\u4EE4", "script", "\u811A\u672C", "run", "\u8FD0\u884C", "subprocess", "system", "eval", "compile", "\u5B89\u88C5", "install", "pip", "npm"],
@@ -825,7 +992,9 @@ var init_skill_loader = __esm({
825
992
  "general_tool_risk_guard": ["tool", "\u5DE5\u5177", "api", "invoke", "\u8C03\u7528", "function", "\u51FD\u6570"],
826
993
  "lateral_movement_guard": ["ssh", "scp", "ftp", "sftp", "rdp", "vnc", "telnet", "\u5185\u7F51", "\u6A2A\u5411", "tunnel", "\u4EE3\u7406", "proxy", "port", "\u7AEF\u53E3", "scan", "\u626B\u63CF", "ping", "traceroute", "nslookup"],
827
994
  "persistence_backdoor_guard": ["cron", "crontab", "\u5B9A\u65F6", "scheduled", "startup", "\u542F\u52A8\u9879", "service", "\u670D\u52A1", "daemon", "\u5B88\u62A4", "registry", "\u6CE8\u518C\u8868", "backdoor", "\u540E\u95E8", "persist", "\u6301\u4E45\u5316", "authorized_keys", "bashrc", "zshrc", "profile", ".rc", "shell config", "shell \u914D\u7F6E"],
828
- "resource_exhaustion_guard": ["fork", "bomb", "\u70B8\u5F39", "memory", "\u5185\u5B58", "disk", "\u78C1\u76D8", "cpu", "process", "\u8FDB\u7A0B", "dd", "while true", "\u65E0\u9650\u5FAA\u73AF", "\u8017\u5C3D", "exhaust", "\u8D44\u6E90"],
995
+ // 注意:避免裸 'memory'/'内存'/'dd'——会误命中 memory-addMemory(写记忆工具,
996
+ // 'dd' 是 'addMemory' 的子串)等无害操作。用组合词/命令前缀精准匹配攻击场景。
997
+ "resource_exhaustion_guard": ["fork", "bomb", "\u70B8\u5F39", "memory bomb", "oom", "out of memory", "\u5185\u5B58\u6EA2\u51FA", "\u5185\u5B58\u8017\u5C3D", "\u5185\u5B58\u6CC4\u6F0F", "disk", "\u78C1\u76D8", "cpu", "process", "\u8FDB\u7A0B", "dd if=", "/dev/zero", "/dev/null", "yes >", "while true", "\u65E0\u9650\u5FAA\u73AF", "\u8017\u5C3D", "exhaust", "\u8D44\u6E90"],
829
998
  "skill_installation_guard": ["skill", "plugin", "\u63D2\u4EF6", "extension", "\u6269\u5C55", "install skill", "\u5B89\u88C5\u63D2\u4EF6", "\u5B89\u88C5\u6280\u80FD", "marketplace", "\u5546\u5E97"],
830
999
  "supply_chain_guard": ["dependency", "\u4F9D\u8D56", "package", "\u5305", "npm install", "pip install", "requirements", "import", "library", "\u5E93", "registry", "\u4ED3\u5E93", "supply", "\u4F9B\u5E94\u94FE", "typosquatting"],
831
1000
  "intent_deviation_guard": ["rm", "del", "delete", "remove", "\u5220\u9664", "format", "\u683C\u5F0F\u5316", "drop", "truncate", "\u6E05\u7A7A", "wipe", "\u64E6\u9664", "\u91CD\u7F6E", "reset", "sudo", "root", "admin", "\u7BA1\u7406\u5458", "privilege", "\u63D0\u6743"]
@@ -841,28 +1010,30 @@ import { fileURLToPath as fileURLToPath3 } from "url";
841
1010
  function loadTemplates() {
842
1011
  if (cachedTemplates) return cachedTemplates;
843
1012
  cachedTemplates = {};
844
- if (!existsSync3(TEMPLATES_DIR)) {
845
- console.warn("[AgentMoss] Templates directory not found:", TEMPLATES_DIR);
1013
+ const dir = existsSync3(TEMPLATES_DIR) ? TEMPLATES_DIR : TEMPLATES_DIR_FALLBACK;
1014
+ if (!existsSync3(dir)) {
1015
+ console.warn("[AgentMoss] Templates directory not found:", TEMPLATES_DIR, "and fallback:", TEMPLATES_DIR_FALLBACK);
846
1016
  return cachedTemplates;
847
1017
  }
848
1018
  for (const file of TEMPLATE_FILES) {
849
- const filePath = resolve2(TEMPLATES_DIR, file);
1019
+ const filePath = resolve2(dir, file);
850
1020
  if (existsSync3(filePath)) {
851
1021
  const key = file.replace(".txt", "").replace("_template", "");
852
1022
  cachedTemplates[key] = readFileSync2(filePath, "utf-8");
853
1023
  }
854
1024
  }
855
- console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates`);
1025
+ console.log(`[AgentMoss] Loaded ${Object.keys(cachedTemplates).length} templates from ${dir}`);
856
1026
  return cachedTemplates;
857
1027
  }
858
- var __filename3, __dirname3, TEMPLATES_DIR, TEMPLATE_FILES, cachedTemplates;
1028
+ var __filename3, __dirname3, TEMPLATES_DIR, TEMPLATES_DIR_FALLBACK, TEMPLATE_FILES, cachedTemplates;
859
1029
  var init_template_loader = __esm({
860
1030
  "src/engine/template-loader.ts"() {
861
1031
  "use strict";
862
1032
  init_esm_shims();
863
1033
  __filename3 = fileURLToPath3(import.meta.url);
864
1034
  __dirname3 = dirname2(__filename3);
865
- TEMPLATES_DIR = resolve2(__dirname3, "../../agent_moss/templates");
1035
+ TEMPLATES_DIR = resolve2(__dirname3, "../templates");
1036
+ TEMPLATES_DIR_FALLBACK = resolve2(__dirname3, "../../agent_moss/templates");
866
1037
  TEMPLATE_FILES = ["prompt1_template.txt", "prompt2_template.txt", "security_judge_template.txt"];
867
1038
  cachedTemplates = null;
868
1039
  }
@@ -1100,13 +1271,14 @@ async function runLLMAnalysis(input, previous) {
1100
1271
  function buildPrompt(input, previous, matchedSkills, templates, scriptAnalysis) {
1101
1272
  const skillsText = formatSkillsForPrompt(matchedSkills);
1102
1273
  const historyStr = input.actionHistory.map((h, i) => `${i + 1}. ${h.actionType}: ${h.actionDetail}`).join("\n") || "(\u65E0\u5386\u53F2\u64CD\u4F5C)";
1103
- const templateName = previous.heuristic || previous.logic ? "prompt2" : "prompt1";
1104
- const baseTemplate = templates[templateName] || templates["prompt1"] || "";
1105
1274
  const scriptAnalysisText = scriptAnalysis ? formatScriptAnalysisForPrompt(scriptAnalysis) : "";
1106
1275
  const hintsText = formatHints(previous);
1107
- return `${baseTemplate}
1108
-
1109
- ## \u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587
1276
+ const securityJudgeTemplate = templates["security_judge"];
1277
+ if (securityJudgeTemplate) {
1278
+ return securityJudgeTemplate.replaceAll("{prompt_session}", input.promptSession || "\uFF08\u672A\u63D0\u4F9B\uFF09").replaceAll("{action_history}", historyStr).replaceAll("{action_type}", input.aNext.actionType).replaceAll("{action_detail}", input.aNext.actionDetail).replaceAll("{reason}", input.reason || "\u672A\u8BF4\u660E").replaceAll("{skills_text}", skillsText).replaceAll("{hints_text}", hintsText).replaceAll("{script_analysis_text}", scriptAnalysisText).replaceAll("{{", "{").replaceAll("}}", "}");
1279
+ }
1280
+ console.warn("[AgentMoss] security_judge template missing, using sparse fallback prompt");
1281
+ return `## \u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587
1110
1282
  - \u4F1A\u8BDD ID: ${input.sessionId}
1111
1283
  - \u7528\u6237\u4EFB\u52A1: ${input.promptSession || "\u672A\u6307\u5B9A"}
1112
1284
  - \u64CD\u4F5C\u7CFB\u7EDF: ${input.osType}
@@ -1128,8 +1300,7 @@ ${scriptAnalysisText ? `
1128
1300
  ## \u811A\u672C\u5185\u5BB9\u5206\u6790
1129
1301
  ${scriptAnalysisText}` : ""}
1130
1302
 
1131
- \u8BF7\u6839\u636E\u4EE5\u4E0A\u4FE1\u606F\uFF0C\u5BF9\u5373\u5C06\u6267\u884C\u7684\u64CD\u4F5C\u8FDB\u884C\u5B89\u5168\u5224\u65AD\u3002\u4F60\u5FC5\u987B\u8F93\u51FA\u4E25\u683C\u7684 JSON \u683C\u5F0F\uFF0C
1132
- \u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3001\u6CE8\u91CA\u6216 markdown \u6807\u8BB0\u3002
1303
+ \u8BF7\u6839\u636E\u4EE5\u4E0A\u4FE1\u606F\uFF0C\u5BF9\u5373\u5C06\u6267\u884C\u7684\u64CD\u4F5C\u8FDB\u884C\u5B89\u5168\u5224\u65AD\u3002\u524D\u7F6E\u68C0\u6D4B\u4E3A low/medium \u4E14\u6709\u5408\u7406\u6267\u884C\u7406\u7531\u65F6\u5E94\u5F53\u5141\u8BB8\u3002\u4F60\u5FC5\u987B\u8F93\u51FA\u4E25\u683C\u7684 JSON \u683C\u5F0F\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3001\u6CE8\u91CA\u6216 markdown \u6807\u8BB0\u3002
1133
1304
 
1134
1305
  \u8F93\u51FA\u683C\u5F0F:
1135
1306
  {"allowed": true/false, "reason": "\u5224\u65AD\u7406\u7531", "riskLevel": "low|medium|high|critical", "riskType": "\u98CE\u9669\u7C7B\u578B", "confidence": 0-100}`;
@@ -1176,7 +1347,9 @@ async function analyzeWithLLM(prompt, config) {
1176
1347
  temperature: config.temperature || 0.1,
1177
1348
  max_tokens: config.maxTokens || 1024,
1178
1349
  messages: [
1179
- { role: "system", content: "\u4F60\u662F\u4E00\u4E2A AI Agent \u5B89\u5168\u5BA1\u8BA1\u4E13\u5BB6\u3002\u4F60\u7684\u4EFB\u52A1\u662F\u5206\u6790\u5373\u5C06\u6267\u884C\u7684\u547D\u4EE4\u662F\u5426\u5B89\u5168\u3002\u4F60\u5FC5\u987B\u53EA\u8F93\u51FA\u7EAF JSON\uFF0C\u4E0D\u8981\u5305\u542B\u4EFB\u4F55 markdown \u6807\u8BB0\u3001\u4EE3\u7801\u5757\u6216\u5176\u4ED6\u6587\u5B57\u3002" },
1350
+ // security_judge 模板自带角色定义与判断规则,system 仅做输出格式约束,
1351
+ // 避免与模板里的"你是 xiaoO Audit Agent 安全审计员"角色定义冲突(对齐 Python:无独立 system)。
1352
+ { role: "system", content: "\u53EA\u8F93\u51FA\u7EAF JSON\uFF0C\u4E0D\u8981\u5305\u542B markdown \u6807\u8BB0\u3001\u4EE3\u7801\u5757\u6216\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\u3002" },
1180
1353
  { role: "user", content: prompt }
1181
1354
  ]
1182
1355
  });
@@ -1264,8 +1437,9 @@ function matchesAny(cmd, patterns) {
1264
1437
  async function runAnalysis(input) {
1265
1438
  const heuristicResult = isHeuristicEnabled() ? runHeuristicCheck(input) : null;
1266
1439
  const isInlineScriptCmd = isInlineScriptCommand(input.aNext.actionDetail.toLowerCase());
1440
+ const isLiteralTextCmd = isLiteralTextCommand(input.aNext.actionDetail.toLowerCase());
1267
1441
  if (heuristicResult && !heuristicResult.allowed) {
1268
- const skipInlineFileAccess = isInlineScriptCmd && heuristicResult.riskType === "file_access";
1442
+ const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && heuristicResult.riskType === "file_access";
1269
1443
  if (!skipInlineFileAccess) {
1270
1444
  return heuristicResult;
1271
1445
  }
@@ -1322,8 +1496,33 @@ async function runAnalysis(input) {
1322
1496
  }
1323
1497
  const logicResult = isLogicRulesEnabled() ? runLogicCheck(input) : null;
1324
1498
  if (logicResult && !logicResult.allowed) {
1325
- const isCredentialPath = logicResult.riskType === "sensitive_path_access" && (logicResult.riskLevel === "high" || logicResult.riskLevel === "critical");
1326
- const skipInlineFileAccess = isInlineScriptCmd && logicResult.riskType === "sensitive_path_access";
1499
+ const isCredentialPath = !!logicResult.isCredential;
1500
+ const skipInlineFileAccess = (isInlineScriptCmd || isLiteralTextCmd) && logicResult.riskType === "sensitive_path_access";
1501
+ if (skipInlineFileAccess && !isCredentialPath) {
1502
+ const inlineJudgment = analyzeInlineScript(input.aNext.actionDetail);
1503
+ if (inlineJudgment.actionable) {
1504
+ if (!inlineJudgment.allowed) {
1505
+ return {
1506
+ allowed: false,
1507
+ reason: inlineJudgment.reason,
1508
+ riskLevel: inlineJudgment.riskLevel,
1509
+ riskType: inlineJudgment.riskType,
1510
+ confidence: 90,
1511
+ source: "logic_rule",
1512
+ violatedLayers: ["1.2"]
1513
+ };
1514
+ }
1515
+ return {
1516
+ allowed: true,
1517
+ reason: inlineJudgment.reason,
1518
+ riskLevel: inlineJudgment.riskLevel,
1519
+ riskType: inlineJudgment.riskType,
1520
+ confidence: 90,
1521
+ source: "logic_rule",
1522
+ violatedLayers: []
1523
+ };
1524
+ }
1525
+ }
1327
1526
  if (!skipInlineFileAccess || isCredentialPath) {
1328
1527
  return logicResult;
1329
1528
  }
@@ -1352,6 +1551,7 @@ var init_coordinator = __esm({
1352
1551
  init_esm_shims();
1353
1552
  init_heuristic();
1354
1553
  init_logic_rules();
1554
+ init_inline_analyzer();
1355
1555
  init_llm_analyzer();
1356
1556
  init_config();
1357
1557
  FULLY_SAFE_TOOLS = /* @__PURE__ */ new Set([