@feiyoug/skill-lab 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. package/README.md +20 -21
  2. package/esm/analyzer/astgrep/client.d.ts +20 -8
  3. package/esm/analyzer/astgrep/client.d.ts.map +1 -1
  4. package/esm/analyzer/astgrep/client.js +58 -31
  5. package/esm/analyzer/config/default.d.ts +8 -0
  6. package/esm/analyzer/config/default.d.ts.map +1 -0
  7. package/esm/analyzer/config/default.js +91 -0
  8. package/esm/analyzer/config/helpers.d.ts +8 -0
  9. package/esm/analyzer/config/helpers.d.ts.map +1 -0
  10. package/esm/analyzer/config/helpers.js +72 -0
  11. package/esm/analyzer/config/mod.d.ts +4 -0
  12. package/esm/analyzer/config/mod.d.ts.map +1 -0
  13. package/esm/analyzer/config/mod.js +3 -0
  14. package/esm/analyzer/config/types.d.ts +58 -0
  15. package/esm/analyzer/config/types.d.ts.map +1 -0
  16. package/esm/analyzer/{config.js → config/types.js} +0 -28
  17. package/esm/analyzer/logging.d.ts +3 -0
  18. package/esm/analyzer/logging.d.ts.map +1 -0
  19. package/esm/analyzer/logging.js +6 -0
  20. package/esm/analyzer/mod.d.ts +12 -5
  21. package/esm/analyzer/mod.d.ts.map +1 -1
  22. package/esm/analyzer/mod.js +25 -12
  23. package/esm/analyzer/result.d.ts +35 -0
  24. package/esm/analyzer/result.d.ts.map +1 -0
  25. package/esm/analyzer/result.js +311 -0
  26. package/esm/analyzer/rules/bash/commands/mod.d.ts +1 -0
  27. package/esm/analyzer/rules/bash/commands/mod.d.ts.map +1 -1
  28. package/esm/analyzer/rules/bash/commands/mod.js +3 -0
  29. package/esm/analyzer/rules/bash/commands/pip.d.ts +3 -0
  30. package/esm/analyzer/rules/bash/commands/pip.d.ts.map +1 -0
  31. package/esm/analyzer/rules/bash/commands/pip.js +14 -0
  32. package/esm/analyzer/rules/bash/extractFileRefs.d.ts +1 -1
  33. package/esm/analyzer/rules/bash/extractFileRefs.d.ts.map +1 -1
  34. package/esm/analyzer/rules/bash/extractFileRefs.js +2 -2
  35. package/esm/analyzer/rules/bash/inline-command-classifier.d.ts +1 -1
  36. package/esm/analyzer/rules/bash/inline-command-classifier.d.ts.map +1 -1
  37. package/esm/analyzer/rules/bash/inline-command-classifier.js +4 -4
  38. package/esm/analyzer/rules/javascript/extractFileRefs.d.ts +3 -4
  39. package/esm/analyzer/rules/javascript/extractFileRefs.d.ts.map +1 -1
  40. package/esm/analyzer/rules/javascript/extractFileRefs.js +3 -4
  41. package/esm/analyzer/rules/markdown/extractCodeBlocks.d.ts.map +1 -1
  42. package/esm/analyzer/rules/markdown/extractCodeBlocks.js +6 -3
  43. package/esm/analyzer/rules/markdown/extractFileRefs.d.ts.map +1 -1
  44. package/esm/analyzer/rules/markdown/extractFileRefs.js +2 -0
  45. package/esm/analyzer/rules/python/extractFileRefs.d.ts +1 -1
  46. package/esm/analyzer/rules/python/extractFileRefs.d.ts.map +1 -1
  47. package/esm/analyzer/rules/python/extractFileRefs.js +2 -2
  48. package/esm/analyzer/steps/001-discovery/discover-files.d.ts +4 -0
  49. package/esm/analyzer/steps/001-discovery/discover-files.d.ts.map +1 -1
  50. package/esm/analyzer/steps/001-discovery/discover-files.js +18 -2
  51. package/esm/analyzer/steps/001-discovery/mod.d.ts.map +1 -1
  52. package/esm/analyzer/steps/001-discovery/mod.js +39 -9
  53. package/esm/analyzer/steps/002-permissions/mod.d.ts.map +1 -1
  54. package/esm/analyzer/steps/002-permissions/mod.js +156 -73
  55. package/esm/analyzer/steps/002-permissions/scan-file.d.ts +1 -1
  56. package/esm/analyzer/steps/002-permissions/scan-file.d.ts.map +1 -1
  57. package/esm/analyzer/steps/002-permissions/scan-file.js +40 -5
  58. package/esm/analyzer/steps/002-permissions/seed-frontmatter.js +2 -2
  59. package/esm/analyzer/steps/003-risks/dep-risks.d.ts +3 -0
  60. package/esm/analyzer/steps/003-risks/dep-risks.d.ts.map +1 -0
  61. package/esm/analyzer/steps/003-risks/dep-risks.js +74 -0
  62. package/esm/analyzer/steps/003-risks/helpers.d.ts +1 -0
  63. package/esm/analyzer/steps/003-risks/helpers.d.ts.map +1 -1
  64. package/esm/analyzer/steps/003-risks/helpers.js +1 -0
  65. package/esm/analyzer/steps/003-risks/mod.d.ts +3 -2
  66. package/esm/analyzer/steps/003-risks/mod.d.ts.map +1 -1
  67. package/esm/analyzer/steps/003-risks/mod.js +41 -4
  68. package/esm/analyzer/steps/003-risks/policy.d.ts +7 -0
  69. package/esm/analyzer/steps/003-risks/policy.d.ts.map +1 -0
  70. package/esm/analyzer/steps/003-risks/policy.js +23 -0
  71. package/esm/analyzer/steps/003-risks/rule-mapped.d.ts +2 -2
  72. package/esm/analyzer/steps/003-risks/rule-mapped.d.ts.map +1 -1
  73. package/esm/analyzer/steps/003-risks/rule-mapped.js +83 -2
  74. package/esm/analyzer/steps/003-risks/scoring.d.ts +9 -1
  75. package/esm/analyzer/steps/003-risks/scoring.d.ts.map +1 -1
  76. package/esm/analyzer/steps/003-risks/scoring.js +55 -42
  77. package/esm/analyzer/treesitter/client.d.ts +31 -0
  78. package/esm/analyzer/treesitter/client.d.ts.map +1 -0
  79. package/esm/analyzer/{treesiter → treesitter}/client.js +43 -39
  80. package/esm/analyzer/treesitter/registry.d.ts +73 -0
  81. package/esm/analyzer/treesitter/registry.d.ts.map +1 -0
  82. package/esm/analyzer/treesitter/registry.js +165 -0
  83. package/esm/analyzer/types.d.ts +14 -28
  84. package/esm/analyzer/types.d.ts.map +1 -1
  85. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts +3 -0
  86. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts.map +1 -0
  87. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/deps.js +3 -0
  88. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts +93 -0
  89. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts.map +1 -0
  90. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/mod.js +297 -0
  91. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts +84 -0
  92. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts.map +1 -0
  93. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/multi.js +268 -0
  94. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts +18 -0
  95. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts.map +1 -0
  96. package/esm/deps/jsr.io/@deno-library/progress/1.5.1/time.js +45 -0
  97. package/esm/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts +700 -0
  98. package/esm/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts.map +1 -0
  99. package/esm/deps/jsr.io/@std/fmt/1.0.3/colors.js +903 -0
  100. package/esm/deps/jsr.io/@std/io/0.225.0/types.d.ts +146 -0
  101. package/esm/deps/jsr.io/@std/io/0.225.0/types.d.ts.map +1 -0
  102. package/esm/deps/jsr.io/@std/io/0.225.0/types.js +15 -0
  103. package/esm/deps/jsr.io/@std/io/0.225.0/write_all.d.ts +51 -0
  104. package/esm/deps/jsr.io/@std/io/0.225.0/write_all.d.ts.map +1 -0
  105. package/esm/deps/jsr.io/@std/io/0.225.0/write_all.js +61 -0
  106. package/esm/shared/deep_merge.d.ts +12 -0
  107. package/esm/shared/deep_merge.d.ts.map +1 -0
  108. package/esm/shared/deep_merge.js +49 -0
  109. package/esm/shared/mod.d.ts +1 -0
  110. package/esm/shared/mod.d.ts.map +1 -1
  111. package/esm/shared/mod.js +1 -0
  112. package/esm/shared/types/filetypes.d.ts +2 -2
  113. package/esm/shared/types/filetypes.d.ts.map +1 -1
  114. package/esm/shared/types/permissions.d.ts +1 -1
  115. package/esm/shared/types/permissions.d.ts.map +1 -1
  116. package/esm/shared/types/risks.d.ts +4 -1
  117. package/esm/shared/types/risks.d.ts.map +1 -1
  118. package/esm/skillreader/types.d.ts +2 -2
  119. package/esm/skillreader/types.d.ts.map +1 -1
  120. package/esm/skillreader/types.js +2 -2
  121. package/package.json +1 -1
  122. package/script/analyzer/astgrep/client.d.ts +20 -8
  123. package/script/analyzer/astgrep/client.d.ts.map +1 -1
  124. package/script/analyzer/astgrep/client.js +58 -64
  125. package/script/analyzer/config/default.d.ts +8 -0
  126. package/script/analyzer/config/default.d.ts.map +1 -0
  127. package/script/analyzer/config/default.js +94 -0
  128. package/script/analyzer/config/helpers.d.ts +8 -0
  129. package/script/analyzer/config/helpers.d.ts.map +1 -0
  130. package/script/analyzer/config/helpers.js +76 -0
  131. package/script/analyzer/config/mod.d.ts +4 -0
  132. package/script/analyzer/config/mod.d.ts.map +1 -0
  133. package/script/analyzer/config/mod.js +21 -0
  134. package/script/analyzer/config/types.d.ts +58 -0
  135. package/script/analyzer/config/types.d.ts.map +1 -0
  136. package/script/analyzer/{config.js → config/types.js} +1 -29
  137. package/script/analyzer/logging.d.ts +3 -0
  138. package/script/analyzer/logging.d.ts.map +1 -0
  139. package/script/analyzer/logging.js +9 -0
  140. package/script/analyzer/mod.d.ts +12 -5
  141. package/script/analyzer/mod.d.ts.map +1 -1
  142. package/script/analyzer/mod.js +35 -20
  143. package/script/analyzer/result.d.ts +35 -0
  144. package/script/analyzer/result.d.ts.map +1 -0
  145. package/script/analyzer/result.js +315 -0
  146. package/script/analyzer/rules/bash/commands/mod.d.ts +1 -0
  147. package/script/analyzer/rules/bash/commands/mod.d.ts.map +1 -1
  148. package/script/analyzer/rules/bash/commands/mod.js +3 -0
  149. package/script/analyzer/rules/bash/commands/pip.d.ts +3 -0
  150. package/script/analyzer/rules/bash/commands/pip.d.ts.map +1 -0
  151. package/script/analyzer/rules/bash/commands/pip.js +17 -0
  152. package/script/analyzer/rules/bash/extractFileRefs.d.ts +1 -1
  153. package/script/analyzer/rules/bash/extractFileRefs.d.ts.map +1 -1
  154. package/script/analyzer/rules/bash/extractFileRefs.js +2 -2
  155. package/script/analyzer/rules/bash/inline-command-classifier.d.ts +1 -1
  156. package/script/analyzer/rules/bash/inline-command-classifier.d.ts.map +1 -1
  157. package/script/analyzer/rules/bash/inline-command-classifier.js +4 -4
  158. package/script/analyzer/rules/javascript/extractFileRefs.d.ts +3 -4
  159. package/script/analyzer/rules/javascript/extractFileRefs.d.ts.map +1 -1
  160. package/script/analyzer/rules/javascript/extractFileRefs.js +3 -4
  161. package/script/analyzer/rules/markdown/extractCodeBlocks.d.ts.map +1 -1
  162. package/script/analyzer/rules/markdown/extractCodeBlocks.js +6 -3
  163. package/script/analyzer/rules/markdown/extractFileRefs.d.ts.map +1 -1
  164. package/script/analyzer/rules/markdown/extractFileRefs.js +2 -0
  165. package/script/analyzer/rules/python/extractFileRefs.d.ts +1 -1
  166. package/script/analyzer/rules/python/extractFileRefs.d.ts.map +1 -1
  167. package/script/analyzer/rules/python/extractFileRefs.js +2 -2
  168. package/script/analyzer/steps/001-discovery/discover-files.d.ts +4 -0
  169. package/script/analyzer/steps/001-discovery/discover-files.d.ts.map +1 -1
  170. package/script/analyzer/steps/001-discovery/discover-files.js +18 -2
  171. package/script/analyzer/steps/001-discovery/mod.d.ts.map +1 -1
  172. package/script/analyzer/steps/001-discovery/mod.js +77 -11
  173. package/script/analyzer/steps/002-permissions/mod.d.ts.map +1 -1
  174. package/script/analyzer/steps/002-permissions/mod.js +194 -75
  175. package/script/analyzer/steps/002-permissions/scan-file.d.ts +1 -1
  176. package/script/analyzer/steps/002-permissions/scan-file.d.ts.map +1 -1
  177. package/script/analyzer/steps/002-permissions/scan-file.js +40 -5
  178. package/script/analyzer/steps/002-permissions/seed-frontmatter.js +3 -3
  179. package/script/analyzer/steps/003-risks/dep-risks.d.ts +3 -0
  180. package/script/analyzer/steps/003-risks/dep-risks.d.ts.map +1 -0
  181. package/script/analyzer/steps/003-risks/dep-risks.js +77 -0
  182. package/script/analyzer/steps/003-risks/helpers.d.ts +1 -0
  183. package/script/analyzer/steps/003-risks/helpers.d.ts.map +1 -1
  184. package/script/analyzer/steps/003-risks/helpers.js +1 -0
  185. package/script/analyzer/steps/003-risks/mod.d.ts +3 -2
  186. package/script/analyzer/steps/003-risks/mod.d.ts.map +1 -1
  187. package/script/analyzer/steps/003-risks/mod.js +77 -4
  188. package/script/analyzer/steps/003-risks/policy.d.ts +7 -0
  189. package/script/analyzer/steps/003-risks/policy.d.ts.map +1 -0
  190. package/script/analyzer/steps/003-risks/policy.js +29 -0
  191. package/script/analyzer/steps/003-risks/rule-mapped.d.ts +2 -2
  192. package/script/analyzer/steps/003-risks/rule-mapped.d.ts.map +1 -1
  193. package/script/analyzer/steps/003-risks/rule-mapped.js +83 -2
  194. package/script/analyzer/steps/003-risks/scoring.d.ts +9 -1
  195. package/script/analyzer/steps/003-risks/scoring.d.ts.map +1 -1
  196. package/script/analyzer/steps/003-risks/scoring.js +55 -42
  197. package/script/analyzer/treesitter/client.d.ts +31 -0
  198. package/script/analyzer/treesitter/client.d.ts.map +1 -0
  199. package/script/analyzer/treesitter/client.js +136 -0
  200. package/script/analyzer/treesitter/registry.d.ts +73 -0
  201. package/script/analyzer/treesitter/registry.d.ts.map +1 -0
  202. package/script/analyzer/treesitter/registry.js +206 -0
  203. package/script/analyzer/types.d.ts +14 -28
  204. package/script/analyzer/types.d.ts.map +1 -1
  205. package/script/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts +3 -0
  206. package/script/deps/jsr.io/@deno-library/progress/1.5.1/deps.d.ts.map +1 -0
  207. package/script/deps/jsr.io/@deno-library/progress/1.5.1/deps.js +10 -0
  208. package/script/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts +93 -0
  209. package/script/deps/jsr.io/@deno-library/progress/1.5.1/mod.d.ts.map +1 -0
  210. package/script/deps/jsr.io/@deno-library/progress/1.5.1/mod.js +334 -0
  211. package/script/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts +84 -0
  212. package/script/deps/jsr.io/@deno-library/progress/1.5.1/multi.d.ts.map +1 -0
  213. package/script/deps/jsr.io/@deno-library/progress/1.5.1/multi.js +305 -0
  214. package/script/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts +18 -0
  215. package/script/deps/jsr.io/@deno-library/progress/1.5.1/time.d.ts.map +1 -0
  216. package/script/deps/jsr.io/@deno-library/progress/1.5.1/time.js +48 -0
  217. package/script/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts +700 -0
  218. package/script/deps/jsr.io/@std/fmt/1.0.3/colors.d.ts.map +1 -0
  219. package/script/deps/jsr.io/@std/fmt/1.0.3/colors.js +986 -0
  220. package/script/deps/jsr.io/@std/io/0.225.0/types.d.ts +146 -0
  221. package/script/deps/jsr.io/@std/io/0.225.0/types.d.ts.map +1 -0
  222. package/script/deps/jsr.io/@std/io/0.225.0/types.js +18 -0
  223. package/script/deps/jsr.io/@std/io/0.225.0/write_all.d.ts +51 -0
  224. package/script/deps/jsr.io/@std/io/0.225.0/write_all.d.ts.map +1 -0
  225. package/script/deps/jsr.io/@std/io/0.225.0/write_all.js +65 -0
  226. package/script/shared/deep_merge.d.ts +12 -0
  227. package/script/shared/deep_merge.d.ts.map +1 -0
  228. package/script/shared/deep_merge.js +53 -0
  229. package/script/shared/mod.d.ts +1 -0
  230. package/script/shared/mod.d.ts.map +1 -1
  231. package/script/shared/mod.js +1 -0
  232. package/script/shared/types/filetypes.d.ts +2 -2
  233. package/script/shared/types/filetypes.d.ts.map +1 -1
  234. package/script/shared/types/permissions.d.ts +1 -1
  235. package/script/shared/types/permissions.d.ts.map +1 -1
  236. package/script/shared/types/risks.d.ts +4 -1
  237. package/script/shared/types/risks.d.ts.map +1 -1
  238. package/script/skillreader/types.d.ts +2 -2
  239. package/script/skillreader/types.d.ts.map +1 -1
  240. package/script/skillreader/types.js +2 -2
  241. package/src/_dnt.polyfills.ts +27 -0
  242. package/src/_dnt.shims.ts +64 -0
  243. package/src/analyzer/astgrep/client.ts +184 -0
  244. package/src/analyzer/astgrep/mod.ts +2 -0
  245. package/src/analyzer/config/default.ts +98 -0
  246. package/src/analyzer/config/helpers.ts +107 -0
  247. package/src/analyzer/config/mod.ts +3 -0
  248. package/src/analyzer/config/types.ts +103 -0
  249. package/src/analyzer/logging.ts +8 -0
  250. package/src/analyzer/mod.ts +118 -0
  251. package/src/analyzer/result.ts +393 -0
  252. package/src/analyzer/rules/bash/astTypes.ts +5 -0
  253. package/src/analyzer/rules/bash/commands/bd.ts +23 -0
  254. package/src/analyzer/rules/bash/commands/cron.ts +21 -0
  255. package/src/analyzer/rules/bash/commands/docker.ts +37 -0
  256. package/src/analyzer/rules/bash/commands/eval.ts +52 -0
  257. package/src/analyzer/rules/bash/commands/generic.ts +16 -0
  258. package/src/analyzer/rules/bash/commands/gh.ts +21 -0
  259. package/src/analyzer/rules/bash/commands/git.ts +28 -0
  260. package/src/analyzer/rules/bash/commands/mod.ts +38 -0
  261. package/src/analyzer/rules/bash/commands/node.ts +64 -0
  262. package/src/analyzer/rules/bash/commands/openspec.ts +16 -0
  263. package/src/analyzer/rules/bash/commands/pip.ts +16 -0
  264. package/src/analyzer/rules/bash/commands/sudo.ts +21 -0
  265. package/src/analyzer/rules/bash/destructive.ts +28 -0
  266. package/src/analyzer/rules/bash/extractFileRefs.ts +101 -0
  267. package/src/analyzer/rules/bash/filesystem.ts +50 -0
  268. package/src/analyzer/rules/bash/injection.ts +21 -0
  269. package/src/analyzer/rules/bash/inline-command-classifier.ts +94 -0
  270. package/src/analyzer/rules/bash/mod.ts +23 -0
  271. package/src/analyzer/rules/bash/network.ts +64 -0
  272. package/src/analyzer/rules/bash/secret-detection.ts +43 -0
  273. package/src/analyzer/rules/javascript/astTypes.ts +8 -0
  274. package/src/analyzer/rules/javascript/extractFileRefs.ts +131 -0
  275. package/src/analyzer/rules/javascript/filesystem.ts +28 -0
  276. package/src/analyzer/rules/javascript/injection.ts +21 -0
  277. package/src/analyzer/rules/javascript/mod.ts +26 -0
  278. package/src/analyzer/rules/javascript/network.ts +27 -0
  279. package/src/analyzer/rules/javascript/secret-detection.ts +68 -0
  280. package/src/analyzer/rules/javascript/subprocess.ts +16 -0
  281. package/src/analyzer/rules/markdown/astTypes.ts +35 -0
  282. package/src/analyzer/rules/markdown/extractCodeBlocks.ts +101 -0
  283. package/src/analyzer/rules/markdown/extractFileRefs.ts +179 -0
  284. package/src/analyzer/rules/markdown/mod.ts +12 -0
  285. package/src/analyzer/rules/mod.ts +77 -0
  286. package/src/analyzer/rules/python/astTypes.ts +9 -0
  287. package/src/analyzer/rules/python/extractFileRefs.ts +92 -0
  288. package/src/analyzer/rules/python/mod.ts +15 -0
  289. package/src/analyzer/rules/python/network.ts +26 -0
  290. package/src/analyzer/rules/python/secret-detection.ts +30 -0
  291. package/src/analyzer/rules/shared/file-refs.ts +38 -0
  292. package/src/analyzer/rules/shared/network-evaluators.ts +107 -0
  293. package/src/analyzer/rules/shared/prompt-injection.ts +48 -0
  294. package/src/analyzer/rules/shared/secret-evaluators.ts +13 -0
  295. package/src/analyzer/rules/text/mod.ts +12 -0
  296. package/src/analyzer/rules/typescript/mod.ts +7 -0
  297. package/src/analyzer/steps/001-discovery/discover-files.ts +211 -0
  298. package/src/analyzer/steps/001-discovery/filter-files.ts +72 -0
  299. package/src/analyzer/steps/001-discovery/mod.ts +103 -0
  300. package/src/analyzer/steps/002-permissions/mod.ts +329 -0
  301. package/src/analyzer/steps/002-permissions/scan-file.ts +258 -0
  302. package/src/analyzer/steps/002-permissions/seed-frontmatter.ts +66 -0
  303. package/src/analyzer/steps/002-permissions/synthesize.ts +42 -0
  304. package/src/analyzer/steps/003-risks/dep-risks.ts +89 -0
  305. package/src/analyzer/steps/003-risks/helpers.ts +41 -0
  306. package/src/analyzer/steps/003-risks/mod.ts +86 -0
  307. package/src/analyzer/steps/003-risks/policy.ts +38 -0
  308. package/src/analyzer/steps/003-risks/rule-mapped.ts +206 -0
  309. package/src/analyzer/steps/003-risks/scoring.ts +117 -0
  310. package/src/analyzer/steps/mod.ts +3 -0
  311. package/src/analyzer/treesitter/client.ts +120 -0
  312. package/src/analyzer/treesitter/registry.ts +198 -0
  313. package/src/analyzer/types.ts +78 -0
  314. package/src/analyzer/utils/code-block-path.ts +33 -0
  315. package/src/analyzer/utils/id-generator.ts +59 -0
  316. package/src/analyzer/utils/secret-validator.ts +29 -0
  317. package/src/analyzer/utils/url-parser.ts +25 -0
  318. package/src/deps/jsr.io/@deno-library/progress/1.5.1/deps.ts +3 -0
  319. package/src/deps/jsr.io/@deno-library/progress/1.5.1/mod.ts +265 -0
  320. package/src/deps/jsr.io/@deno-library/progress/1.5.1/multi.ts +250 -0
  321. package/src/deps/jsr.io/@deno-library/progress/1.5.1/time.ts +69 -0
  322. package/src/deps/jsr.io/@std/fmt/1.0.3/colors.ts +1004 -0
  323. package/src/deps/jsr.io/@std/internal/1.0.12/_os.ts +15 -0
  324. package/src/deps/jsr.io/@std/internal/1.0.12/os.ts +7 -0
  325. package/src/deps/jsr.io/@std/io/0.225.0/types.ts +157 -0
  326. package/src/deps/jsr.io/@std/io/0.225.0/write_all.ts +65 -0
  327. package/src/deps/jsr.io/@std/path/1.1.4/_common/assert_path.ts +10 -0
  328. package/src/deps/jsr.io/@std/path/1.1.4/_common/basename.ts +53 -0
  329. package/src/deps/jsr.io/@std/path/1.1.4/_common/common.ts +26 -0
  330. package/src/deps/jsr.io/@std/path/1.1.4/_common/constants.ts +49 -0
  331. package/src/deps/jsr.io/@std/path/1.1.4/_common/dirname.ts +9 -0
  332. package/src/deps/jsr.io/@std/path/1.1.4/_common/format.ts +25 -0
  333. package/src/deps/jsr.io/@std/path/1.1.4/_common/from_file_url.ts +12 -0
  334. package/src/deps/jsr.io/@std/path/1.1.4/_common/glob_to_reg_exp.ts +295 -0
  335. package/src/deps/jsr.io/@std/path/1.1.4/_common/normalize.ts +9 -0
  336. package/src/deps/jsr.io/@std/path/1.1.4/_common/normalize_string.ts +74 -0
  337. package/src/deps/jsr.io/@std/path/1.1.4/_common/relative.ts +10 -0
  338. package/src/deps/jsr.io/@std/path/1.1.4/_common/strip_trailing_separators.ts +25 -0
  339. package/src/deps/jsr.io/@std/path/1.1.4/_common/to_file_url.ts +17 -0
  340. package/src/deps/jsr.io/@std/path/1.1.4/basename.ts +37 -0
  341. package/src/deps/jsr.io/@std/path/1.1.4/common.ts +35 -0
  342. package/src/deps/jsr.io/@std/path/1.1.4/constants.ts +18 -0
  343. package/src/deps/jsr.io/@std/path/1.1.4/dirname.ts +30 -0
  344. package/src/deps/jsr.io/@std/path/1.1.4/extname.ts +29 -0
  345. package/src/deps/jsr.io/@std/path/1.1.4/format.ts +30 -0
  346. package/src/deps/jsr.io/@std/path/1.1.4/from_file_url.ts +30 -0
  347. package/src/deps/jsr.io/@std/path/1.1.4/glob_to_regexp.ts +94 -0
  348. package/src/deps/jsr.io/@std/path/1.1.4/is_absolute.ts +30 -0
  349. package/src/deps/jsr.io/@std/path/1.1.4/is_glob.ts +49 -0
  350. package/src/deps/jsr.io/@std/path/1.1.4/join.ts +31 -0
  351. package/src/deps/jsr.io/@std/path/1.1.4/join_globs.ts +42 -0
  352. package/src/deps/jsr.io/@std/path/1.1.4/mod.ts +217 -0
  353. package/src/deps/jsr.io/@std/path/1.1.4/normalize.ts +33 -0
  354. package/src/deps/jsr.io/@std/path/1.1.4/normalize_glob.ts +45 -0
  355. package/src/deps/jsr.io/@std/path/1.1.4/parse.ts +44 -0
  356. package/src/deps/jsr.io/@std/path/1.1.4/posix/_util.ts +10 -0
  357. package/src/deps/jsr.io/@std/path/1.1.4/posix/basename.ts +62 -0
  358. package/src/deps/jsr.io/@std/path/1.1.4/posix/constants.ts +15 -0
  359. package/src/deps/jsr.io/@std/path/1.1.4/posix/dirname.ts +72 -0
  360. package/src/deps/jsr.io/@std/path/1.1.4/posix/extname.ts +96 -0
  361. package/src/deps/jsr.io/@std/path/1.1.4/posix/format.ts +31 -0
  362. package/src/deps/jsr.io/@std/path/1.1.4/posix/from_file_url.ts +25 -0
  363. package/src/deps/jsr.io/@std/path/1.1.4/posix/glob_to_regexp.ts +94 -0
  364. package/src/deps/jsr.io/@std/path/1.1.4/posix/is_absolute.ts +25 -0
  365. package/src/deps/jsr.io/@std/path/1.1.4/posix/join.ts +46 -0
  366. package/src/deps/jsr.io/@std/path/1.1.4/posix/join_globs.ts +45 -0
  367. package/src/deps/jsr.io/@std/path/1.1.4/posix/normalize.ts +63 -0
  368. package/src/deps/jsr.io/@std/path/1.1.4/posix/normalize_glob.ts +43 -0
  369. package/src/deps/jsr.io/@std/path/1.1.4/posix/parse.ts +121 -0
  370. package/src/deps/jsr.io/@std/path/1.1.4/posix/relative.ts +103 -0
  371. package/src/deps/jsr.io/@std/path/1.1.4/posix/resolve.ts +71 -0
  372. package/src/deps/jsr.io/@std/path/1.1.4/posix/to_file_url.ts +32 -0
  373. package/src/deps/jsr.io/@std/path/1.1.4/posix/to_namespaced_path.ts +21 -0
  374. package/src/deps/jsr.io/@std/path/1.1.4/relative.ts +32 -0
  375. package/src/deps/jsr.io/@std/path/1.1.4/resolve.ts +32 -0
  376. package/src/deps/jsr.io/@std/path/1.1.4/to_file_url.ts +30 -0
  377. package/src/deps/jsr.io/@std/path/1.1.4/to_namespaced_path.ts +31 -0
  378. package/src/deps/jsr.io/@std/path/1.1.4/types.ts +40 -0
  379. package/src/deps/jsr.io/@std/path/1.1.4/windows/_util.ts +28 -0
  380. package/src/deps/jsr.io/@std/path/1.1.4/windows/basename.ts +54 -0
  381. package/src/deps/jsr.io/@std/path/1.1.4/windows/constants.ts +15 -0
  382. package/src/deps/jsr.io/@std/path/1.1.4/windows/dirname.ts +118 -0
  383. package/src/deps/jsr.io/@std/path/1.1.4/windows/extname.ts +90 -0
  384. package/src/deps/jsr.io/@std/path/1.1.4/windows/format.ts +31 -0
  385. package/src/deps/jsr.io/@std/path/1.1.4/windows/from_file_url.ts +34 -0
  386. package/src/deps/jsr.io/@std/path/1.1.4/windows/glob_to_regexp.ts +92 -0
  387. package/src/deps/jsr.io/@std/path/1.1.4/windows/is_absolute.ts +40 -0
  388. package/src/deps/jsr.io/@std/path/1.1.4/windows/join.ts +78 -0
  389. package/src/deps/jsr.io/@std/path/1.1.4/windows/join_globs.ts +46 -0
  390. package/src/deps/jsr.io/@std/path/1.1.4/windows/normalize.ts +136 -0
  391. package/src/deps/jsr.io/@std/path/1.1.4/windows/normalize_glob.ts +43 -0
  392. package/src/deps/jsr.io/@std/path/1.1.4/windows/parse.ts +184 -0
  393. package/src/deps/jsr.io/@std/path/1.1.4/windows/relative.ts +128 -0
  394. package/src/deps/jsr.io/@std/path/1.1.4/windows/resolve.ts +178 -0
  395. package/src/deps/jsr.io/@std/path/1.1.4/windows/to_file_url.ts +38 -0
  396. package/src/deps/jsr.io/@std/path/1.1.4/windows/to_namespaced_path.ts +60 -0
  397. package/src/deps/jsr.io/@std/yaml/1.0.11/_chars.ts +55 -0
  398. package/src/deps/jsr.io/@std/yaml/1.0.11/_dumper_state.ts +841 -0
  399. package/src/deps/jsr.io/@std/yaml/1.0.11/_loader_state.ts +1780 -0
  400. package/src/deps/jsr.io/@std/yaml/1.0.11/_schema.ts +183 -0
  401. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/binary.ts +127 -0
  402. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/bool.ts +37 -0
  403. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/float.ts +112 -0
  404. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/int.ts +174 -0
  405. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/map.ts +17 -0
  406. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/merge.ts +13 -0
  407. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/nil.ts +27 -0
  408. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/omap.ts +30 -0
  409. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/pairs.ts +22 -0
  410. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/regexp.ts +33 -0
  411. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/seq.ts +13 -0
  412. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/set.ts +17 -0
  413. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/str.ts +12 -0
  414. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/timestamp.ts +101 -0
  415. package/src/deps/jsr.io/@std/yaml/1.0.11/_type/undefined.ts +23 -0
  416. package/src/deps/jsr.io/@std/yaml/1.0.11/_type.ts +49 -0
  417. package/src/deps/jsr.io/@std/yaml/1.0.11/_utils.ts +16 -0
  418. package/src/deps/jsr.io/@std/yaml/1.0.11/mod.ts +54 -0
  419. package/src/deps/jsr.io/@std/yaml/1.0.11/parse.ts +128 -0
  420. package/src/deps/jsr.io/@std/yaml/1.0.11/stringify.ts +118 -0
  421. package/src/shared/deep_merge.ts +73 -0
  422. package/src/shared/mod.ts +2 -0
  423. package/src/shared/types/filetypes.ts +101 -0
  424. package/src/shared/types/findings.ts +7 -0
  425. package/src/shared/types/mod.ts +6 -0
  426. package/src/shared/types/permissions.ts +17 -0
  427. package/src/shared/types/references.ts +62 -0
  428. package/src/shared/types/risks.ts +72 -0
  429. package/src/shared/types/syntaxNode.ts +7 -0
  430. package/src/skillreader/cloudStorage/mod.ts +170 -0
  431. package/src/skillreader/factory.ts +71 -0
  432. package/src/skillreader/fs/git.ts +153 -0
  433. package/src/skillreader/fs/mod.ts +84 -0
  434. package/src/skillreader/github/base.ts +162 -0
  435. package/src/skillreader/github/githubApi.ts +40 -0
  436. package/src/skillreader/github/githubRaw.ts +24 -0
  437. package/src/skillreader/github/mod.ts +45 -0
  438. package/src/skillreader/github/utils.ts +40 -0
  439. package/src/skillreader/manifest.ts +67 -0
  440. package/src/skillreader/mod.ts +26 -0
  441. package/src/skillreader/types.ts +150 -0
  442. package/src/skillreader/utils/frontmatter-parser.ts +72 -0
  443. package/src/skillreader/utils/http-range.ts +38 -0
  444. package/src/skillreader/utils/mod.ts +12 -0
  445. package/esm/analyzer/astgrep/registry.d.ts +0 -18
  446. package/esm/analyzer/astgrep/registry.d.ts.map +0 -1
  447. package/esm/analyzer/astgrep/registry.js +0 -71
  448. package/esm/analyzer/config.d.ts +0 -27
  449. package/esm/analyzer/config.d.ts.map +0 -1
  450. package/esm/analyzer/steps/003-risks/output.d.ts +0 -3
  451. package/esm/analyzer/steps/003-risks/output.d.ts.map +0 -1
  452. package/esm/analyzer/steps/003-risks/output.js +0 -16
  453. package/esm/analyzer/treesiter/client.d.ts +0 -26
  454. package/esm/analyzer/treesiter/client.d.ts.map +0 -1
  455. package/script/analyzer/astgrep/registry.d.ts +0 -18
  456. package/script/analyzer/astgrep/registry.d.ts.map +0 -1
  457. package/script/analyzer/astgrep/registry.js +0 -109
  458. package/script/analyzer/config.d.ts +0 -27
  459. package/script/analyzer/config.d.ts.map +0 -1
  460. package/script/analyzer/steps/003-risks/output.d.ts +0 -3
  461. package/script/analyzer/steps/003-risks/output.d.ts.map +0 -1
  462. package/script/analyzer/steps/003-risks/output.js +0 -19
  463. package/script/analyzer/treesiter/client.d.ts +0 -26
  464. package/script/analyzer/treesiter/client.d.ts.map +0 -1
  465. package/script/analyzer/treesiter/client.js +0 -165
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/mod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAMpE,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAKhE"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/mod.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AASrE,wBAAsB,WAAW,CAC7B,KAAK,EAAE,aAAa,EACpB,OAAO,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,iBAAiB,GAAG,QAAQ,CAAC,GAC9D,OAAO,CAAC,mBAAmB,CAAC,CAuC9B"}
@@ -1,11 +1,48 @@
1
- import { toAnalyzerResult } from "./output.js";
1
+ import * as dntShim from "../../../_dnt.shims.js";
2
+ import ProgressBar from "../../../deps/jsr.io/@deno-library/progress/1.5.1/mod.js";
3
+ import { SkillAnalyzerResult } from "../../result.js";
4
+ import { DEFAULT_ANALYZER_CONFIG, resolveConfig } from "../../config/mod.js";
5
+ import { analyzeDependencyRisks } from "./dep-risks.js";
2
6
  import { analyzeRuleMappedRisks } from "./rule-mapped.js";
3
7
  const REMOTE_SCRIPT_WARNING = "Remote script content analysis is NOT_IMPLEMENTED";
4
- export function run003Risks(state) {
8
+ const ANSI_SHOW_CURSOR = "\x1b[?25h";
9
+ const ENCODER = new TextEncoder();
10
+ export async function run003Risks(state, context) {
5
11
  let next = state;
6
- next = analyzeRuleMappedRisks(next);
12
+ const resolvedConfig = context?.config ?? resolveConfig(DEFAULT_ANALYZER_CONFIG);
13
+ const shouldRenderProgress = (context?.showProgressBar ?? false) && dntShim.Deno.stderr.isTerminal();
14
+ const riskBar = shouldRenderProgress
15
+ ? new ProgressBar({
16
+ total: Math.max(1, next.findings.length),
17
+ clear: true,
18
+ output: dntShim.Deno.stderr,
19
+ display: "Finalizing [:bar] :completed/:total findings :percent",
20
+ })
21
+ : null;
22
+ let processed = 0;
23
+ try {
24
+ if (riskBar) {
25
+ await riskBar.render(processed);
26
+ }
27
+ const resolvedContext = { config: resolvedConfig };
28
+ next = analyzeDependencyRisks(next, resolvedContext);
29
+ next = analyzeRuleMappedRisks(next, resolvedContext, () => {
30
+ processed += 1;
31
+ if (riskBar) {
32
+ void riskBar.render(processed);
33
+ }
34
+ });
35
+ }
36
+ finally {
37
+ if (riskBar) {
38
+ await riskBar.end();
39
+ }
40
+ if (shouldRenderProgress && dntShim.Deno.stderr.isTerminal()) {
41
+ dntShim.Deno.stderr.writeSync(ENCODER.encode(ANSI_SHOW_CURSOR));
42
+ }
43
+ }
7
44
  next = addRemoteScriptWarningIfNeeded(next);
8
- return toAnalyzerResult(dedupeRisks(next));
45
+ return new SkillAnalyzerResult(dedupeRisks(next), resolvedConfig);
9
46
  }
10
47
  function addRemoteScriptWarningIfNeeded(state) {
11
48
  const hasRemoteCodeExecution = state.risks.some((risk) => risk.type === "NETWORK:remote_code_execution");
@@ -0,0 +1,7 @@
1
+ import type { TreesitterGrammar } from "../../treesitter/registry.js";
2
+ import type { AnalyzerConfig } from "../../config/mod.js";
3
+ export declare function isDenied(config: AnalyzerConfig, grammar: TreesitterGrammar, importName: string): boolean;
4
+ export declare function isAllowed(config: AnalyzerConfig, grammar: TreesitterGrammar, importName: string): boolean;
5
+ export declare function isNetworkDenied(config: AnalyzerConfig, host: string): boolean;
6
+ export declare function isNetworkAllowed(config: AnalyzerConfig, host: string): boolean;
7
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAY1D,wBAAgB,QAAQ,CACpB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GACnB,OAAO,CAGT;AAED,wBAAgB,SAAS,CACrB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,MAAM,GACnB,OAAO,CAGT;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9E"}
@@ -0,0 +1,23 @@
1
+ function normalizeEntry(value) {
2
+ return value.trim().toLowerCase();
3
+ }
4
+ function listHasValue(list, value) {
5
+ if (!value || !list || list.length === 0)
6
+ return false;
7
+ const normalized = normalizeEntry(value);
8
+ return list.some((entry) => normalizeEntry(entry) === normalized);
9
+ }
10
+ export function isDenied(config, grammar, importName) {
11
+ const imports = config.denylist?.languages?.[grammar]?.imports;
12
+ return listHasValue(imports, importName);
13
+ }
14
+ export function isAllowed(config, grammar, importName) {
15
+ const imports = config.allowlist?.languages?.[grammar]?.imports;
16
+ return listHasValue(imports, importName);
17
+ }
18
+ export function isNetworkDenied(config, host) {
19
+ return listHasValue(config.denylist?.network?.domains, host);
20
+ }
21
+ export function isNetworkAllowed(config, host) {
22
+ return listHasValue(config.allowlist?.network?.domains, host);
23
+ }
@@ -1,3 +1,3 @@
1
- import type { AnalyzerState } from "../../types.js";
2
- export declare function analyzeRuleMappedRisks(state: AnalyzerState): AnalyzerState;
1
+ import type { AnalyzerContext, AnalyzerState } from "../../types.js";
2
+ export declare function analyzeRuleMappedRisks(state: AnalyzerState, context: Pick<AnalyzerContext, "config">, onFindingProcessed?: () => void): AnalyzerState;
3
3
  //# sourceMappingURL=rule-mapped.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule-mapped.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/rule-mapped.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAUpD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CA0B1E"}
1
+ {"version":3,"file":"rule-mapped.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/rule-mapped.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAarE,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,EACxC,kBAAkB,CAAC,EAAE,MAAM,IAAI,GAChC,aAAa,CAsCf"}
@@ -1,11 +1,13 @@
1
1
  import { evalRuleRiskMappings, RULES_BY_ID } from "../../rules/mod.js";
2
2
  import { addRisk } from "./helpers.js";
3
+ import { isAllowed, isDenied, isNetworkAllowed, isNetworkDenied } from "./policy.js";
4
+ import { GRAMMAR_SPECS } from "../../treesitter/registry.js";
3
5
  const PROMPT_CATEGORY = "PROMPT";
4
6
  const INJECTION_CATEGORY = "INJECTION";
5
7
  const NETWORK_CATEGORY = "NETWORK";
6
8
  const SECRETS_CATEGORY = "SECRETS";
7
9
  const DESTRUCTIVE_CATEGORIES = new Set(["DESTRUCTIVE", "PRIVILEGE", "PERSISTENCE"]);
8
- export function analyzeRuleMappedRisks(state) {
10
+ export function analyzeRuleMappedRisks(state, context, onFindingProcessed) {
9
11
  let next = state;
10
12
  for (const finding of next.findings) {
11
13
  const rule = RULES_BY_ID.get(finding.ruleId);
@@ -14,21 +16,100 @@ export function analyzeRuleMappedRisks(state) {
14
16
  const matchedPermission = resolvePermissionForFinding(next, finding);
15
17
  const mapped = evalRuleRiskMappings(rule, { permission: matchedPermission, finding });
16
18
  for (const risk of mapped) {
19
+ const policy = resolvePolicyForRisk({
20
+ context,
21
+ rule,
22
+ finding,
23
+ permission: matchedPermission,
24
+ risk,
25
+ });
26
+ if (policy.skip)
27
+ continue;
17
28
  const permissionIds = selectPermissionIds(next, finding, risk.code, matchedPermission);
18
29
  if (permissionIds.length === 0)
19
30
  continue;
20
31
  next = addRisk(next, {
21
32
  type: risk.code,
33
+ groupKey: matchedPermission ? `${risk.code}:${matchedPermission.tool}` : risk.code,
22
34
  severity: risk.severity,
23
35
  message: risk.message,
24
36
  permissionIds,
25
37
  reference: finding.reference,
26
- metadata: risk.metadata ?? finding.extracted,
38
+ metadata: policy.metadata,
27
39
  });
28
40
  }
41
+ onFindingProcessed?.();
29
42
  }
30
43
  return next;
31
44
  }
45
+ function resolvePolicyForRisk(input) {
46
+ const { context, rule, finding, permission, risk } = input;
47
+ const baseMetadata = (risk.metadata ?? finding.extracted);
48
+ const policyMetadata = {};
49
+ if (risk.code.startsWith("NETWORK:")) {
50
+ const host = resolveHost(baseMetadata);
51
+ if (host) {
52
+ if (isNetworkDenied(context.config, host)) {
53
+ policyMetadata.network = { host, source: "denylist" };
54
+ }
55
+ else if (isNetworkAllowed(context.config, host)) {
56
+ return { skip: true };
57
+ }
58
+ }
59
+ }
60
+ const grammar = resolveRuleGrammar(rule);
61
+ const importName = resolveImportName(finding, permission);
62
+ if (grammar && importName) {
63
+ if (isDenied(context.config, grammar, importName)) {
64
+ policyMetadata.language = { grammar, importName, source: "denylist" };
65
+ }
66
+ else if (isAllowed(context.config, grammar, importName)) {
67
+ return { skip: true };
68
+ }
69
+ }
70
+ const metadata = Object.keys(policyMetadata).length
71
+ ? { ...(baseMetadata ?? {}), policy: policyMetadata }
72
+ : baseMetadata;
73
+ return { skip: false, metadata };
74
+ }
75
+ function resolveRuleGrammar(rule) {
76
+ if (!rule)
77
+ return null;
78
+ if ("grammar" in rule && typeof rule.grammar === "string") {
79
+ return rule.grammar in GRAMMAR_SPECS ? rule.grammar : null;
80
+ }
81
+ return null;
82
+ }
83
+ function resolveImportName(finding, permission) {
84
+ const extracted = finding.extracted;
85
+ const candidates = [
86
+ extracted?.import,
87
+ extracted?.module,
88
+ extracted?.package,
89
+ extracted?.dependency,
90
+ ];
91
+ for (const value of candidates) {
92
+ if (typeof value === "string" && value.trim())
93
+ return value.trim();
94
+ }
95
+ if (permission?.metadata) {
96
+ const meta = permission.metadata;
97
+ const metaCandidates = [meta.import, meta.module, meta.package, meta.dependency];
98
+ for (const value of metaCandidates) {
99
+ if (typeof value === "string" && value.trim())
100
+ return value.trim();
101
+ }
102
+ }
103
+ return undefined;
104
+ }
105
+ function resolveHost(metadata) {
106
+ if (!metadata)
107
+ return undefined;
108
+ const raw = metadata.host;
109
+ if (typeof raw === "string" && raw.trim())
110
+ return raw.trim();
111
+ return undefined;
112
+ }
32
113
  function resolvePermissionForFinding(state, finding) {
33
114
  return state.permissions.find((permission) => overlaps(permission, finding));
34
115
  }
@@ -1,7 +1,15 @@
1
+ import type { AnalyzerConfig } from "../../config/mod.js";
1
2
  import type { AnalyzerState } from "../../types.js";
3
+ type RiskLevel = "safe" | "caution" | "attention" | "risky" | "avoid";
2
4
  export declare function scoreState(state: AnalyzerState): {
3
5
  score: number;
4
- riskLevel: "safe" | "caution" | "attention" | "risky" | "avoid";
6
+ riskLevel: RiskLevel;
5
7
  summary: string;
6
8
  };
9
+ export declare function scoreState(state: AnalyzerState, config: AnalyzerConfig): {
10
+ score: number;
11
+ riskLevel: RiskLevel;
12
+ summary: string;
13
+ };
14
+ export {};
7
15
  //# sourceMappingURL=scoring.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/scoring.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;IAChE,OAAO,EAAE,MAAM,CAAC;CACnB,CA0CA"}
1
+ {"version":3,"file":"scoring.d.ts","sourceRoot":"","sources":["../../../../src/analyzer/steps/003-risks/scoring.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,KAAK,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;AAGtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,GAAG;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,wBAAgB,UAAU,CACtB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,cAAc,GACvB;IACC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC"}
@@ -1,58 +1,71 @@
1
- import { SCORING } from "../../config.js";
2
- export function scoreState(state) {
3
- const severityScore = Math.max(0, ...state.risks.map((risk) => SCORING.severity[risk.severity]));
4
- const permissionScore = Math.max(0, ...state.permissions.map((perm) => {
5
- const base = SCORING.permissions[`${perm.scope}:${perm.permission}`] ?? 0;
6
- const wildcard = perm.args?.includes("*") ? SCORING.scopeWildcard : 0;
7
- return base + wildcard;
8
- }));
9
- let uplift = 0;
10
- const hasExternalPost = state.risks.some((risk) => risk.type === "NETWORK:data_exfiltration" &&
11
- ["POST", "PUT", "PATCH"].includes(String(risk.metadata?.method ?? "GET").toUpperCase()));
12
- if (hasExternalPost)
13
- uplift += SCORING.uplift.externalPost;
14
- const hasPipeToShell = state.risks.some((risk) => risk.type === "NETWORK:remote_code_execution");
15
- if (hasPipeToShell)
16
- uplift += SCORING.uplift.pipeToShell;
17
- const criticalCount = state.risks.filter((risk) => risk.severity === "critical").length;
18
- if (criticalCount >= 3)
19
- uplift += SCORING.uplift.multipleCritical;
20
- const hasSecretTransfer = state.risks.some((risk) => risk.type === "NETWORK:credential_leak" ||
21
- risk.type === "NETWORK:localhost_secret_exposure");
22
- if (hasSecretTransfer)
23
- uplift += SCORING.uplift.secretsInRequest;
24
- const score = severityScore + permissionScore + uplift;
25
- const riskLevel = toRiskLevel(score);
1
+ import { DEFAULT_ANALYZER_CONFIG, resolveConfig } from "../../config/mod.js";
2
+ const SEVERITY_ORDER = { critical: 0, warning: 1, info: 2 };
3
+ export function scoreState(state, config) {
4
+ const resolvedConfig = resolveConfig(config ?? DEFAULT_ANALYZER_CONFIG);
5
+ const baseScore = {
6
+ info: 0,
7
+ warning: 1,
8
+ critical: 5,
9
+ ...(resolvedConfig.riskReport?.baseScore ?? {}),
10
+ };
11
+ const upliftConfig = resolvedConfig.riskReport?.uplift ?? {};
12
+ const thresholds = {
13
+ safe: 0,
14
+ caution: 1,
15
+ attention: 3,
16
+ risky: 5,
17
+ avoid: 7,
18
+ ...(resolvedConfig.riskReport?.thresholds ?? {}),
19
+ };
20
+ const groupedSeverity = new Map();
21
+ const ungroupedSeverity = [];
22
+ for (const risk of state.risks) {
23
+ const score = baseScore[risk.severity] ?? 0;
24
+ if (risk.groupKey) {
25
+ groupedSeverity.set(risk.groupKey, Math.max(groupedSeverity.get(risk.groupKey) ?? 0, score));
26
+ continue;
27
+ }
28
+ ungroupedSeverity.push(score);
29
+ }
30
+ const severityScore = Math.max(0, ...ungroupedSeverity, ...groupedSeverity.values());
31
+ const riskTypes = new Set(state.risks.map((risk) => risk.type));
32
+ const upliftScore = Array.from(riskTypes).reduce((sum, riskType) => sum + (upliftConfig[riskType] ?? 0), 0);
33
+ const score = severityScore + upliftScore;
34
+ const riskLevel = toRiskLevel(score, thresholds);
26
35
  const summary = buildSummary(state, riskLevel);
27
36
  return { score, riskLevel, summary };
28
37
  }
29
- function toRiskLevel(score) {
30
- if (score <= 0)
31
- return "safe";
32
- if (score <= 2)
33
- return "caution";
34
- if (score <= 4)
35
- return "attention";
36
- if (score <= 6)
38
+ function toRiskLevel(score, thresholds) {
39
+ if (score >= thresholds.avoid)
40
+ return "avoid";
41
+ if (score >= thresholds.risky)
37
42
  return "risky";
38
- return "avoid";
43
+ if (score >= thresholds.attention)
44
+ return "attention";
45
+ if (score >= thresholds.caution)
46
+ return "caution";
47
+ return "safe";
39
48
  }
40
49
  function buildSummary(state, riskLevel) {
41
- const topRisk = state.risks[0]?.type ?? "no major risks";
42
- const topPermission = state.permissions[0]
43
- ? `${state.permissions[0].scope}:${state.permissions[0].permission}`
44
- : "no permissions";
50
+ if (state.risks.length === 0)
51
+ return "No significant risk signals detected.";
52
+ const sorted = [...state.risks].sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
53
+ const topSeverity = sorted[0].severity;
54
+ const topTypes = [
55
+ ...new Set(sorted.filter((risk) => risk.severity === topSeverity).map((risk) => risk.type)),
56
+ ].slice(0, 3);
57
+ const typeList = topTypes.join(", ");
45
58
  if (riskLevel === "avoid") {
46
- return `Critical risks detected (${topRisk}) with elevated capability (${topPermission}).`;
59
+ return `Severe risks detected: ${typeList}.`;
47
60
  }
48
61
  if (riskLevel === "risky") {
49
- return `Elevated risk profile (${topRisk}) and broad access (${topPermission}).`;
62
+ return `Elevated risk: ${typeList}.`;
50
63
  }
51
64
  if (riskLevel === "attention") {
52
- return `Moderate risk signal (${topRisk}) from detected capabilities.`;
65
+ return `Moderate risk: ${typeList}.`;
53
66
  }
54
67
  if (riskLevel === "caution") {
55
- return `Low-risk profile with limited permissions (${topPermission}).`;
68
+ return `Low-risk signals: ${typeList}.`;
56
69
  }
57
70
  return "No significant risk signals detected.";
58
71
  }
@@ -0,0 +1,31 @@
1
+ import { Parser, Query, Tree } from "web-tree-sitter";
2
+ import type { TreesitterGrammar } from "./registry.js";
3
+ import type { AnalyzerLogger } from "../types.js";
4
+ export declare class TreesitterClient {
5
+ private readonly logger;
6
+ private readonly showProgressBar;
7
+ private PARSER_BY_GRAMMAR;
8
+ private LANG_BY_GRAMMAR;
9
+ private QUERY_CACHE;
10
+ private ROOT_NODE_CACHE_BY_CONTENT;
11
+ /** Parser.init() is idempotent but we avoid re-calling it. */
12
+ private parserInitialized;
13
+ constructor(logger?: AnalyzerLogger, showProgressBar?: boolean);
14
+ private ensureParserInit;
15
+ getParser(grammar: TreesitterGrammar): Promise<Parser>;
16
+ /**
17
+ * Creates (and caches) a tree-sitter Query for the given grammar and S-expression query string.
18
+ */
19
+ createQuery(grammar: TreesitterGrammar, queryString: string): Promise<Query>;
20
+ /**
21
+ * Parses content into a tree-sitter Tree with memoization.
22
+ *
23
+ * Cache key strategy:
24
+ * - first level: content length
25
+ * - second level: fast non-cryptographic hash of content
26
+ */
27
+ parse(grammar: TreesitterGrammar, content: string): Promise<Tree>;
28
+ private getTreeCache;
29
+ private hashContent;
30
+ }
31
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/analyzer/treesitter/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEhE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,qBAAa,gBAAgB;IAYrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAZpC,OAAO,CAAC,iBAAiB,CAAkD;IAC3E,OAAO,CAAC,eAAe,CAAoD;IAC3E,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,0BAA0B,CAG3B;IACP,8DAA8D;IAC9D,OAAO,CAAC,iBAAiB,CAAkB;gBAGtB,MAAM,GAAE,cAA6B,EACrC,eAAe,GAAE,OAAe;YAGvC,gBAAgB;IAOjB,SAAS,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBnE;;OAEG;IACU,WAAW,CAAC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAazF;;;;;;OAMG;IACU,KAAK,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9E,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,WAAW;CAStB"}
@@ -1,10 +1,20 @@
1
- // export type TreesitterQuery = {
2
- // matches: (
3
- // node: unknown,
4
- // ) => Array<{ captures: Array<{ name: string; node: unknown }> }>;
5
- // };
1
+ import { Language, Parser, Query } from "web-tree-sitter";
2
+ import { ensureGrammar } from "./registry.js";
3
+ import { NO_OP_LOGGER } from "../logging.js";
6
4
  export class TreesitterClient {
7
- constructor() {
5
+ constructor(logger = NO_OP_LOGGER, showProgressBar = false) {
6
+ Object.defineProperty(this, "logger", {
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true,
10
+ value: logger
11
+ });
12
+ Object.defineProperty(this, "showProgressBar", {
13
+ enumerable: true,
14
+ configurable: true,
15
+ writable: true,
16
+ value: showProgressBar
17
+ });
8
18
  Object.defineProperty(this, "PARSER_BY_GRAMMAR", {
9
19
  enumerable: true,
10
20
  configurable: true,
@@ -23,50 +33,42 @@ export class TreesitterClient {
23
33
  writable: true,
24
34
  value: new Map()
25
35
  });
26
- Object.defineProperty(this, "ROOT_NODE_CACHE_BY_GRAMMAR", {
36
+ Object.defineProperty(this, "ROOT_NODE_CACHE_BY_CONTENT", {
27
37
  enumerable: true,
28
38
  configurable: true,
29
39
  writable: true,
30
40
  value: {}
31
41
  });
32
- Object.defineProperty(this, "GRAMMER_LIB_BY_LANGUAGE", {
42
+ /** Parser.init() is idempotent but we avoid re-calling it. */
43
+ Object.defineProperty(this, "parserInitialized", {
33
44
  enumerable: true,
34
45
  configurable: true,
35
46
  writable: true,
36
- value: {
37
- markdown: { lib: "@tree-sitter-grammars/tree-sitter-markdown" },
38
- "markdown-inline": {
39
- lib: "@tree-sitter-grammars/tree-sitter-markdown",
40
- module: "inline",
41
- },
42
- }
47
+ value: false
43
48
  });
44
49
  }
50
+ async ensureParserInit() {
51
+ if (this.parserInitialized)
52
+ return;
53
+ await Parser.init();
54
+ this.parserInitialized = true;
55
+ }
45
56
  async getParser(grammar) {
46
57
  if (this.PARSER_BY_GRAMMAR[grammar]) {
47
58
  return this.PARSER_BY_GRAMMAR[grammar];
48
59
  }
49
- const gramerLib = this.GRAMMER_LIB_BY_LANGUAGE[grammar];
50
- if (!gramerLib) {
51
- throw new Error(`Treesiter for ${grammar} is not configured`);
60
+ await this.ensureParserInit();
61
+ let lang = this.LANG_BY_GRAMMAR[grammar];
62
+ if (!lang) {
63
+ const wasmPath = await ensureGrammar(grammar, {
64
+ logger: this.logger,
65
+ showProgressBar: this.showProgressBar,
66
+ });
67
+ lang = await Language.load(wasmPath);
68
+ this.LANG_BY_GRAMMAR[grammar] = lang;
52
69
  }
53
- const [{ default: Parser }, libModule] = await Promise.all([
54
- import("tree-sitter"),
55
- import(gramerLib.lib),
56
- ]);
57
- // The markdown npm package exposes sub-grammars via "module.exports":
58
- // { default: ..., "module.exports": { name, language, inline, nodeTypeInfo } }
59
- let grammarModule = libModule.default;
60
- if (gramerLib.module) {
61
- const moduleExports = libModule["module.exports"];
62
- grammarModule = moduleExports?.[gramerLib.module];
63
- }
64
- if (!grammarModule) {
65
- throw new Error(`Invalid tree-sitter grammar: "${gramerLib.module}" not found in ${gramerLib.lib}`);
66
- }
67
- this.LANG_BY_GRAMMAR[grammar] = grammarModule;
68
70
  const parser = new Parser();
69
- parser.setLanguage(grammarModule);
71
+ parser.setLanguage(lang);
70
72
  this.PARSER_BY_GRAMMAR[grammar] = parser;
71
73
  return parser;
72
74
  }
@@ -79,9 +81,8 @@ export class TreesitterClient {
79
81
  return this.QUERY_CACHE.get(cacheKey);
80
82
  }
81
83
  await this.getParser(grammar); // ensures LANG_BY_GRAMMAR[grammar] is populated
82
- const { default: Parser } = await import("tree-sitter");
83
84
  const lang = this.LANG_BY_GRAMMAR[grammar];
84
- const query = new Parser.Query(lang, queryString);
85
+ const query = new Query(lang, queryString);
85
86
  this.QUERY_CACHE.set(cacheKey, query);
86
87
  return query;
87
88
  }
@@ -104,6 +105,9 @@ export class TreesitterClient {
104
105
  }
105
106
  const parser = await this.getParser(grammar);
106
107
  const tree = parser.parse(content);
108
+ if (!tree) {
109
+ throw new Error(`Failed to parse ${grammar} content`);
110
+ }
107
111
  const hash = this.hashContent(content);
108
112
  const bucket = treeCacheByLen.get(len) ?? new Map();
109
113
  bucket.set(hash, tree);
@@ -111,10 +115,10 @@ export class TreesitterClient {
111
115
  return tree;
112
116
  }
113
117
  getTreeCache(grammar) {
114
- if (!this.ROOT_NODE_CACHE_BY_GRAMMAR[grammar]) {
115
- this.ROOT_NODE_CACHE_BY_GRAMMAR[grammar] = new Map();
118
+ if (!this.ROOT_NODE_CACHE_BY_CONTENT[grammar]) {
119
+ this.ROOT_NODE_CACHE_BY_CONTENT[grammar] = new Map();
116
120
  }
117
- return this.ROOT_NODE_CACHE_BY_GRAMMAR[grammar];
121
+ return this.ROOT_NODE_CACHE_BY_CONTENT[grammar];
118
122
  }
119
123
  hashContent(content) {
120
124
  // FNV-1a 32-bit (fast, non-cryptographic)
@@ -0,0 +1,73 @@
1
+ import type { AnalyzerLogger } from "../types.js";
2
+ export type GrammarSpec = {
3
+ /** Local filename used in the cache directory. */
4
+ filename: string;
5
+ /** Exact, version-pinned URL to download the grammar .wasm from. */
6
+ url: string;
7
+ };
8
+ /**
9
+ * Grammar specifications. All URLs are exact version-pinned to ensure
10
+ * ABI compatibility with web-tree-sitter@0.25.4.
11
+ *
12
+ * Grammar .wasm files are compiled by the tree-sitter CLI against a specific
13
+ * WASM ABI. Mixing grammar versions with a different web-tree-sitter version
14
+ * causes silent parse failures, so both must be pinned together.
15
+ */
16
+ export declare const GRAMMAR_SPECS: {
17
+ bash: {
18
+ filename: string;
19
+ url: string;
20
+ };
21
+ javascript: {
22
+ filename: string;
23
+ url: string;
24
+ };
25
+ python: {
26
+ filename: string;
27
+ url: string;
28
+ };
29
+ typescript: {
30
+ filename: string;
31
+ url: string;
32
+ };
33
+ tsx: {
34
+ filename: string;
35
+ url: string;
36
+ };
37
+ markdown: {
38
+ filename: string;
39
+ url: string;
40
+ };
41
+ "markdown-inline": {
42
+ filename: string;
43
+ url: string;
44
+ };
45
+ };
46
+ /** Available languages for tree-sitter grammars. */
47
+ export type TreesitterGrammar = keyof typeof GRAMMAR_SPECS;
48
+ /**
49
+ * Returns the skill-lab cache directory, following XDG conventions.
50
+ *
51
+ * Priority:
52
+ * 1. $SKILL_LAB_CACHE_DIR — explicit override
53
+ * 2. $XDG_CACHE_HOME/skill-lab — if XDG_CACHE_HOME is set
54
+ * 3. Platform default:
55
+ * Linux/macOS: ~/.cache/skill-lab
56
+ * Windows: %LOCALAPPDATA%\skill-lab\Cache
57
+ */
58
+ export declare function getCacheDir(): string;
59
+ /**
60
+ * Ensures a grammar .wasm file is present in the local cache.
61
+ *
62
+ * On first call for a given language, downloads the file from the pinned URL
63
+ * in GRAMMAR_SPECS. Subsequent calls return immediately from cache.
64
+ *
65
+ * @param lang - Language key (e.g. "bash", "typescript", "markdown-inline")
66
+ * @param opts.logger - Optional logger for download events
67
+ * @returns Absolute path to the cached .wasm file
68
+ */
69
+ export declare function ensureGrammar(lang: string, opts?: {
70
+ logger?: AnalyzerLogger;
71
+ showProgressBar?: boolean;
72
+ }): Promise<string>;
73
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/analyzer/treesitter/registry.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAOlD,MAAM,MAAM,WAAW,GAAG;IACtB,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6Ba,CAAC;AAExC,oDAAoD;AACpD,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,aAAa,CAAC;AAE3D;;;;;;;;;GASG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAgBpC;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B,GACF,OAAO,CAAC,MAAM,CAAC,CAgFjB"}