@js-recon/js-recon 1.3.2 → 1.4.1-alpha.9

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 (236) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.github/workflows/build-and-prettify.yaml +205 -14
  3. package/.github/workflows/pr_checker.yml +2 -2
  4. package/.github/workflows/promote-js-recon.yml +104 -0
  5. package/.github/workflows/publish-js-recon.yml +22 -80
  6. package/.github/workflows/rules-smoke-test.yaml +79 -0
  7. package/CHANGELOG.md +171 -4
  8. package/CLAUDE.md +350 -16
  9. package/Dockerfile.release +29 -0
  10. package/README.md +48 -19
  11. package/build/analyze/engine/csMastSEngine.js +129 -0
  12. package/build/analyze/engine/csMastSEngine.js.map +1 -0
  13. package/build/analyze/engine/index.js +15 -0
  14. package/build/analyze/engine/index.js.map +1 -1
  15. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js +2 -1
  16. package/build/analyze/helpers/engineHelpers/findDirectAssignment.js.map +1 -1
  17. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js +2 -1
  18. package/build/analyze/helpers/engineHelpers/findMemberExpressionAssignment.js.map +1 -1
  19. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js +2 -1
  20. package/build/analyze/helpers/engineHelpers/resolveFunctionIdentifier.js.map +1 -1
  21. package/build/analyze/helpers/engineHelpers/taintFlow.js +11 -2
  22. package/build/analyze/helpers/engineHelpers/taintFlow.js.map +1 -1
  23. package/build/analyze/helpers/initRules.js +1 -1
  24. package/build/analyze/helpers/initRules.js.map +1 -1
  25. package/build/analyze/helpers/schemas.js +6 -2
  26. package/build/analyze/helpers/schemas.js.map +1 -1
  27. package/build/analyze/helpers/validate.js +3 -3
  28. package/build/analyze/helpers/validate.js.map +1 -1
  29. package/build/analyze/index.js +1 -0
  30. package/build/analyze/index.js.map +1 -1
  31. package/build/completion/index.js +432 -0
  32. package/build/completion/index.js.map +1 -0
  33. package/build/cs_mast/index.js +213 -0
  34. package/build/cs_mast/index.js.map +1 -0
  35. package/build/endpoints/next_js/client_jsFilesHref.js +2 -1
  36. package/build/endpoints/next_js/client_jsFilesHref.js.map +1 -1
  37. package/build/endpoints/next_js/client_jsonParse.js +2 -1
  38. package/build/endpoints/next_js/client_jsonParse.js.map +1 -1
  39. package/build/endpoints/next_js/client_mappedJsonFile.js +2 -1
  40. package/build/endpoints/next_js/client_mappedJsonFile.js.map +1 -1
  41. package/build/endpoints/next_js/client_subsequentRequests.js +2 -1
  42. package/build/endpoints/next_js/client_subsequentRequests.js.map +1 -1
  43. package/build/fingerprint/index.js +56 -33
  44. package/build/fingerprint/index.js.map +1 -1
  45. package/build/globalConfig.js +3 -3
  46. package/build/globalConfig.js.map +1 -1
  47. package/build/index.js +210 -10
  48. package/build/index.js.map +1 -1
  49. package/build/lazyLoad/angular/angular_getFromMainJs.js +2 -1
  50. package/build/lazyLoad/angular/angular_getFromMainJs.js.map +1 -1
  51. package/build/lazyLoad/downloadFilesUtil.js +6 -5
  52. package/build/lazyLoad/downloadFilesUtil.js.map +1 -1
  53. package/build/lazyLoad/downloadLoadedJsUtil.js +59 -5
  54. package/build/lazyLoad/downloadLoadedJsUtil.js.map +1 -1
  55. package/build/lazyLoad/downloadQueue.js +10 -9
  56. package/build/lazyLoad/downloadQueue.js.map +1 -1
  57. package/build/lazyLoad/index.js +127 -85
  58. package/build/lazyLoad/index.js.map +1 -1
  59. package/build/lazyLoad/methodFilter.js +50 -0
  60. package/build/lazyLoad/methodFilter.js.map +1 -0
  61. package/build/lazyLoad/next_js/NextJsCrawler.js +69 -48
  62. package/build/lazyLoad/next_js/NextJsCrawler.js.map +1 -1
  63. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js +36 -34
  64. package/build/lazyLoad/next_js/next_GetLazyResourcesBuildManifestJs.js.map +1 -1
  65. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js +66 -13
  66. package/build/lazyLoad/next_js/next_GetLazyResourcesWebpackJs.js.map +1 -1
  67. package/build/lazyLoad/next_js/next_parseLayoutJs.js +80 -68
  68. package/build/lazyLoad/next_js/next_parseLayoutJs.js.map +1 -1
  69. package/build/lazyLoad/next_js/next_promiseResolve.js +22 -16
  70. package/build/lazyLoad/next_js/next_promiseResolve.js.map +1 -1
  71. package/build/lazyLoad/nuxt_js/nuxt_astParse.js +49 -47
  72. package/build/lazyLoad/nuxt_js/nuxt_astParse.js.map +1 -1
  73. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js +64 -0
  74. package/build/lazyLoad/nuxt_js/nuxt_getBuildsManifest.js.map +1 -0
  75. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js +3 -1
  76. package/build/lazyLoad/nuxt_js/nuxt_getFromPageSource.js.map +1 -1
  77. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js +3 -2
  78. package/build/lazyLoad/nuxt_js/nuxt_stringAnalysisJSFiles.js.map +1 -1
  79. package/build/lazyLoad/react/react_followImports.js +16 -7
  80. package/build/lazyLoad/react/react_followImports.js.map +1 -1
  81. package/build/lazyLoad/react/react_webpackChunkPaths.js +175 -123
  82. package/build/lazyLoad/react/react_webpackChunkPaths.js.map +1 -1
  83. package/build/lazyLoad/svelte/svelte_getFromPageSource.js +16 -0
  84. package/build/lazyLoad/svelte/svelte_getFromPageSource.js.map +1 -1
  85. package/build/lazyLoad/svelte/svelte_getVersionJson.js +40 -0
  86. package/build/lazyLoad/svelte/svelte_getVersionJson.js.map +1 -0
  87. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js +3 -2
  88. package/build/lazyLoad/svelte/svelte_stringAnalysisJSFiles.js.map +1 -1
  89. package/build/lazyLoad/techDetect/checkAngularJS.js +27 -6
  90. package/build/lazyLoad/techDetect/checkAngularJS.js.map +1 -1
  91. package/build/lazyLoad/techDetect/checkNextJS.js +24 -15
  92. package/build/lazyLoad/techDetect/checkNextJS.js.map +1 -1
  93. package/build/lazyLoad/techDetect/checkReact.js +8 -0
  94. package/build/lazyLoad/techDetect/checkReact.js.map +1 -1
  95. package/build/lazyLoad/techDetect/checkSvelte.js +17 -0
  96. package/build/lazyLoad/techDetect/checkSvelte.js.map +1 -1
  97. package/build/lazyLoad/techDetect/index.js +33 -5
  98. package/build/lazyLoad/techDetect/index.js.map +1 -1
  99. package/build/lazyLoad/vue/vue_RuntimeJs.js +2 -1
  100. package/build/lazyLoad/vue/vue_RuntimeJs.js.map +1 -1
  101. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js +2 -1
  102. package/build/lazyLoad/vue/vue_SingleJsFileOnHome.js.map +1 -1
  103. package/build/lazyLoad/vue/vue_discoverJsFiles.js +59 -25
  104. package/build/lazyLoad/vue/vue_discoverJsFiles.js.map +1 -1
  105. package/build/lazyLoad/vue/vue_getClientSidePaths.js +2 -1
  106. package/build/lazyLoad/vue/vue_getClientSidePaths.js.map +1 -1
  107. package/build/lazyLoad/vue/vue_jsImports.js +2 -1
  108. package/build/lazyLoad/vue/vue_jsImports.js.map +1 -1
  109. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js +2 -2
  110. package/build/lazyLoad/vue/vue_recursiveClientSidePathDownload.js.map +1 -1
  111. package/build/lazyLoad/vue/vue_viteMapDeps.js +62 -54
  112. package/build/lazyLoad/vue/vue_viteMapDeps.js.map +1 -1
  113. package/build/map/angular_js/getAngularConnections.js +88 -0
  114. package/build/map/angular_js/getAngularConnections.js.map +1 -0
  115. package/build/map/angular_js/interactive.js +4 -0
  116. package/build/map/angular_js/interactive.js.map +1 -0
  117. package/build/map/graphql/resolveGraphql.js +2 -1
  118. package/build/map/graphql/resolveGraphql.js.map +1 -1
  119. package/build/map/index.js +38 -0
  120. package/build/map/index.js.map +1 -1
  121. package/build/map/next_js/getExports.js +2 -1
  122. package/build/map/next_js/getExports.js.map +1 -1
  123. package/build/map/next_js/getFetchInstances.js +2 -1
  124. package/build/map/next_js/getFetchInstances.js.map +1 -1
  125. package/build/map/next_js/getTurbopackConnections.js +2 -1
  126. package/build/map/next_js/getTurbopackConnections.js.map +1 -1
  127. package/build/map/next_js/getWebpackConnections.js +2 -1
  128. package/build/map/next_js/getWebpackConnections.js.map +1 -1
  129. package/build/map/next_js/resolveAxios.js +2 -1
  130. package/build/map/next_js/resolveAxios.js.map +1 -1
  131. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js +2 -1
  132. package/build/map/next_js/resolveAxiosHelpers/directCallsWithoutAssignment.js.map +1 -1
  133. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js +2 -1
  134. package/build/map/next_js/resolveAxiosHelpers/findAxiosInstance.js.map +1 -1
  135. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js +2 -1
  136. package/build/map/next_js/resolveAxiosHelpers/findCrossChunkParams.js.map +1 -1
  137. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js +2 -1
  138. package/build/map/next_js/resolveAxiosHelpers/handleAxiosCreate.js.map +1 -1
  139. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js +2 -1
  140. package/build/map/next_js/resolveAxiosHelpers/handleZDotCreate.js.map +1 -1
  141. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js +2 -1
  142. package/build/map/next_js/resolveAxiosHelpers/interceptorHeaders.js.map +1 -1
  143. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js +2 -1
  144. package/build/map/next_js/resolveAxiosHelpers/processExportedEndpoints.js.map +1 -1
  145. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js +2 -1
  146. package/build/map/next_js/resolveAxiosHelpers/traceAxiosInstanceExports.js.map +1 -1
  147. package/build/map/next_js/resolveAxiosHelpers/traceBody.js +2 -1
  148. package/build/map/next_js/resolveAxiosHelpers/traceBody.js.map +1 -1
  149. package/build/map/next_js/resolveFetch.js +2 -1
  150. package/build/map/next_js/resolveFetch.js.map +1 -1
  151. package/build/map/next_js/resolveNewRequest.js +2 -1
  152. package/build/map/next_js/resolveNewRequest.js.map +1 -1
  153. package/build/map/next_js/resolveServerActions.js +2 -1
  154. package/build/map/next_js/resolveServerActions.js.map +1 -1
  155. package/build/map/next_js/utils.js +2 -1
  156. package/build/map/next_js/utils.js.map +1 -1
  157. package/build/map/react_js/getReactConnections.js +5 -4
  158. package/build/map/react_js/getReactConnections.js.map +1 -1
  159. package/build/map/vue_js/crossFileResolver.js +3 -2
  160. package/build/map/vue_js/crossFileResolver.js.map +1 -1
  161. package/build/map/vue_js/getViteConnections.js +5 -4
  162. package/build/map/vue_js/getViteConnections.js.map +1 -1
  163. package/build/map/vue_js/taint_utils.js +2 -1
  164. package/build/map/vue_js/taint_utils.js.map +1 -1
  165. package/build/map/vue_js/vue_resolveFetch.js +3 -2
  166. package/build/map/vue_js/vue_resolveFetch.js.map +1 -1
  167. package/build/map/vue_js/vue_resolveHttpClient.js +5 -3
  168. package/build/map/vue_js/vue_resolveHttpClient.js.map +1 -1
  169. package/build/map/vue_js/vue_resolveXhr.js +5 -3
  170. package/build/map/vue_js/vue_resolveXhr.js.map +1 -1
  171. package/build/mcp/cli.js.map +1 -1
  172. package/build/refactor/index.js +973 -27
  173. package/build/refactor/index.js.map +1 -1
  174. package/build/refactor/next/helpers.js +395 -0
  175. package/build/refactor/next/helpers.js.map +1 -0
  176. package/build/refactor/next/index.js +261 -71
  177. package/build/refactor/next/index.js.map +1 -1
  178. package/build/refactor/next/transform.js +1027 -0
  179. package/build/refactor/next/transform.js.map +1 -0
  180. package/build/refactor/next/validator.js +119 -0
  181. package/build/refactor/next/validator.js.map +1 -0
  182. package/build/refactor/react/helpers.js +106 -0
  183. package/build/refactor/react/helpers.js.map +1 -0
  184. package/build/refactor/react/index.js +290 -585
  185. package/build/refactor/react/index.js.map +1 -1
  186. package/build/refactor/react/library-classify.js +397 -0
  187. package/build/refactor/react/library-classify.js.map +1 -0
  188. package/build/refactor/react/transform.js +1852 -0
  189. package/build/refactor/react/transform.js.map +1 -0
  190. package/build/refactor/react/validator.js +123 -0
  191. package/build/refactor/react/validator.js.map +1 -0
  192. package/build/refactor/react-vite/index.js +652 -0
  193. package/build/refactor/react-vite/index.js.map +1 -0
  194. package/build/refactor/react-vite/vendor-analyze.js +336 -0
  195. package/build/refactor/react-vite/vendor-analyze.js.map +1 -0
  196. package/build/refactor/remote/cache.js +250 -0
  197. package/build/refactor/remote/cache.js.map +1 -0
  198. package/build/refactor/remote/config.js +63 -0
  199. package/build/refactor/remote/config.js.map +1 -0
  200. package/build/refactor/remote/hf-client.js +202 -0
  201. package/build/refactor/remote/hf-client.js.map +1 -0
  202. package/build/refactor/remote/version-detect.js +355 -0
  203. package/build/refactor/remote/version-detect.js.map +1 -0
  204. package/build/refactor/vue/index.js +176 -0
  205. package/build/refactor/vue/index.js.map +1 -0
  206. package/build/refactor/vue/vendor-analyze-vue.js +271 -0
  207. package/build/refactor/vue/vendor-analyze-vue.js.map +1 -0
  208. package/build/refactor/vue/vite.js +216 -0
  209. package/build/refactor/vue/vite.js.map +1 -0
  210. package/build/report/utility/genHtml.js +15 -4
  211. package/build/report/utility/genHtml.js.map +1 -1
  212. package/build/run/bundler-detect.js +154 -0
  213. package/build/run/bundler-detect.js.map +1 -0
  214. package/build/run/index.js +208 -16
  215. package/build/run/index.js.map +1 -1
  216. package/build/sourcemaps/index.js +89 -0
  217. package/build/sourcemaps/index.js.map +1 -0
  218. package/build/strings/index.js +6 -2
  219. package/build/strings/index.js.map +1 -1
  220. package/build/strings/trufflehog.js +71 -0
  221. package/build/strings/trufflehog.js.map +1 -0
  222. package/build/utility/banner.js +68 -0
  223. package/build/utility/banner.js.map +1 -0
  224. package/build/utility/getChromiumPath.js +40 -0
  225. package/build/utility/getChromiumPath.js.map +1 -0
  226. package/build/utility/globals.js +7 -0
  227. package/build/utility/globals.js.map +1 -1
  228. package/build/utility/makeReq.js +21 -11
  229. package/build/utility/makeReq.js.map +1 -1
  230. package/build/utility/postmanGenerator.js +2 -2
  231. package/build/utility/postmanGenerator.js.map +1 -1
  232. package/build/utility/puppeteerInstance.js +7 -1
  233. package/build/utility/puppeteerInstance.js.map +1 -1
  234. package/package.json +14 -8
  235. package/scripts/smoke-test.js +74 -0
  236. package/urls.txt +5 -0
package/CHANGELOG.md CHANGED
@@ -1,10 +1,177 @@
1
1
  # Change Log
2
2
 
3
- ## 1.3.2 - 2026-07-15
3
+ ## 1.4.1-alpha.9 - 2026-07-15
4
4
 
5
5
  ### Fixed
6
6
 
7
- - Rules auto-download now works under the `js-recon` GitHub organization. This is a hotfix of the stable line (functionally identical to 1.3.1), published so `@js-recon/js-recon` has a working stable `latest` after the move to the `js-recon` org: `initRules` now fetches releases from `js-recon/js-recon-rules` and matches the `js-recon-js-recon-rules-` release-archive prefix. In 1.3.1 these still referenced the old `shriyanss` namespace, so `js-recon run` failed to download rules (threw `Could not find extracted rules directory`) once the rules repository was migrated. (`analyze`)
7
+ - Homebrew: `brew install js-recon` now always installs the latest **stable** release instead of whichever version (including alphas/betas) was most recently promoted. `promote-js-recon.yml`'s Homebrew tap job is now channel-aware — it updates `Formula/js-recon-alpha.rb` / `Formula/js-recon-beta.rb` for prerelease promotions and leaves the main `Formula/js-recon.rb` (stable) formula untouched. Alpha/beta channels are now available via `brew install js-recon/tap/js-recon-alpha` / `js-recon-beta`, mirroring the existing `:alpha`/`:beta` Docker/GHCR tags. (`ci`, `homebrew`)
8
+ - `run` (batch mode, `-u <file>`): the generated OpenAPI spec and Postman collection (`mapped-openapi.json`, `mapped-openapi.postman_collection.json`) are no longer contaminated with endpoints from previously-processed targets in the same batch run. `openapiOutput` in `utility/globals.ts` is an accumulator that every map resolver pushes into, and it was never cleared between targets — so target N's output silently inherited every endpoint discovered for targets `1..N-1`. A new `clearOpenapiOutput()` is now called alongside the existing `clearJsUrls()`/`clearJsonUrls()` reset at the start of each target's pipeline. (`run`, `utility`)
9
+ - `refactor`: when the remote CS-MAST-S signature lookup for the active tech/scat/branch combination comes back empty (e.g. a non-default `--scat` value not yet covered by the dataset), the run's final summary now prints an explicit, high-visibility recap block (`LIBRARY STRIPPING WAS SKIPPED FOR THIS RUN`, naming the tech/scat/branch) in addition to the existing inline warning. Previously this was a single line that could scroll by unnoticed mid-run, so batch/automated invocations could silently lose library stripping with no easy signal that the output still contains library code. (`refactor`)
10
+ - `refactor -t next-webpack`: chunks whose module wrapper is a named `function` declaration (`function webpack_<id>(...)`, synthesized whenever the original bundle module was itself a `function` expression — the dominant form on real-world bundles) are now correctly recovered. Previously the traversal only visited `ArrowFunctionExpression` nodes, so these chunks were reported as `No module function found`, and in the rare cases where a nested arrow function's immediate parent happened to be an assignment, that unrelated inner fragment was captured as a false-positive "recovered" module. Both wrapper forms are now supported and the top-level check requires the wrapper to be a direct child of `Program`. Also fixes `next/validator.ts`'s `_generator` import, which was missing the `?? _generator` ESM interop fallback present in the react validator and broke under Vitest, blocking unit test coverage of this module. (`refactor`)
11
+ - `refactor`: the per-file signature cache's 7-day age-based TTL had no way to detect that the upstream HuggingFace dataset content changed within that window, so a stale-but-not-expired (or emptied/corrupted) cache entry was silently trusted, producing non-deterministic `chunks_library_skip`/`files_recovered` results across otherwise identical runs. Each bucket file's content hash is now fetched from the HF tree API once per branch per run and compared against the hash recorded when the entry was cached (`remote_hash.txt`); a mismatch invalidates the cache immediately regardless of age, and an unavailable remote hash falls back to the pre-existing age-based check. The hash-fetch call is wrapped in try/catch so a transient failure (e.g. HF API rate-limiting under concurrent invocations) degrades gracefully to the age-based check instead of throwing an unhandled rejection that silently aborted the whole run (`chunks_total: 0`, no visible error). (`refactor`)
12
+
13
+ ## 1.4.1-alpha.8 - 2026-07-14
14
+
15
+ ### Changed
16
+
17
+ - CI: `promote-js-recon.yml`'s Homebrew tap job now reads its push token (`HOMEBREW_TAP_GH_PAT`) from a scoped `homebrew-publish` GitHub Environment, restoring push access after the previous repo-wide `HOMEBREW_TAP_TOKEN` was retired. (`ci`)
18
+
19
+ ## 1.4.1-alpha.7 - 2026-07-14
20
+
21
+ ### Changed
22
+
23
+ - CI: bot commits (`chore: prettify code`, `chore: merge changes after release vX.Y.Z`) are now cryptographically signed via SSH (using [`shriyanss/verified-commit-action`](https://github.com/shriyanss/verified-commit-action)) and show as "Verified" on GitHub, under a dedicated `js-recon-bot` identity. The signing key is scoped to a `commit-signing` GitHub Environment so it's only readable by the jobs that need it, not the whole repo. `promote-js-recon.yml`'s Docker/GHCR publish job now reads `DOCKER_SECRET` from a similarly scoped `docker-publish` environment, and the Homebrew tap job no longer references a token secret. (`ci`)
24
+
25
+ ## 1.4.1-alpha.6 - 2026-07-13
26
+
27
+ ### Changed
28
+
29
+ - CI: npm publishing now uses OIDC trusted publishing with staged releases (`npm stage publish`) instead of a classic auth token, since NPM is restricting tokens that bypass MFA. Promoting a staged release to live still requires a manual, 2FA-gated `npm stage approve` — this cannot be automated. The Homebrew tap update and Docker/GHCR image publishing have moved out of `publish-js-recon.yml` into a new manually-triggered workflow, `promote-js-recon.yml`, run after the staged release is approved. That workflow installs js-recon from the published npm registry artifact (`npm pack`/`npm install <pkg>@<version>`) rather than building from git source, as an additional supply-chain safeguard — what ships in the Docker/GHCR images and what Homebrew hashes is provably the same bits that were reviewed and approved on npm. (`ci`)
30
+
31
+ ## 1.4.1-alpha.5 - 2026-07-13
32
+
33
+ ### Fixed
34
+
35
+ - Homebrew install: `puppeteer-extra` now receives the ESM `puppeteer` instance directly via `addExtra()` instead of relying on its internal `require('puppeteer')` call. On newer Node.js versions (22+, as shipped by Homebrew), a synchronous `require()` of an ESM module triggers `ExperimentalWarning` on every run. Using `addExtra()` bypasses the `require()` entirely and silences the warning. (`all`)
36
+ - `lazyload` (tech detect, react): React framework detection now works for Vite dev-mode servers. Vite's `@vitejs/plugin-react` and `@vitejs/plugin-react-swc` inject an inline `<script>` block containing `import { injectIntoGlobalHook } from "/@react-refresh"` into every dev-served page. Previously, none of the `REACT_MARKERS` matched this content, so dev-mode targets returned `unknown`. Two fixes: (1) `@react-refresh` and `injectIntoGlobalHook` are now included in `REACT_MARKERS` so the inline-script branch of `checkReact` fires immediately; (2) `/@react-refresh` is now a fast-path match in `fetchAndCheck` so any script src pointing at the HMR endpoint is also caught; (3) the intercepted-URL fallback in `frameworkDetect` now recognises `/@react-refresh` as a React signal alongside the existing Next.js / Nuxt / Svelte URL patterns. (`lazyload`, `fingerprint`, `run`)
37
+ - `lazyload` (tech detect, angular): Angular framework detection is now more robust. Three HTML-level signals are checked before fetching `main.js` — `data-beasties-container` (Angular's Beasties SSR/prerendering marker), `ng-version` (set by the Angular runtime on the root component element after bootstrapping, visible in Puppeteer-rendered DOM), and `_nghost-*` view-encapsulation attributes. These checks require no extra HTTP request and work even for zoneless Angular apps (Angular 16+) that omit Zone.js and therefore lack the previous `isAngularZone`/`this.ngZone` patterns. The `main.js` src pattern was also broadened from `main-` (hashed production builds only) to also match `main.js` (unhashed development builds). (`lazyload`, `fingerprint`, `run`)
38
+ - `lazyload`, `map`, `strings`: `.mjs` (ES module) files are now fully supported across all framework pipelines. Previously, extension filters in `downloadQueue.ts`, `downloadFilesUtil.ts`, `downloadLoadedJsUtil.ts`, `react_followImports.ts`, `getReactConnections.ts`, `getViteConnections.ts`, `getAngularConnections.ts`, `vue_resolveHttpClient.ts`, `vue_resolveFetch.ts`, `vue_resolveXhr.ts`, `crossFileResolver.ts`, and `strings/index.ts` only matched `.js` files. Sites that bundle all application code as `.mjs` (e.g. Framer/Rolldown) were silently ignored — all chunks were downloaded but zero files were scanned for connections, strings, or secrets. All affected paths now match both `.js` and `.mjs`. (`run`, `lazyload`, `map`, `strings`)
39
+ - `run` (react): The map step now receives the full `outputDir` (all downloaded hosts) rather than only the target host's subdirectory. Previously, when a React site served all its JS from a CDN host, the map step was pointed at an empty target-host directory and reported zero chunks. Now mirrors the Vue pipeline's directory-passing behaviour so CDN-hosted chunks are analysed correctly. (`run`, `map`)
40
+ - `lazyload` (react): `react_followImports` now discovers dynamic imports written as template literals (``import(`./chunk.mjs`)``) in addition to single/double-quoted strings. Bundlers that use Rolldown (e.g. Framer) emit all dynamic import paths as template literals; the previous regex only matched quoted strings, silently missing all lazily-loaded page and collection chunks. (`lazyload`, `run`)
41
+ - `lazyload`: `.mjs.map` sourcemap files are now handled correctly. The filename extraction regex now prefers the `.mjs.map` suffix over the shorter `.mjs` match, preventing sourcemap JSON content from being written with a `.mjs` extension (which caused Prettier's Babel parser to throw a `SyntaxError` and discard the file). The sourcemap write path now uses the JSON parser for both `.js.map` and `.mjs.map` files. (`lazyload`, `run`)
42
+ - `lazyload` (Puppeteer): `downloadLoadedJsUtil` now uses `waitUntil: "networkidle0"` with a 10 s timeout on `page.goto()`. Previously the call had no timeout and no error handling, so pages whose `load` event never fires (deferred JS, service workers, some SPA patterns) caused the lazyload step to hang indefinitely. Navigation errors and timeouts are now caught and the URLs collected up to that point are returned normally. (`lazyload`, `run`)
43
+ - `lazyload` (Puppeteer): `browser.close()` in `downloadLoadedJsUtil` is now wrapped in a try/catch; if it hangs, the Chrome process is force-killed via `SIGKILL`. Previously a stuck `browser.close()` caused the process to hang after download was otherwise complete. (`lazyload`, `run`)
44
+ - `lazyload` (Puppeteer): All three Puppeteer-using modules (`downloadLoadedJsUtil`, `next_GetLazyResourcesWebpackJs`, `techDetect/index`) now abort non-http/s requests (e.g. `mailto:`, `data:`, `blob:`, `chrome-extension:`, `tel:`) in the request interceptor instead of calling `request.continue()`. Calling `continue()` on these schemes throws an unhandled error and can trigger OS protocol handlers. (`lazyload`, `run`)
45
+ - `lazyload` (Puppeteer): `downloadLoadedJsUtil` and `next_GetLazyResourcesWebpackJs` now pass `--disable-external-protocol-dialog` to Chrome at launch and install an `evaluateOnNewDocument` guard that overrides `window.open` and suppresses clicks on non-http/s anchors. This provides a three-layer defence (Chrome flag + JS intercept + request interceptor abort) ensuring that non-http protocol links on target pages never invoke OS handlers (mail client, phone, etc.). (`lazyload`, `run`)
46
+ - `lazyload` (Puppeteer): All three Puppeteer-using modules now issue a `Page.setDownloadBehavior({ behavior: "deny" })` CDP command immediately after page creation. This prevents accidental file downloads triggered by download-link clicks or JavaScript during crawl, which could block the browser and fill the output directory with unexpected files. (`lazyload`, `run`)
47
+ - `lazyload` (tech detect): After `waitUntil: "load"` resolves, if no framework URL has been captured in `interceptedUrls` yet, a conditional `page.waitForNavigation({ timeout: 5000 })` is now issued to wait for a second navigation event. This catches sites that serve a JS proof-of-work bot challenge (e.g. Vercel's `challenge.v2.min.js`) that fires its own `load` event before calling `window.location` to redirect to the real app. Previously, Puppeteer exited on the challenge page's `load` event and tech detection returned null (exit 10). On sites with no redirect the navigation wait times out after 5 s and detection continues normally. (`lazyload`, `run`)
48
+ - `lazyload`: When `frameworkDetect` returns null and `downloadLoadedJs` is used as a fallback, the downloaded file URL paths are now scanned for `/_next/`, `/_nuxt/`, and `/_app/immutable/` signatures as a second-chance tech detection pass. Previously, sites that serve their framework app at a non-root `basePath` (e.g. Next.js at `/app` instead of `/`) caused the initial Puppeteer-based detection to miss the framework because the intercepted JS paths didn't match any framework pattern, resulting in exit 10. (`lazyload`, `run`)
49
+ - `lazyload` (next_js): `next_parseLayoutJs` now applies a 1.5 MB per-file size guard — checked from both the `Content-Length` response header and the fetched content body — before passing layout files to the AST parser. Files exceeding the limit are skipped with a yellow warning. Previously, Next.js App Router sites with 50+ nested pages each loading a large `layout.js` caused cumulative AST memory of ~2 GB, exhausting the V8 heap and crashing with SIGSEGV (exit 139). (`lazyload`, `run`)
50
+ - `cs-mast`: `--scat`, `--sinc`, `--all-scat-permutations`, `--perm-output`, and `--perm-concurrency` flags were declared in the CLI but not wired to the underlying function, causing a TypeScript compile error (`TS2554: Expected 5 arguments, but got 10`). The function now accepts all five additional parameters: `--scat`/`--sinc` override the active CS-MAST config, and `--all-scat-permutations` runs all 511 non-empty scat subsets in parallel batches and writes one collision file per subset to `--perm-output`. (`cs-mast`)
51
+
52
+ - `refactor -t react-vite`: vendor chunks (`vendor-react-*.js`, `rolldown-runtime-*.js`) that are absent from `mapped.json` are now automatically located in the downloaded assets directory and injected before the refactor pass. Previously, `mapped.json` typically contained only app chunks — vendor chunks are excluded from mapping because they hold only third-party code. This left `vendorExportMaps` empty, so the `rewriteVendorImports` pass had nothing to match against and vendor import statements like `import { d as t } from './vendor-react-CLFLfR9F.js'` survived into the output, causing the Vite build check to fail with "Could not resolve". The fix uses the existing `findAssetsDir`/`findVendorChunkFiles` helpers (already used by the webpack branch) to discover the assets directory from `// File Source:` headers in chunk code.
53
+ - `lazyload` (nuxt): `nuxt_getFromPageSource` now prints the number of new JS files discovered (delta from the global URL set) instead of the running total. Previously the count included every URL already known from earlier in the session.
54
+ - `lazyload` (vue): Each discovery method in `vue_discoverJsFiles` now prints only the count of URL that are genuinely new — URLs already known from earlier methods are excluded. Previously `fromImports.length`, `fromStringRefs.length`, etc. could include URLs already in the accumulator and over-count.
55
+ - Error messages emitted by `makeReq` (fetch failures, cache errors, timeout notices, firewall detection) now use `progressError`/`progressLog` instead of `console.error`/`console.log`, so they are routed through the active progress bar's logger and no longer clutter the bar line when errors occur during a scan.
56
+ - `refactor` (`react-webpack`, `react-vite`): new `--detect-version` flag. When set, the tool fetches per-version `reliable_signatures.json` files from the `shriyanss/cs-mast-s-dataset` HuggingFace bucket (path: `version/react/<bundler>/<version>/<scat>/reliable_signatures.json`) and matches them against CS-MAST signatures generated from the target bundle's chunks. The best-matching React version is used to set `react` and `react-dom` version pins in the refactored output's `package.json` instead of the default `^18.3.1`. Signatures are cached under `~/.js-recon/refactor/version_sigs_cache/` with a 7-day TTL. Supports all webpack versions (react-0.12 through react-19) and all Vite versions (react-16 through react-19) available in the dataset. (`refactor`)
57
+
58
+ ### Added
59
+
60
+ - `fingerprint`: output files are now written incrementally — each result is flushed to disk immediately after detection rather than buffered and written at the end. For text, csv, and jsonl formats the result is appended; for json the full array is rewritten. Output files are also created (and csv headers written) before the worker pool starts, so a partial file always exists if the scan is interrupted. (`fingerprint`)
61
+ - CLI: help output is now colorized. Section titles (`Usage:`, `Options:`, `Commands:`) are bold cyan; flag names are yellow; `<required>` argument placeholders are magenta; `[optional]` argument placeholders are cyan; descriptions are dimmed; and `(default: …)` suffixes are dim italic. Applies to every subcommand.
62
+ - `run`: the pipeline now runs an optional `refactor` pass after the report step for React, Vue, Nuxt, and Next.js targets. The bundler (webpack vs vite) is detected automatically using CS-MAST-S signatures sampled from the `shriyanss/cs-mast-s-dataset` HuggingFace bucket — the same bucket and caching layer used by `refactor --remote-collisions`. If the detected match count meets `--cs-mast-tech-detect-threshold` (default `50`), `refactor` is called with the full tech identifier (e.g. `react-webpack`); otherwise the step is silently skipped. Refactored output is written to `refactored/` (single-URL mode) or `<workingDir>/refactored/` (batch mode). Currently only React bundles have bucket entries; Vue, Nuxt, and Next.js gracefully skip until their signatures are added to the bucket. (`run`, `refactor`)
63
+ - `run`: new `--cs-mast-tech-detect-threshold <n>` flag (default `50`). Sets the minimum number of CS-MAST-S signature matches required to consider a bundler detected for the refactor step. Pass `0` to disable refactor entirely. (`run`)
64
+ - `refactor` (`react-vite`, `react-webpack`): new `--remote-collisions <path>` flag. Accepts a HuggingFace bucket path (e.g. `react/vite/large-0.1.8`) and uses it as the signature source instead of the automatic `TECH_TO_BRANCH` mapping. When the path does not exist in the `shriyanss/cs-mast-s-dataset` bucket the tool exits with code 25. The existing caching layer is fully reused — signatures are cached under `~/.js-recon/refactor/signature_cache/` and the file list is cached in `~/.js-recon/refactor/cs-mast-s-list-cache.json`. Feature directories that contain no collision records in the dataset are skipped during intersection rather than collapsing the result to zero.
65
+ - `refactor` (`react-webpack`, `react-vite`): `--detect-version` now uses multiple scat configurations for improved accuracy. Three new flags control the behaviour: `--detect-version-config` (default `dynamic`), `--detect-version-dynamic-threshold` (default `3`), and `--detect-version-dynamic-conf-purge`. In `dynamic` mode the tool automatically selects up to `--detect-version-dynamic-threshold` scat configs that have non-empty reliable signatures across all known React versions, caches the selection in `~/.js-recon/refactor/config.json`, and aggregates match counts across all configs per version for a stronger detection signal. Alternatively, passing comma-separated scat categories (e.g. `lit,decl,loop,cond`) to `--detect-version-config` fixes the config; the tool validates signatures are non-empty for every version and exits with code 26 if not. Use `--detect-version-dynamic-conf-purge` to force recomputation of the cached config.
66
+
67
+ ### Changed
68
+
69
+ - Set `react/webpack/large-0.1.8` as default cs-mast-s dataset for react + webpack refactoring
70
+
71
+ ## 1.4.1-alpha.4 - 2026-06-29
72
+
73
+ ### Added
74
+
75
+ - `sourcemaps`: new subcommand to extract original source files from `.map` sourcemaps without running the full pipeline. Accepts a single `.map` file or a directory of `.map` files via `-i`/`--input`; writes recovered sources to `-o`/`--output` (default: `extracted`).
76
+ - Homebrew tap distribution: `brew tap js-recon/tap && brew install js-recon` installs js-recon via the `js-recon/homebrew-tap` Homebrew tap. The formula (`Formula/js-recon.rb`) auto-updates on every npm publish via the `update-homebrew-tap` CI job in `publish-js-recon.yml`.
77
+
78
+ ### Changed
79
+
80
+ - `lazyload`: sourcemap extraction logic moved to the new `sourcemaps` module (`src/sourcemaps/`). Behaviour is identical; `lazyload` now delegates to `extractSourceMaps` from that module rather than containing a private copy.
81
+
82
+ ## 1.4.1-alpha.3 - 2026-06-25
83
+
84
+ ### Added
85
+
86
+ - `run`: `--include-methods`, `--exclude-methods`, and `--list-methods` flags are now available on the `run` command, mirroring the same flags on `lazyload`. All three lazyload passes inside the `run` pipeline (initial, subsequent-requests, and re-pass) honour the method filter. `--list-methods [framework]` prints available method names and exits before any network work, so it can be used without a `-u` target URL.
87
+
88
+ - `run` (angular): Full 4-step pipeline support for Angular apps — lazyload → map → analyze → report. Previously the pipeline halted after lazyload with a warning; Angular targets now get the same depth of analysis as React and Vue. The map step resolves Angular `HttpClient` calls (`n.get(url)`, `n.post(url, body)`, etc.) via the shared HTTP-client resolver and native `fetch()` calls via the shared fetch resolver; the analyze step runs all rules whose `tech` array includes `"angular"` (or `"all"`); the report step generates the HTML/SQLite report as for other frameworks.
89
+
90
+ - `map`: Angular support via new `angular_js/` module. `getAngularConnections` reads Angular CLI (esbuild) chunks from the download directory and emits one chunk per JS file. Polyfill bundles (`polyfills-*.js`) are excluded (vendor code only). Registered as a new tech option (`-t angular`) alongside `next`, `vue`, `react`, and `svelte`.
91
+
92
+ - `analyze`: Angular added as a valid `tech` value in rule YAML and the Zod schema. Rules whose `tech` array lists `angular` (or `all`) now run when `--tech angular` is set (or when `run` detects Angular automatically).
93
+
94
+ - `rules` (angular): New rule `detect_angular_bypass_security_trust` detects calls to `bypassSecurityTrustHtml`, `bypassSecurityTrustScript`, `bypassSecurityTrustStyle`, `bypassSecurityTrustUrl`, and `bypassSecurityTrustResourceUrl` — Angular's DomSanitizer bypass methods that disable built-in XSS protection. Severity: high. Added `angular` to the `tech` array of all 17 existing AST rules that previously covered only `next`, `vue`, `react`, and `svelte`.
95
+
96
+ - `refactor -t react-vite`: new Vite (rolldown) React refactor mode. Takes a `mapped.json` whose chunks are Vite-produced ESM files and outputs one `.jsx` file per app chunk with library boilerplate removed and readable source recovered:
97
+ - Analyzes all vendor chunks (`vendor-react-*.js`) to classify every export as `react`, `react/jsx-runtime`, `react-dom/client`, or `react-router-dom`
98
+ - Detects CJS interop vars — both `__toESM(getter(), 1)` and bare `getter()` forms — and rewrites `(0, x.prop)(args)` calls to bare canonical names (`useState(args)`, `jsx(...)`, etc.)
99
+ - Rewrites the vendor import statement to direct canonical library imports (`import { useState, useEffect } from 'react'`, etc.)
100
+ - Reuses shared cleanup passes from the webpack refactor: `slicedToArray` collapse, JSX recovery (handles rolldown's template literal tag names `` `div` ``), Babel helper removal, unused-import pruning
101
+ - Runs a Vite build check after writing output: scaffolds a minimal Vite project in the output directory, renames `.js` → `.jsx`, rewrites relative dynamic imports, installs dependencies, and runs `vite build` to confirm the refactored code compiles
102
+
103
+ - `refactor -t react-webpack`: new `--scat <categories>` flag overrides the CS-MAST scat category set used for both the remote signature download and the module classifier. Accepts a comma-separated list of categories from `lit,id,op,decl,loop,cond,name,val,op_name` (e.g. `--scat lit,decl,cond`). The flag correctly maps to bucket directory names following the canonical `ALL_SCAT_CATEGORIES` ordering (the same ordering used by `jsr-cs-mast-s-gen`), so `--scat lit,cond,decl` and `--scat decl,lit,cond` both resolve to the `lit-decl-cond` bucket directory.
104
+
105
+ - `lazyload` (svelte): `svelte_getVersionJson` — probes `/<appDir>/version.json` when SvelteKit is detected. SvelteKit generates this file at build time and serves it for the `updated` store; because it has no `<script src>`, `<link href>`, or `import()` reference anywhere it is invisible to all other discovery steps and must be fetched directly. The `appDir` is derived from the entry-point URLs already discovered (default: `_app`). The method is registered in `methodFilter.ts` and can be skipped via `--exclude-methods svelte_getVersionJson`.
106
+
107
+ - `run` (nuxt): Full 4-step pipeline support for Nuxt.js apps — lazyload → map → analyze → report. Previously the pipeline halted after lazyload because `nuxt` was not in the supported-techs allowlist; Nuxt targets now run the same pipeline as Vue.
108
+
109
+ - `lazyload` (nuxt): `nuxt_getBuildsManifest` — probes `/_nuxt/builds/latest.json` and derives `/_nuxt/builds/meta/<id>.json` from it. Both files are fetched at runtime by the Nuxt client for incremental-deployment support but are never referenced from HTML or JS string literals, making them invisible to all other discovery steps. The method is registered in `methodFilter.ts` and can be skipped via `--exclude-methods nuxt_getBuildsManifest`.
110
+
111
+ ### Changed
112
+
113
+ - `refactor -t react-webpack`: remote signatures now load from the HuggingFace bucket `shriyanss/cs-mast-s-dataset` (bucket prefix `react/webpack/large`) instead of the old dataset branch `react-small`. The bucket uses a structured prefix layout (`main/`, `react/webpack/small/`, `react/webpack/large/`). The local cache key changes from `react-small/` to `react/webpack/large/`, automatically invalidating any stale cache.
114
+
115
+ ### Fixed
116
+
117
+ - `refactor -t react-webpack`: lazy-loaded components are now converted to true dynamic `import()` calls (Pass 4.5). Previously, webpack's async chunk-loading expression `__webpack_require__.e(N).then(__webpack_require__.bind(__webpack_require__, N))` was emitted as-is with `__webpack_require__` undefined in the output, causing a runtime `ReferenceError`. Pass 4.5 detects this pattern by matching the `.e(N)` / `.bind(requireParam, N)` shape and replaces it with `import('./N.js')`, producing a valid dynamic import that works in any ES module environment.
118
+ - `refactor -t react-webpack`: minified route-component variable names are now renamed to descriptive names derived from their `<Route path="…">` attributes. `renameRouteComponents` traverses the JSX `<Routes>` tree, accumulates path segments, generates a PascalCase component name per route (e.g. `/admin/users` → `AdminUsers`, `/admin/index` → `AdminDashboard`), and renames the corresponding `lazy(() => import('./N.js'))` declarations via `scope.rename`. The Suspense fallback component is renamed `Loading`. The App component function is renamed `App`.
119
+
120
+ - `lazyload` (svelte): `svelte_getFromPageSource` now extracts JS entry-point paths from inline `<script>` bodies by matching `import("...")` call arguments. SvelteKit `adapter-node` boots the client via `Promise.all([import("./_app/immutable/entry/start.js"), ...])` with no `src` attribute, which the previous HTML-attribute-only parser missed entirely, causing 0 JS files to be downloaded. The fix seeds the entry-point URLs so the downstream ESM import-following loop (`react_followImports`) can traverse the full chunk graph.
121
+ - `lazyload` (react): `react_followImports` `__vite_mapDeps` handler now correctly resolves SvelteKit's file-relative chunk paths (`"../nodes/0.js"`) in addition to Vue/React's root-relative paths (`"/assets/chunk.js"`). Previously all non-absolute paths had `/` prepended before URL resolution, causing `"../nodes/0.js"` to become `"/../nodes/0.js"` which the URL constructor normalized to `"/nodes/0.js"` — a wrong origin-root path that produced 404 responses. The fix resolves paths starting with `/` against `baseUrl` (origin root) and all other paths against `fileUrl` (the chunk containing the mapDeps table). This eliminates 32 spurious "Failed to write file" errors per SvelteKit run; the correct 34 chunk files were still downloaded via `svelte_stringAnalysisJSFiles`, so analysis results were unaffected.
122
+
123
+ ## 1.4.1-alpha.2 - 2026-06-20
124
+
125
+ ### Fixed
126
+
127
+ - `lazyload`: `--include-methods`, `--exclude-methods`, and `--list-methods` flags were listed as Added in v1.4.1-alpha.1 but the CLI wiring was absent from that release; they are now fully implemented and functional
128
+ - `lazyload`: `--list-methods` works without `-u`; the URL option is now validated manually so `--list-methods` can run standalone
129
+ - `refactor`: `-l`/`--list` no longer errors with "Mapped JSON file does not exist" when listing technologies — the list early-return now runs before the file-existence check
130
+
131
+ ## 1.4.1-alpha.1 - 2026-06-20
132
+
133
+ ### Added
134
+
135
+ - `lazyload`: `--include-methods <methods>` and `--exclude-methods <methods>` flags for selective method execution. Comma-separated method names are matched against the file-based method registry in `src/lazyLoad/methodFilter.ts`; invalid names exit with code 22. Methods are named after their source files (e.g. `next_bruteForceJsFiles`).
136
+ - `lazyload`: `--list-methods [framework]` flag prints all available method names grouped by framework (`next_js`, `vue`, `nuxt_js`, `svelte`, `angular`, `react`) and exits. Optionally pass a framework name to filter the output.
137
+ - `lazyload`: `--research` now tracks and writes technique efficiency output for all frameworks (Vue, Nuxt, Angular, React, Svelte), not just Next.js.
138
+
139
+ - `cs-mast`: new subcommand that computes CS-MAST-S (Context-Stratified Merkelized Abstract Syntax Tree) signatures for every downloaded `.js` file and finds structural hash collisions across targets (`cs-mast`)
140
+ - `--ct / --collision-table`: print a collision table sorted by frequency (files sharing the same CS-MAST-S root signature)
141
+ - `--min-collisions <n>`: minimum number of files that must share a signature to appear in the table (default: 2)
142
+ - `--co / --collision-output <file>`: write collision results to a file; independent of `--ct` (file is written without printing the table if `--ct` is omitted)
143
+ - `--cf / --collision-format json|csv`: output format (default: csv); if `--co` is a directory or has no extension, the file is written as `collisions.<fmt>` in the current working directory
144
+ - Uses `@shriyanss/cs-mast` with `scat: [lit, decl, loop, cond]`, SHA-256, `sourceType: unambiguous`; parse errors are skipped with a warning
145
+
146
+ - `refactor -t react-webpack`: new React webpack refactor mode that splits a webpack 5 bundle into individual ES module files (`refactor`)
147
+ - Numeric module map (`var e = { 540: fn, … }`) is extracted and each module written to `<id>.js` with full ES import/export conversion (require→import hoisting, exports→named/default export rewriting, outer wrapper stripped)
148
+ - Non-module IIFE content (bootstrap helpers, root component, `ReactDOM.render` call) is captured into `index.js`
149
+ - Webpack require helper is detected by its `return (moduleMap[id](…), mod.exports)` return shape and stripped from `index.js`
150
+ - Top-level `requireFn(N)` calls in `index.js` are hoisted to `import * as x from "./N.js"`; remaining inline calls are replaced recursively throughout the file
151
+ - `refactor --collisions` now accepts a per-feature results directory (a directory whose immediate subdirs each contain `<scat>/collisions.json`, e.g. a 18-feature corpus with `01-usestate-hook-webpack/lit-decl-loop-cond/collisions.json` etc.) — reads only the scat-relevant file per feature subdir, intersects the max-count signature sets across all features, and uses the intersection as the library baseline; works even when the full dataset is hundreds of GB (`refactor`)
152
+ - `refactor -t react-webpack`: Pass G now strips three additional Babel inline helpers emitted to the IIFE body — `_typeof` (lazy self-reassignment typeof polyfill, detected by single-return body reassigning its own binding), `_defineProperty`/`_toPropertyKey`/`_toPrimitive` (property-setter helpers, detected by `Object.defineProperty` call with `{value, enumerable, configurable, writable}` descriptor), and `_objectSpreadPropsHelper` (detected by `Object.keys` first-statement + `getOwnPropertySymbols` reference) — cleaning up noise left by JSX spread and object spread (`refactor`)
153
+
154
+ ### Fixed
155
+
156
+ - Puppeteer browser launch now resolves a usable Chrome/Chromium via a new `getChromiumPath` utility (`PUPPETEER_EXECUTABLE_PATH` env var → well-known system paths → `which`) and passes it as `executablePath`; also adds `--disable-dev-shm-usage` to the sandbox-disabled arg list — fixes crashes on systems where Puppeteer's bundled Chrome is absent or has missing shared libraries (`lazyload`, `makeReq`)
157
+ - `refactor --collisions`: `scanExportMap` now records a self-reference when a module export's RHS is a complex expression (e.g. a function declaration) so it participates in canonical library classification checks instead of being silently dropped (`refactor`)
158
+ - `refactor --collisions`: added `Profiler` to `REACT_CANONICAL` export set (`refactor`)
159
+
160
+ ### Changed
161
+
162
+ - `refactor -t react` renamed to `refactor -t react-webpack` to make the bundler explicit
163
+ - Improved tool description in `globalConfig.ts`
164
+
165
+ ## 1.3.1-beta.1 - 2026-06-08
166
+
167
+ ### Added
168
+
169
+ ### Changed
170
+
171
+ ### Fixed
172
+
173
+ - `--max-heap` on `map` and `run` is now opt-in: without the flag, no process re-exec occurs and the existing `--max-old-space-size` from the npm start script is preserved. Previously, the default `0` caused every invocation to re-exec with `os.totalmem()` as the heap ceiling, which could trigger OOM kills on memory-constrained hosts and changed the default runtime for all users who never specified the flag. (`map`, `run`)
174
+ - XHR and HTTP-client taint resolvers (`vue_resolveXhr`, `vue_resolveHttpClient`) now sort the JS file list alphabetically before applying the 50 MB caller-lookup cap. Previously the cap was applied in `readdirSync` order, which is filesystem-dependent and made the included file set non-deterministic across runs — on large bundles this could silently exclude different API call sites depending on inode ordering. (`map`)
8
175
 
9
176
  ## 1.3.1 - 2026-06-16
10
177
 
@@ -448,7 +615,7 @@
448
615
 
449
616
  - Added `analyze` module
450
617
  - Added analysis of OpenAPI spec file (requestEngine)
451
- - Use the repo https://github.com/shriyanss/js-recon-rules to remotely store and download rules
618
+ - Use the repo https://github.com/js-recon/js-recon-rules to remotely store and download rules
452
619
 
453
620
  ### Changed
454
621
 
@@ -523,7 +690,7 @@
523
690
 
524
691
  ### Fixed
525
692
 
526
- - Fixed [issue 30](https://github.com/shriyanss/js-recon/issues/30): `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory`
693
+ - Fixed [issue 30](https://github.com/js-recon/js-recon/issues/30): `FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory`
527
694
 
528
695
  ## 1.1.3-alpha.2 - 2025.07.23
529
696