@kenhkl/agent-moss 0.16.12 → 0.16.14

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.
@@ -0,0 +1,6 @@
1
+ {
2
+ "_comment": "规则包清单。schema_version 是**契约**:引擎启动时按自己认识的版本校验,不匹配直接报错(不会'读不懂就当空')。结构有破坏性变更时才 +1;新增文件/新增可选键不用动。",
3
+ "schema_version": 1,
4
+ "name": "agent-moss-rules",
5
+ "description": "AgentMoss 内置规则包:L1/L2/L3 规则、平台特征、脚本与形式化引擎识别名单。契约与校验见 agent_moss/rules_contract.py。"
6
+ }
@@ -0,0 +1,389 @@
1
+ {
2
+ "_comment": [
3
+ "平台行为特征(Platform Traits)—— 双端共用的单一事实源。",
4
+ "Python: agent_moss/profiles/*.py ← rules_loader.load_platform_traits()",
5
+ "TS: ts/src/engine/platform-traits.ts ← rules-loader.loadPlatformTraits()",
6
+ "",
7
+ "这些不是『检测规则』而是『放行/豁免的边界』,直接决定判定的宽严,改动务必谨慎:",
8
+ " fully_safe_commands 首段命令命中 → 跳过 L2 + L3",
9
+ " readonly_sensitive_commands 首段命令命中 → 跳 L3,保留 L2(L1 敏感路径照常)",
10
+ " read_only_commands 命令词命中 → 重定向 > 视为输出而非写文件",
11
+ " write_command_res 命令词命中 → 视为写/删意图(词边界正则)",
12
+ " write_keywords / read_keywords 意图关键词(子串匹配,不加词边界)",
13
+ " safe_action_types action_type 命中 → 跳过 L2 + L3",
14
+ " readonly_sensitive_action_types action_type 命中 → 跳 L3,保留 L2",
15
+ "",
16
+ "macos / harmony 继承 linux(同为类 Unix 命令集),只写 inherits 即可。",
17
+ "列表类字段保持顺序(与源码一致);集合类字段(read_only_commands / safe_action_types /",
18
+ "readonly_sensitive_action_types)已按字典序排列 —— 仅做成员判断,顺序无语义。",
19
+ "改动后自查:python3 -m pytest tests/test_platform_traits.py"
20
+ ],
21
+ "_schema": 1,
22
+ "linux": {
23
+ "write_keywords": [
24
+ "write",
25
+ "写入",
26
+ "save",
27
+ "保存",
28
+ "modify",
29
+ "修改",
30
+ "update",
31
+ "更新",
32
+ "delete",
33
+ "删除",
34
+ "remove",
35
+ "移除",
36
+ "create",
37
+ "创建",
38
+ "append",
39
+ "追加",
40
+ "truncate",
41
+ "截断",
42
+ "overwrite",
43
+ "覆盖",
44
+ "replace",
45
+ "替换",
46
+ "edit"
47
+ ],
48
+ "read_keywords": [
49
+ "read",
50
+ "读取",
51
+ "cat",
52
+ "head",
53
+ "tail",
54
+ "less",
55
+ "more",
56
+ "view",
57
+ "查看",
58
+ "open",
59
+ "打开",
60
+ "load",
61
+ "加载",
62
+ "grep",
63
+ "search",
64
+ "搜索",
65
+ "find",
66
+ "查找"
67
+ ],
68
+ "write_command_res": [
69
+ "\\brm\\b",
70
+ "\\bunlink\\b",
71
+ "\\brmdir\\b",
72
+ "\\bshred\\b",
73
+ "\\bcp\\b",
74
+ "\\bmv\\b",
75
+ "\\binstall\\b",
76
+ "\\btee\\b",
77
+ "\\bdd\\b",
78
+ "\\bmkfs\\b",
79
+ "\\b(fdisk|parted|cfdisk|sfdisk)\\b",
80
+ "\\bchmod\\b",
81
+ "\\bchown\\b",
82
+ "\\btruncate\\b"
83
+ ],
84
+ "read_only_commands": [
85
+ "arch",
86
+ "arp",
87
+ "awk",
88
+ "blockdev",
89
+ "cat",
90
+ "cut",
91
+ "df",
92
+ "dir",
93
+ "dmesg",
94
+ "dmidecode",
95
+ "du",
96
+ "echo",
97
+ "ethtool",
98
+ "fdisk",
99
+ "file",
100
+ "find",
101
+ "free",
102
+ "getconf",
103
+ "getent",
104
+ "grep",
105
+ "head",
106
+ "hexdump",
107
+ "hostnamectl",
108
+ "hwinfo",
109
+ "id",
110
+ "ifconfig",
111
+ "inxi",
112
+ "iostat",
113
+ "ip",
114
+ "journalctl",
115
+ "last",
116
+ "less",
117
+ "localectl",
118
+ "ls",
119
+ "lsblk",
120
+ "lscpu",
121
+ "lsmem",
122
+ "lsmod",
123
+ "lsns",
124
+ "lsof",
125
+ "lspci",
126
+ "lsusb",
127
+ "modinfo",
128
+ "more",
129
+ "mpstat",
130
+ "netstat",
131
+ "nl",
132
+ "nmcli",
133
+ "nproc",
134
+ "od",
135
+ "parted",
136
+ "pgrep",
137
+ "pidof",
138
+ "printf",
139
+ "ps",
140
+ "rev",
141
+ "route",
142
+ "sed",
143
+ "smartctl",
144
+ "sort",
145
+ "ss",
146
+ "stat",
147
+ "strings",
148
+ "sysctl",
149
+ "systemctl",
150
+ "tac",
151
+ "tail",
152
+ "timedatectl",
153
+ "top",
154
+ "tr",
155
+ "tree",
156
+ "udevadm",
157
+ "uname",
158
+ "uniq",
159
+ "uptime",
160
+ "vmstat",
161
+ "w",
162
+ "wc",
163
+ "who",
164
+ "whoami",
165
+ "xxd"
166
+ ],
167
+ "fully_safe_commands": [
168
+ "^ls(?:\\s|$)",
169
+ "^dir(?:\\s|$)",
170
+ "^pwd(?:\\s|$)",
171
+ "^which\\s+",
172
+ "^whereis\\s+",
173
+ "^realpath\\s+",
174
+ "^basename\\s+",
175
+ "^dirname\\s+",
176
+ "^file\\s+",
177
+ "^stat\\s+",
178
+ "^du(?:\\s|$)",
179
+ "^echo\\s+",
180
+ "^printf\\s+",
181
+ "^type\\s+",
182
+ "^command\\s+",
183
+ "^whoami(?:\\s|$)",
184
+ "^id(?:\\s|$)",
185
+ "^hostname(?:\\s|$)",
186
+ "^uname(?:\\s|$)",
187
+ "^date(?:\\s|$)",
188
+ "^env(?:\\s|$)",
189
+ "^printenv(?:\\s|$)",
190
+ "^tty(?:\\s|$)",
191
+ "^arch(?:\\s|$)",
192
+ "^uptime(?:\\s|$)",
193
+ "^groups(?:\\s|$)",
194
+ "^logname(?:\\s|$)",
195
+ "^df(?:\\s|$)",
196
+ "^free(?:\\s|$)",
197
+ "^vmstat(?:\\s|$)",
198
+ "^nproc(?:\\s|$)",
199
+ "^lscpu(?:\\s|$)",
200
+ "^lsblk(?:\\s|$)",
201
+ "^lspci(?:\\s|$)",
202
+ "^lsusb(?:\\s|$)",
203
+ "^lsmod(?:\\s|$)"
204
+ ],
205
+ "readonly_sensitive_commands": [
206
+ "^cat\\s+\\S",
207
+ "^head(?:\\s|$)",
208
+ "^tail(?:\\s|$)",
209
+ "^less(?:\\s|$)",
210
+ "^more(?:\\s|$)",
211
+ "^wc(?:\\s|$)",
212
+ "^grep(?:\\s|$)",
213
+ "^find\\s+",
214
+ "^ag(?:\\s|$)",
215
+ "^rg(?:\\s|$)",
216
+ "^awk\\s+",
217
+ "^(?!.*(?:\\s|['\\\"])-[a-zA-Z]*i[a-zA-Z]*\\b)(?!.*(?:\\s|['\\\"])--in-place)sed\\s+",
218
+ "^cut\\s+",
219
+ "^sort(?:\\s|$)",
220
+ "^uniq(?:\\s|$)",
221
+ "^ps(?:\\s|$)",
222
+ "^ss(?:\\s|$)",
223
+ "^netstat(?:\\s|$)",
224
+ "^lsof(?:\\s|$)",
225
+ "^systemctl\\s+(?:status|is-active|is-enabled|is-failed|list-units|list-unit-files|list-dependencies|show|cat)\\b",
226
+ "^service\\s+\\S+\\s+status\\b",
227
+ "^journalctl\\b(?!.*--(?:vacuum-size|vacuum-time|vacuum-files|rotate|flush|sync)\\b)"
228
+ ],
229
+ "safe_action_types": [
230
+ "ask_user_question",
231
+ "count_text_length",
232
+ "filemgr-globfiles",
233
+ "glob",
234
+ "list_dir",
235
+ "ls"
236
+ ],
237
+ "readonly_sensitive_action_types": [
238
+ "file_read",
239
+ "filemgr-grepfiles",
240
+ "filemgr-readfile",
241
+ "grep",
242
+ "head",
243
+ "read",
244
+ "read_file",
245
+ "tail"
246
+ ]
247
+ },
248
+ "windows": {
249
+ "write_keywords": [
250
+ "write",
251
+ "写入",
252
+ "save",
253
+ "保存",
254
+ "modify",
255
+ "修改",
256
+ "update",
257
+ "更新",
258
+ "delete",
259
+ "删除",
260
+ "remove",
261
+ "移除",
262
+ "create",
263
+ "创建",
264
+ "append",
265
+ "追加",
266
+ "overwrite",
267
+ "覆盖",
268
+ "replace",
269
+ "替换",
270
+ "set",
271
+ "设置"
272
+ ],
273
+ "read_keywords": [
274
+ "read",
275
+ "读取",
276
+ "type",
277
+ "findstr",
278
+ "dir",
279
+ "view",
280
+ "查看",
281
+ "open",
282
+ "打开",
283
+ "load",
284
+ "加载",
285
+ "search",
286
+ "搜索",
287
+ "find",
288
+ "查找",
289
+ "get",
290
+ "获取"
291
+ ],
292
+ "write_command_res": [
293
+ "\\b(del|erase)\\b",
294
+ "\\brmdir\\b",
295
+ "\\b(rd)\\b",
296
+ "\\bcopy\\b",
297
+ "\\b(xcopy|robocopy)\\b",
298
+ "\\b(move|movefile)\\b",
299
+ "\\breplace\\b",
300
+ "\\bicacls\\b",
301
+ "\\battrib\\b",
302
+ "\\breg(?:\\.exe)?\\s+(?:add|delete|copy|save|restore|import|load|unload)\\b",
303
+ "\\bformat\\b",
304
+ "\\bdiskpart\\b",
305
+ "\\bmkdir\\b",
306
+ "\\bmd\\b",
307
+ "\\bsetx\\b",
308
+ "\\bwmic\\b"
309
+ ],
310
+ "read_only_commands": [
311
+ "cls",
312
+ "cmd",
313
+ "comp",
314
+ "dir",
315
+ "diskpart",
316
+ "driverquery",
317
+ "echo",
318
+ "fc",
319
+ "find",
320
+ "findstr",
321
+ "getmac",
322
+ "help",
323
+ "hostname",
324
+ "ipconfig",
325
+ "more",
326
+ "netstat",
327
+ "powershell",
328
+ "query",
329
+ "reg",
330
+ "sort",
331
+ "systeminfo",
332
+ "tasklist",
333
+ "tree",
334
+ "type",
335
+ "ver",
336
+ "w32tm",
337
+ "where",
338
+ "whoami",
339
+ "wmic"
340
+ ],
341
+ "fully_safe_commands": [
342
+ "^dir(?:\\s|$)",
343
+ "^where\\s+",
344
+ "^echo\\s+",
345
+ "^cd(?:\\s|$)",
346
+ "^tree(?:\\s|$)",
347
+ "^help(?:\\s|$)",
348
+ "^cls(?:\\s|$)",
349
+ "^ver(?:\\s|$)",
350
+ "^whoami(?:\\s|$)",
351
+ "^hostname(?:\\s|$)",
352
+ "^systeminfo(?:\\s|$)",
353
+ "^tasklist(?:\\s|$)",
354
+ "^getmac(?:\\s|$)",
355
+ "^driverquery(?:\\s|$)",
356
+ "^netstat(?:\\s|$)"
357
+ ],
358
+ "readonly_sensitive_commands": [
359
+ "^type\\s+",
360
+ "^findstr\\s+",
361
+ "^sc\\s+query\\b",
362
+ "^reg\\s+query\\b"
363
+ ],
364
+ "safe_action_types": [
365
+ "ask_user_question",
366
+ "count_text_length",
367
+ "filemgr-globfiles",
368
+ "glob",
369
+ "list_dir",
370
+ "ls"
371
+ ],
372
+ "readonly_sensitive_action_types": [
373
+ "file_read",
374
+ "filemgr-grepfiles",
375
+ "filemgr-readfile",
376
+ "grep",
377
+ "head",
378
+ "read",
379
+ "read_file",
380
+ "tail"
381
+ ]
382
+ },
383
+ "macos": {
384
+ "inherits": "linux"
385
+ },
386
+ "harmony": {
387
+ "inherits": "linux"
388
+ }
389
+ }
@@ -0,0 +1,311 @@
1
+ {
2
+ "_comment": "脚本内容分析的高风险词表(Python script_content_analyzer/script_analyzer ↔ TS script-content-analyzer/script-analyzer 单一事实源)。suspicious_patterns 与 script_exec_patterns 的 flags 是语义标志(i/s/m);keyword_combination_risks 的 group1/group2 里以 $ 开头的字符串是对 keyword_sets 的引用。script_exec_patterns 分两份是**历史原因**:chain 供递归追踪(识别解释器 + 任意后缀),legacy 只认 .sh(供 L3 提示词用),两者不可互相替换。",
3
+ "keyword_sets": {
4
+ "network_post": [
5
+ "curl POST",
6
+ "curl --data",
7
+ "curl -d",
8
+ "wget --post-data",
9
+ "wget --post-file"
10
+ ]
11
+ },
12
+ "suspicious_patterns": [
13
+ {
14
+ "name": "curl POST",
15
+ "pattern": "curl\\s+(.*\\s)?-X\\s+POST",
16
+ "flags": "i"
17
+ },
18
+ {
19
+ "name": "curl --data",
20
+ "pattern": "curl\\s+(.*\\s)?--data",
21
+ "flags": "i"
22
+ },
23
+ {
24
+ "name": "curl -d",
25
+ "pattern": "curl\\s+(.*\\s)?-d\\s",
26
+ "flags": "i"
27
+ },
28
+ {
29
+ "name": "wget --post-data",
30
+ "pattern": "wget\\s+(.*\\s)?--post-data",
31
+ "flags": "i"
32
+ },
33
+ {
34
+ "name": "wget --post-file",
35
+ "pattern": "wget\\s+(.*\\s)?--post-file",
36
+ "flags": "i"
37
+ },
38
+ {
39
+ "name": "nc -e",
40
+ "pattern": "\\bnc\\s+.*-e\\b",
41
+ "flags": ""
42
+ },
43
+ {
44
+ "name": "ncat -e",
45
+ "pattern": "\\bncat\\s+.*-e\\b",
46
+ "flags": ""
47
+ },
48
+ {
49
+ "name": "/dev/tcp",
50
+ "pattern": "/dev/tcp/",
51
+ "flags": ""
52
+ },
53
+ {
54
+ "name": "/dev/udp",
55
+ "pattern": "/dev/udp/",
56
+ "flags": ""
57
+ },
58
+ {
59
+ "name": "$(base64",
60
+ "pattern": "\\$\\(\\s*base64",
61
+ "flags": ""
62
+ },
63
+ {
64
+ "name": "`base64",
65
+ "pattern": "`\\s*base64",
66
+ "flags": ""
67
+ },
68
+ {
69
+ "name": "base64 decode pipe",
70
+ "pattern": "base64\\s+(-d|--decode)\\s*\\|",
71
+ "flags": ""
72
+ },
73
+ {
74
+ "name": "/etc/shadow",
75
+ "pattern": "/etc/shadow",
76
+ "flags": ""
77
+ },
78
+ {
79
+ "name": "id_rsa",
80
+ "pattern": "\\bid_rsa\\b",
81
+ "flags": ""
82
+ },
83
+ {
84
+ "name": "id_ed25519",
85
+ "pattern": "\\bid_ed25519\\b",
86
+ "flags": ""
87
+ },
88
+ {
89
+ "name": "crontab install",
90
+ "pattern": "crontab\\s+-",
91
+ "flags": ""
92
+ },
93
+ {
94
+ "name": "authorized_keys",
95
+ "pattern": "authorized_keys",
96
+ "flags": ""
97
+ },
98
+ {
99
+ "name": "ssh no host key check",
100
+ "pattern": "ssh\\s+.*StrictHostKeyChecking\\s*=\\s*no",
101
+ "flags": ""
102
+ }
103
+ ],
104
+ "keyword_combination_risks": [
105
+ {
106
+ "group1": "$network_post",
107
+ "group2": [
108
+ "$(base64",
109
+ "`base64",
110
+ "base64 decode pipe"
111
+ ],
112
+ "level": "critical",
113
+ "reason": "检测到网络数据发送 + Base64编码组合,构成 Critical 级别数据外传风险。攻击者可能将敏感数据编码后外传。"
114
+ },
115
+ {
116
+ "group1": "$network_post",
117
+ "group2": [
118
+ "/etc/shadow",
119
+ "id_ed25519",
120
+ "id_rsa"
121
+ ],
122
+ "level": "critical",
123
+ "reason": "检测到网络数据发送 + 敏感文件访问组合,构成 Critical 级别凭证外传风险。"
124
+ },
125
+ {
126
+ "group1": [
127
+ "/dev/tcp",
128
+ "/dev/udp",
129
+ "nc -e",
130
+ "ncat -e"
131
+ ],
132
+ "group2": [],
133
+ "level": "high",
134
+ "reason": "检测到反弹 Shell 特征,攻击者可能建立远程控制通道。"
135
+ },
136
+ {
137
+ "group1": [
138
+ "authorized_keys",
139
+ "crontab install",
140
+ "ssh no host key check"
141
+ ],
142
+ "group2": [],
143
+ "level": "high",
144
+ "reason": "检测到持久化后门特征,攻击者可能在系统中植入后门。"
145
+ }
146
+ ],
147
+ "single_keyword_risks": {
148
+ "curl POST": {
149
+ "level": "high",
150
+ "reason": "检测到 curl POST 请求,可能向外部服务器发送数据。"
151
+ },
152
+ "curl --data": {
153
+ "level": "high",
154
+ "reason": "检测到 curl --data 参数,可能向外部服务器发送数据。"
155
+ },
156
+ "curl -d": {
157
+ "level": "high",
158
+ "reason": "检测到 curl -d 参数,可能向外部服务器发送数据。"
159
+ },
160
+ "wget --post-data": {
161
+ "level": "high",
162
+ "reason": "检测到 wget POST 请求,可能向外部服务器发送数据。"
163
+ },
164
+ "wget --post-file": {
165
+ "level": "high",
166
+ "reason": "检测到 wget 文件上传,可能向外部服务器发送文件。"
167
+ },
168
+ "nc -e": {
169
+ "level": "critical",
170
+ "reason": "检测到 nc -e 反弹 Shell 特征。"
171
+ },
172
+ "ncat -e": {
173
+ "level": "critical",
174
+ "reason": "检测到 ncat -e 反弹 Shell 特征。"
175
+ },
176
+ "/dev/tcp": {
177
+ "level": "critical",
178
+ "reason": "检测到 /dev/tcp 反弹 Shell 特征。"
179
+ },
180
+ "/dev/udp": {
181
+ "level": "critical",
182
+ "reason": "检测到 /dev/udp 反弹 Shell 特征。"
183
+ },
184
+ "$(base64": {
185
+ "level": "high",
186
+ "reason": "检测到 Base64 编码执行,可能是混淆逃逸。"
187
+ },
188
+ "`base64": {
189
+ "level": "high",
190
+ "reason": "检测到 Base64 编码执行,可能是混淆逃逸。"
191
+ },
192
+ "base64 decode pipe": {
193
+ "level": "high",
194
+ "reason": "检测到 Base64 解码后管道执行,可能是混淆逃逸。"
195
+ },
196
+ "/etc/shadow": {
197
+ "level": "critical",
198
+ "reason": "检测到访问系统密码文件。"
199
+ },
200
+ "id_rsa": {
201
+ "level": "critical",
202
+ "reason": "检测到访问 SSH 私钥。"
203
+ },
204
+ "id_ed25519": {
205
+ "level": "critical",
206
+ "reason": "检测到访问 SSH 私钥。"
207
+ },
208
+ "crontab install": {
209
+ "level": "high",
210
+ "reason": "检测到修改定时任务,可能是持久化后门。"
211
+ },
212
+ "authorized_keys": {
213
+ "level": "high",
214
+ "reason": "检测到修改 SSH 授权密钥,可能是持久化后门。"
215
+ },
216
+ "ssh no host key check": {
217
+ "level": "high",
218
+ "reason": "检测到 SSH 跳过主机密钥验证,可能是横向移动。"
219
+ }
220
+ },
221
+ "env_exfil_patterns": [
222
+ "$env",
223
+ "$(env)",
224
+ "$USER",
225
+ "$(hostname)",
226
+ "$(pwd)",
227
+ "$HOME"
228
+ ],
229
+ "script_exec_patterns": {
230
+ "chain": [
231
+ {
232
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*bash\\s+(\\S+)",
233
+ "flags": "i"
234
+ },
235
+ {
236
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*/bin/bash\\s+(\\S+)",
237
+ "flags": "i"
238
+ },
239
+ {
240
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*sh\\s+(\\S+)",
241
+ "flags": "i"
242
+ },
243
+ {
244
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*zsh\\s+(\\S+)",
245
+ "flags": "i"
246
+ },
247
+ {
248
+ "pattern": "\\./(\\S+)",
249
+ "flags": "i"
250
+ },
251
+ {
252
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*source\\s+(\\S+)",
253
+ "flags": "i"
254
+ },
255
+ {
256
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*\\.\\s+(\\S+)",
257
+ "flags": "i"
258
+ },
259
+ {
260
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*python3?\\s+(\\S+\\.py)",
261
+ "flags": "i"
262
+ },
263
+ {
264
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*node\\s+(\\S+\\.js)",
265
+ "flags": "i"
266
+ },
267
+ {
268
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*ruby\\s+(\\S+\\.rb)",
269
+ "flags": "i"
270
+ },
271
+ {
272
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*perl\\s+(\\S+\\.pl)",
273
+ "flags": "i"
274
+ },
275
+ {
276
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*php\\s+(\\S+\\.php)",
277
+ "flags": "i"
278
+ },
279
+ {
280
+ "pattern": "(?:^|\\s|&&|\\|\\|)\\s*lua\\s+(\\S+\\.lua)",
281
+ "flags": "i"
282
+ }
283
+ ],
284
+ "legacy": [
285
+ {
286
+ "pattern": "bash\\s+(\\S+\\.sh)",
287
+ "flags": ""
288
+ },
289
+ {
290
+ "pattern": "sh\\s+(\\S+\\.sh)",
291
+ "flags": ""
292
+ },
293
+ {
294
+ "pattern": "\\./(\\S+\\.sh)",
295
+ "flags": ""
296
+ },
297
+ {
298
+ "pattern": "source\\s+(\\S+\\.sh)",
299
+ "flags": ""
300
+ },
301
+ {
302
+ "pattern": "\\.\\s+(\\S+\\.sh)",
303
+ "flags": ""
304
+ },
305
+ {
306
+ "pattern": "zsh\\s+(\\S+\\.sh)",
307
+ "flags": ""
308
+ }
309
+ ]
310
+ }
311
+ }