@feiyoug/skill-lab 0.0.0 → 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 +73 -0
  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
@@ -0,0 +1,120 @@
1
+ import { Language, Parser, Query, Tree } from "web-tree-sitter";
2
+ import { ensureGrammar } from "./registry.js";
3
+ import type { TreesitterGrammar } from "./registry.js";
4
+ import type { AnalyzerLogger } from "../types.js";
5
+ import { NO_OP_LOGGER } from "../logging.js";
6
+
7
+ export class TreesitterClient {
8
+ private PARSER_BY_GRAMMAR: Partial<Record<TreesitterGrammar, Parser>> = {};
9
+ private LANG_BY_GRAMMAR: Partial<Record<TreesitterGrammar, Language>> = {};
10
+ private QUERY_CACHE = new Map<string, Query>();
11
+ private ROOT_NODE_CACHE_BY_CONTENT: Partial<
12
+ // cache by length then hash
13
+ Record<TreesitterGrammar, Map<number, Map<number, Tree>>>
14
+ > = {};
15
+ /** Parser.init() is idempotent but we avoid re-calling it. */
16
+ private parserInitialized: boolean = false;
17
+
18
+ constructor(
19
+ private readonly logger: AnalyzerLogger = NO_OP_LOGGER,
20
+ private readonly showProgressBar: boolean = false,
21
+ ) {}
22
+
23
+ private async ensureParserInit() {
24
+ if (this.parserInitialized) return;
25
+
26
+ await Parser.init();
27
+ this.parserInitialized = true;
28
+ }
29
+
30
+ public async getParser(grammar: TreesitterGrammar): Promise<Parser> {
31
+ if (this.PARSER_BY_GRAMMAR[grammar]) {
32
+ return this.PARSER_BY_GRAMMAR[grammar]!;
33
+ }
34
+
35
+ await this.ensureParserInit();
36
+
37
+ let lang = this.LANG_BY_GRAMMAR[grammar];
38
+ if (!lang) {
39
+ const wasmPath = await ensureGrammar(grammar, {
40
+ logger: this.logger,
41
+ showProgressBar: this.showProgressBar,
42
+ });
43
+ lang = await Language.load(wasmPath);
44
+ this.LANG_BY_GRAMMAR[grammar] = lang;
45
+ }
46
+
47
+ const parser = new Parser();
48
+ parser.setLanguage(lang);
49
+
50
+ this.PARSER_BY_GRAMMAR[grammar] = parser;
51
+ return parser;
52
+ }
53
+
54
+ /**
55
+ * Creates (and caches) a tree-sitter Query for the given grammar and S-expression query string.
56
+ */
57
+ public async createQuery(grammar: TreesitterGrammar, queryString: string): Promise<Query> {
58
+ const cacheKey = `${grammar}:${queryString}`;
59
+ if (this.QUERY_CACHE.has(cacheKey)) {
60
+ return this.QUERY_CACHE.get(cacheKey)!;
61
+ }
62
+
63
+ await this.getParser(grammar); // ensures LANG_BY_GRAMMAR[grammar] is populated
64
+ const lang = this.LANG_BY_GRAMMAR[grammar]!;
65
+ const query = new Query(lang, queryString);
66
+ this.QUERY_CACHE.set(cacheKey, query);
67
+ return query;
68
+ }
69
+
70
+ /**
71
+ * Parses content into a tree-sitter Tree with memoization.
72
+ *
73
+ * Cache key strategy:
74
+ * - first level: content length
75
+ * - second level: fast non-cryptographic hash of content
76
+ */
77
+ public async parse(grammar: TreesitterGrammar, content: string): Promise<Tree> {
78
+ const treeCacheByLen = this.getTreeCache(grammar);
79
+ const len = content.length;
80
+ const treeCacheByHash = treeCacheByLen.get(len);
81
+ if (treeCacheByHash) {
82
+ const hash = this.hashContent(content);
83
+ const cached = treeCacheByHash.get(hash);
84
+ if (cached) return cached;
85
+ }
86
+
87
+ const parser = await this.getParser(grammar);
88
+ const tree = parser.parse(content);
89
+ if (!tree) {
90
+ throw new Error(`Failed to parse ${grammar} content`);
91
+ }
92
+
93
+ const hash = this.hashContent(content);
94
+ const bucket = treeCacheByLen.get(len) ?? new Map<number, Tree>();
95
+ bucket.set(hash, tree);
96
+ treeCacheByLen.set(len, bucket);
97
+
98
+ return tree;
99
+ }
100
+
101
+ private getTreeCache(grammar: TreesitterGrammar): Map<number, Map<number, Tree>> {
102
+ if (!this.ROOT_NODE_CACHE_BY_CONTENT[grammar]) {
103
+ this.ROOT_NODE_CACHE_BY_CONTENT[grammar] = new Map<
104
+ number,
105
+ Map<number, Tree>
106
+ >();
107
+ }
108
+ return this.ROOT_NODE_CACHE_BY_CONTENT[grammar]!;
109
+ }
110
+
111
+ private hashContent(content: string): number {
112
+ // FNV-1a 32-bit (fast, non-cryptographic)
113
+ let hash = 0x811c9dc5;
114
+ for (let i = 0; i < content.length; i++) {
115
+ hash ^= content.charCodeAt(i);
116
+ hash = Math.imul(hash, 0x01000193);
117
+ }
118
+ return hash >>> 0;
119
+ }
120
+ }
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Shared grammar registry for web-tree-sitter WASM grammars.
3
+ *
4
+ * Used by both AstGrepClient and TreesitterClient. Grammar .wasm files are
5
+ * downloaded from GitHub Releases on first use and cached locally following
6
+ * the XDG cache directory convention.
7
+ *
8
+ * Cache location (in priority order):
9
+ * 1. $SKILL_LAB_CACHE_DIR
10
+ * 2. $XDG_CACHE_HOME/skill-lab
11
+ * 3. ~/.cache/skill-lab (Linux/macOS)
12
+ * %LOCALAPPDATA%\skill-lab\Cache (Windows)
13
+ */
14
+ import * as dntShim from "../../_dnt.shims.js";
15
+
16
+
17
+ import { join } from "../../deps/jsr.io/@std/path/1.1.4/mod.js";
18
+ import type { AnalyzerLogger } from "../types.js";
19
+ import ProgressBar from "../../deps/jsr.io/@deno-library/progress/1.5.1/mod.js";
20
+
21
+ const TREESITTER_GRAMMER_SUBDIR = "treesitter/grammars";
22
+ const ANSI_CLEAR_LINE = "\r\x1b[K";
23
+ const ENCODER = new TextEncoder();
24
+
25
+ export type GrammarSpec = {
26
+ /** Local filename used in the cache directory. */
27
+ filename: string;
28
+ /** Exact, version-pinned URL to download the grammar .wasm from. */
29
+ url: string;
30
+ };
31
+
32
+ /**
33
+ * Grammar specifications. All URLs are exact version-pinned to ensure
34
+ * ABI compatibility with web-tree-sitter@0.25.4.
35
+ *
36
+ * Grammar .wasm files are compiled by the tree-sitter CLI against a specific
37
+ * WASM ABI. Mixing grammar versions with a different web-tree-sitter version
38
+ * causes silent parse failures, so both must be pinned together.
39
+ */
40
+ export const GRAMMAR_SPECS = {
41
+ bash: {
42
+ filename: "bash.wasm",
43
+ url: "https://github.com/tree-sitter/tree-sitter-bash/releases/download/v0.25.1/tree-sitter-bash.wasm",
44
+ },
45
+ javascript: {
46
+ filename: "javascript.wasm",
47
+ url: "https://github.com/tree-sitter/tree-sitter-javascript/releases/download/v0.25.0/tree-sitter-javascript.wasm",
48
+ },
49
+ python: {
50
+ filename: "python.wasm",
51
+ url: "https://github.com/tree-sitter/tree-sitter-python/releases/download/v0.25.0/tree-sitter-python.wasm",
52
+ },
53
+ typescript: {
54
+ filename: "typescript.wasm",
55
+ url: "https://github.com/tree-sitter/tree-sitter-typescript/releases/download/v0.23.2/tree-sitter-typescript.wasm",
56
+ },
57
+ tsx: {
58
+ filename: "tsx.wasm",
59
+ url: "https://github.com/tree-sitter/tree-sitter-typescript/releases/download/v0.23.2/tree-sitter-tsx.wasm",
60
+ },
61
+ markdown: {
62
+ filename: "markdown.wasm",
63
+ url: "https://github.com/tree-sitter-grammars/tree-sitter-markdown/releases/download/v0.5.2/tree-sitter-markdown.wasm",
64
+ },
65
+ "markdown-inline": {
66
+ filename: "markdown_inline.wasm",
67
+ url: "https://github.com/tree-sitter-grammars/tree-sitter-markdown/releases/download/v0.5.2/tree-sitter-markdown_inline.wasm",
68
+ },
69
+ } satisfies Record<string, GrammarSpec>;
70
+
71
+ /** Available languages for tree-sitter grammars. */
72
+ export type TreesitterGrammar = keyof typeof GRAMMAR_SPECS;
73
+
74
+ /**
75
+ * Returns the skill-lab cache directory, following XDG conventions.
76
+ *
77
+ * Priority:
78
+ * 1. $SKILL_LAB_CACHE_DIR — explicit override
79
+ * 2. $XDG_CACHE_HOME/skill-lab — if XDG_CACHE_HOME is set
80
+ * 3. Platform default:
81
+ * Linux/macOS: ~/.cache/skill-lab
82
+ * Windows: %LOCALAPPDATA%\skill-lab\Cache
83
+ */
84
+ export function getCacheDir(): string {
85
+ const explicit = dntShim.Deno.env.get("SKILL_LAB_CACHE_DIR");
86
+ if (explicit) return explicit;
87
+
88
+ const xdgCache = dntShim.Deno.env.get("XDG_CACHE_HOME");
89
+ if (xdgCache) return join(xdgCache, "skill-lab");
90
+
91
+ if (dntShim.Deno.build.os === "windows") {
92
+ const localAppData = dntShim.Deno.env.get("LOCALAPPDATA");
93
+ if (localAppData) return join(localAppData, "skill-lab", "Cache");
94
+ const userProfile = dntShim.Deno.env.get("USERPROFILE") ?? "~";
95
+ return join(userProfile, "AppData", "Local", "skill-lab", "Cache");
96
+ }
97
+
98
+ const home = dntShim.Deno.env.get("HOME") ?? "~";
99
+ return join(home, ".cache", "skill-lab");
100
+ }
101
+
102
+ /**
103
+ * Ensures a grammar .wasm file is present in the local cache.
104
+ *
105
+ * On first call for a given language, downloads the file from the pinned URL
106
+ * in GRAMMAR_SPECS. Subsequent calls return immediately from cache.
107
+ *
108
+ * @param lang - Language key (e.g. "bash", "typescript", "markdown-inline")
109
+ * @param opts.logger - Optional logger for download events
110
+ * @returns Absolute path to the cached .wasm file
111
+ */
112
+ export async function ensureGrammar(
113
+ lang: string,
114
+ opts?: {
115
+ logger?: AnalyzerLogger;
116
+ showProgressBar?: boolean;
117
+ },
118
+ ): Promise<string> {
119
+ if (!(lang in GRAMMAR_SPECS)) {
120
+ throw new Error(
121
+ `No grammar spec for language: "${lang}". Available: ${
122
+ Object.keys(GRAMMAR_SPECS).join(", ")
123
+ }`,
124
+ );
125
+ }
126
+ const spec = GRAMMAR_SPECS[lang as TreesitterGrammar];
127
+
128
+ const cacheDir = join(getCacheDir(), TREESITTER_GRAMMER_SUBDIR);
129
+ const cachedPath = join(cacheDir, spec.filename);
130
+
131
+ // Return immediately if already cached
132
+ try {
133
+ const stat = await dntShim.Deno.stat(cachedPath);
134
+ if (stat.isFile) return cachedPath;
135
+ } catch {
136
+ // Not cached yet — fall through to download
137
+ }
138
+
139
+ // Download and write to cache
140
+ await dntShim.Deno.mkdir(cacheDir, { recursive: true });
141
+ if (dntShim.Deno.stderr.isTerminal()) {
142
+ dntShim.Deno.stderr.writeSync(ENCODER.encode(ANSI_CLEAR_LINE));
143
+ }
144
+
145
+ const resp = await fetch(spec.url);
146
+ if (!resp.ok) {
147
+ throw new Error(
148
+ `Failed to download grammar ${spec.filename}: HTTP ${resp.status} from ${spec.url}`,
149
+ );
150
+ }
151
+
152
+ const shouldRenderProgress = (opts?.showProgressBar ?? false) && dntShim.Deno.stdout.isTerminal();
153
+ const contentLenHeader = resp.headers.get("content-length")!;
154
+ const contentLen = parseInt(contentLenHeader);
155
+ const scanBar = shouldRenderProgress
156
+ ? new ProgressBar({
157
+ total: contentLen,
158
+ clear: true,
159
+ output: dntShim.Deno.stderr,
160
+ complete: "=",
161
+ incomplete: "-",
162
+ display: `Installing ${lang} grammar [:bar] :percent ETA :eta`,
163
+ })
164
+ : null;
165
+
166
+ let bytes: Uint8Array;
167
+ try {
168
+ if (!resp.body) {
169
+ bytes = new Uint8Array(await resp.arrayBuffer());
170
+ } else {
171
+ const reader = resp.body.getReader();
172
+ const chunks: Uint8Array[] = [];
173
+ let received = 0;
174
+
175
+ while (true) {
176
+ const { value, done } = await reader.read();
177
+ if (done) break;
178
+ if (!value) continue;
179
+
180
+ chunks.push(value);
181
+ received += value.byteLength;
182
+ scanBar?.render(received);
183
+ }
184
+
185
+ bytes = new Uint8Array(received);
186
+ let offset = 0;
187
+ for (const chunk of chunks) {
188
+ bytes.set(chunk, offset);
189
+ offset += chunk.byteLength;
190
+ }
191
+ }
192
+ } finally {
193
+ scanBar?.end();
194
+ }
195
+ await dntShim.Deno.writeFile(cachedPath, bytes);
196
+
197
+ return cachedPath;
198
+ }
@@ -0,0 +1,78 @@
1
+ import type { SkillFile, SkillReader } from "../skillreader/mod.js";
2
+ import type {
3
+ FileRefDiscoveryMethod,
4
+ FileReference,
5
+ FileType,
6
+ Finding,
7
+ Frontmatter,
8
+ Permission,
9
+ Reference,
10
+ ReferenceType,
11
+ Risk,
12
+ } from "../shared/mod.js";
13
+ import { AstGrepClient } from "./astgrep/client.js";
14
+ import { TreesitterClient } from "./treesitter/client.js";
15
+ import type { AnalyzerConfig, ScanConfig } from "./config/mod.js";
16
+ export type { AnalyzerConfig, ScanConfig };
17
+
18
+ export type AnalyzerLogger = {
19
+ debug: (template: string, props?: Record<string, unknown>) => void;
20
+ info: (template: string, props?: Record<string, unknown>) => void;
21
+ warn: (template: string, props?: Record<string, unknown>) => void;
22
+ error: (template: string, props?: Record<string, unknown>) => void;
23
+ };
24
+
25
+ export type AnalyzerState = {
26
+ skillId: string;
27
+ skillVersionId: string;
28
+ files: SkillFile[];
29
+ frontmatter: Frontmatter;
30
+ scanQueue: FileReference[];
31
+ permissions: Permission[];
32
+ findings: Finding[];
33
+ risks: Risk[];
34
+ warnings: string[];
35
+ metadata: {
36
+ scannedFiles: Set<string>;
37
+ skippedFiles: Array<{ path: string; reason: string; referenceBy?: Reference }>;
38
+ rulesUsed: string[];
39
+ config: ScanConfig;
40
+ };
41
+ };
42
+
43
+ export type AnalyzerContext = {
44
+ skillReader: SkillReader;
45
+ treesitterClient: TreesitterClient;
46
+ astgrepClient: AstGrepClient;
47
+ logger?: AnalyzerLogger;
48
+ showProgressBar?: boolean;
49
+ /** Resolved (defaults-merged) user config. */
50
+ config: AnalyzerConfig;
51
+ };
52
+
53
+ /** A file path or package reference discovered in source content. */
54
+ export type FileRefDiscovery = {
55
+ path: string;
56
+ line: number;
57
+ via: FileRefDiscoveryMethod;
58
+ };
59
+
60
+ export type CodeBlock = {
61
+ language: FileType;
62
+ content: string;
63
+ startLine: number;
64
+ endLine: number;
65
+ type: ReferenceType;
66
+ };
67
+
68
+ export type FileTypeConfig = {
69
+ extractCodeBlocks?: (
70
+ context: AnalyzerContext,
71
+ content: string,
72
+ ) => Promise<CodeBlock[]>;
73
+ extractFileRefs?: (
74
+ context: AnalyzerContext,
75
+ content: string,
76
+ ) => FileRefDiscovery[] | Promise<FileRefDiscovery[]>;
77
+ defaultLanguage: FileType | null;
78
+ };
@@ -0,0 +1,33 @@
1
+ export type DecodedCodeBlockPath = {
2
+ parentPath: string;
3
+ startLine: number;
4
+ endLine: number;
5
+ };
6
+
7
+ export function encodeCodeBlockPath(
8
+ parentPath: string,
9
+ startLine: number,
10
+ endLine: number,
11
+ ): string {
12
+ return `${parentPath}:${startLine}-${endLine}`;
13
+ }
14
+
15
+ export function decodeCodeBlockPath(path: string): DecodedCodeBlockPath | null {
16
+ const match = path.match(/^(.+):(\d+)-(\d+)$/);
17
+ if (!match) return null;
18
+
19
+ const startLine = Number(match[2]);
20
+ const endLine = Number(match[3]);
21
+ if (!Number.isFinite(startLine) || !Number.isFinite(endLine)) return null;
22
+ if (startLine <= 0 || endLine < startLine) return null;
23
+
24
+ return {
25
+ parentPath: match[1],
26
+ startLine,
27
+ endLine,
28
+ };
29
+ }
30
+
31
+ export function isCodeBlockPath(path: string): boolean {
32
+ return decodeCodeBlockPath(path) !== null;
33
+ }
@@ -0,0 +1,59 @@
1
+ export function generatePermissionId(
2
+ tool: string,
3
+ args: string[] = ["*"],
4
+ metadata?: Record<string, unknown>,
5
+ ): string {
6
+ const normalizedArgs = args.length > 0 ? args : ["*"];
7
+ const base = sanitize(`${tool}-${normalizedArgs.join("-")}`);
8
+ const normalizedMetadata = filterMetadataForHash(metadata ?? {});
9
+
10
+ const shouldHash = normalizedArgs.length > 1 || Object.keys(normalizedMetadata).length > 0;
11
+ if (!shouldHash) return base;
12
+
13
+ const hashInput = stableStringify({ args: normalizedArgs, metadata: normalizedMetadata });
14
+ return `${base}-${shortHash(hashInput)}`;
15
+ }
16
+
17
+ export function generateRiskId(type: string, index: number): string {
18
+ return sanitize(`risk-${type}-${index + 1}`);
19
+ }
20
+
21
+ function sanitize(value: string): string {
22
+ return value
23
+ .toLowerCase()
24
+ .replace(/[^a-z0-9.*-]+/g, "-")
25
+ .replace(/-+/g, "-")
26
+ .replace(/^-|-$/g, "");
27
+ }
28
+
29
+ function filterMetadataForHash(metadata: Record<string, unknown>): Record<string, unknown> {
30
+ const result: Record<string, unknown> = {};
31
+ for (const [key, value] of Object.entries(metadata)) {
32
+ if (key === "pattern") continue;
33
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
34
+ result[key] = value;
35
+ }
36
+ }
37
+ return result;
38
+ }
39
+
40
+ function stableStringify(value: unknown): string {
41
+ if (Array.isArray(value)) {
42
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
43
+ }
44
+ if (value && typeof value === "object") {
45
+ const entries = Object.entries(value as Record<string, unknown>)
46
+ .sort(([a], [b]) => a.localeCompare(b))
47
+ .map(([key, item]) => `${key}:${stableStringify(item)}`);
48
+ return `{${entries.join(",")}}`;
49
+ }
50
+ return JSON.stringify(value);
51
+ }
52
+
53
+ function shortHash(input: string): string {
54
+ let hash = 0;
55
+ for (let i = 0; i < input.length; i += 1) {
56
+ hash = (hash * 31 + input.charCodeAt(i)) | 0;
57
+ }
58
+ return Math.abs(hash).toString(36).padStart(6, "0").slice(0, 6);
59
+ }
@@ -0,0 +1,29 @@
1
+ const SECRET_KEYWORDS = [
2
+ "token",
3
+ "key",
4
+ "secret",
5
+ "password",
6
+ "pwd",
7
+ "pass",
8
+ "credential",
9
+ "cred",
10
+ "auth",
11
+ "api",
12
+ "apikey",
13
+ "bearer",
14
+ "oauth",
15
+ "jwt",
16
+ "session",
17
+ "private",
18
+ ];
19
+
20
+ export function isSecretLikeName(value: unknown): boolean {
21
+ if (typeof value !== "string") return false;
22
+ const normalized = value.toLowerCase();
23
+ return SECRET_KEYWORDS.some((keyword) => normalized.includes(keyword));
24
+ }
25
+
26
+ export function normalizeKeyCandidate(value: unknown): string {
27
+ if (typeof value !== "string") return "";
28
+ return value.replace(/[;,)]+$/, "").trim();
29
+ }
@@ -0,0 +1,25 @@
1
+ export function parseUrlFromUnknown(
2
+ input: string,
3
+ ): { host: string; protocol: string; raw: string } | null {
4
+ if (!input) return null;
5
+ const cleaned = input.trim().replace(/^['"`]|['"`]$/g, "");
6
+ const withProtocol = /^https?:\/\//i.test(cleaned) ? cleaned : `https://${cleaned}`;
7
+
8
+ try {
9
+ const url = new URL(withProtocol);
10
+ return {
11
+ host: url.hostname,
12
+ protocol: url.protocol.replace(":", ""),
13
+ raw: cleaned,
14
+ };
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+
20
+ export function classifyDestination(host: string): "loopback" | "internal" | "external" {
21
+ if (["localhost", "127.0.0.1", "::1"].includes(host)) return "loopback";
22
+ if (host.endsWith(".local")) return "internal";
23
+ if (/^10\.|^192\.168\.|^172\.(1[6-9]|2[0-9]|3[01])\./.test(host)) return "internal";
24
+ return "external";
25
+ }
@@ -0,0 +1,3 @@
1
+ export { bgGreen, bgWhite, stripAnsiCode } from "../../../@std/fmt/1.0.3/colors.js";
2
+ export { writeAll } from "../../../@std/io/0.225.0/write_all.js";
3
+ // export type { Writer } from "jsr:@std/io@0.225.0/types";