specific-ai-cli 0.0.0-stage → 0.1.1

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 (277) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +177 -0
  3. package/README.ja.md +177 -0
  4. package/README.ko.md +177 -0
  5. package/README.md +174 -2
  6. package/README.zh-TW.md +177 -0
  7. package/assets/banner.txt +3 -0
  8. package/dist/cli/argv.js +98 -0
  9. package/dist/cli/commands/auth.js +11 -0
  10. package/dist/cli/commands/config.js +23 -0
  11. package/dist/cli/commands/doctor.js +134 -0
  12. package/dist/cli/commands/platforms.js +24 -0
  13. package/dist/cli/commands/version.js +4 -0
  14. package/dist/cli/confirm.js +22 -0
  15. package/dist/cli/dispatch.js +440 -0
  16. package/dist/cli/help.js +223 -0
  17. package/dist/cli/hints.js +60 -0
  18. package/dist/cli/main.js +18 -0
  19. package/dist/cli/output.js +66 -0
  20. package/dist/core/auth-handlers.js +41 -0
  21. package/dist/core/auth-store.js +119 -0
  22. package/dist/core/capabilities.js +163 -0
  23. package/dist/core/config.js +121 -0
  24. package/dist/core/cookies.js +164 -0
  25. package/dist/core/errors.js +37 -0
  26. package/dist/core/files.js +89 -0
  27. package/dist/core/fsutil.js +52 -0
  28. package/dist/core/hash.js +4 -0
  29. package/dist/core/http.js +331 -0
  30. package/dist/core/image.js +280 -0
  31. package/dist/core/log.js +40 -0
  32. package/dist/core/login.js +191 -0
  33. package/dist/core/mp4.js +130 -0
  34. package/dist/core/normalize.js +207 -0
  35. package/dist/core/options.js +110 -0
  36. package/dist/core/paths.js +38 -0
  37. package/dist/core/pb.js +59 -0
  38. package/dist/core/py.js +181 -0
  39. package/dist/core/rand.js +131 -0
  40. package/dist/core/registry.js +129 -0
  41. package/dist/core/schemas.js +41 -0
  42. package/dist/core/stream.js +104 -0
  43. package/dist/core/toolkit.js +35 -0
  44. package/dist/core/vm.js +73 -0
  45. package/dist/core/vocab.js +157 -0
  46. package/dist/platforms/_shared/impaas.js +410 -0
  47. package/dist/platforms/bilibili/index.js +216 -0
  48. package/dist/platforms/bilibili/web/api.js +806 -0
  49. package/dist/platforms/bilibili/web/client.js +311 -0
  50. package/dist/platforms/bilibili/web/commands.js +783 -0
  51. package/dist/platforms/bilibili/web/ddddocr.js +342 -0
  52. package/dist/platforms/bilibili/web/gaia.js +130 -0
  53. package/dist/platforms/bilibili/web/geetest-manual.js +154 -0
  54. package/dist/platforms/bilibili/web/geetest-vision.js +232 -0
  55. package/dist/platforms/bilibili/web/geetest.js +450 -0
  56. package/dist/platforms/bilibili/web/normalize.js +234 -0
  57. package/dist/platforms/bilibili/web/profile.js +135 -0
  58. package/dist/platforms/bilibili/web/resolve.js +112 -0
  59. package/dist/platforms/bilibili/web/sign.js +223 -0
  60. package/dist/platforms/bilibili/web/upos.js +102 -0
  61. package/dist/platforms/douyin/index.js +142 -0
  62. package/dist/platforms/douyin/web/api.js +863 -0
  63. package/dist/platforms/douyin/web/client.js +413 -0
  64. package/dist/platforms/douyin/web/commands.js +712 -0
  65. package/dist/platforms/douyin/web/creator.js +601 -0
  66. package/dist/platforms/douyin/web/crypto.js +247 -0
  67. package/dist/platforms/douyin/web/dtrait.js +190 -0
  68. package/dist/platforms/douyin/web/im.js +502 -0
  69. package/dist/platforms/douyin/web/image.js +5 -0
  70. package/dist/platforms/douyin/web/live.js +225 -0
  71. package/dist/platforms/douyin/web/mssdk.js +148 -0
  72. package/dist/platforms/douyin/web/normalize.js +326 -0
  73. package/dist/platforms/douyin/web/passport.js +1247 -0
  74. package/dist/platforms/douyin/web/profile.js +221 -0
  75. package/dist/platforms/douyin/web/proto.js +26 -0
  76. package/dist/platforms/douyin/web/resolve.js +88 -0
  77. package/dist/platforms/douyin/web/sign.js +436 -0
  78. package/dist/platforms/douyin/web/tos.js +78 -0
  79. package/dist/platforms/index.js +17 -0
  80. package/dist/platforms/jd/index.js +67 -0
  81. package/dist/platforms/jd/web/aks.js +115 -0
  82. package/dist/platforms/jd/web/api.js +549 -0
  83. package/dist/platforms/jd/web/chat.js +132 -0
  84. package/dist/platforms/jd/web/client.js +470 -0
  85. package/dist/platforms/jd/web/commands.js +557 -0
  86. package/dist/platforms/jd/web/jcap/helper.js +90 -0
  87. package/dist/platforms/jd/web/jcap/host.js +107 -0
  88. package/dist/platforms/jd/web/jcap/lsd.js +300 -0
  89. package/dist/platforms/jd/web/jcap/solver.js +995 -0
  90. package/dist/platforms/jd/web/jcap.js +150 -0
  91. package/dist/platforms/jd/web/js.js +420 -0
  92. package/dist/platforms/jd/web/login.js +775 -0
  93. package/dist/platforms/jd/web/normalize.js +297 -0
  94. package/dist/platforms/jd/web/profile.js +256 -0
  95. package/dist/platforms/jd/web/util.js +175 -0
  96. package/dist/platforms/jd/web/webm.js +133 -0
  97. package/dist/platforms/kuaishou/index.js +98 -0
  98. package/dist/platforms/kuaishou/web/api.js +694 -0
  99. package/dist/platforms/kuaishou/web/captcha-crypto.js +134 -0
  100. package/dist/platforms/kuaishou/web/captcha-fp.js +180 -0
  101. package/dist/platforms/kuaishou/web/captcha.js +273 -0
  102. package/dist/platforms/kuaishou/web/client.js +487 -0
  103. package/dist/platforms/kuaishou/web/commands.js +863 -0
  104. package/dist/platforms/kuaishou/web/gap.js +144 -0
  105. package/dist/platforms/kuaishou/web/gdfp.js +376 -0
  106. package/dist/platforms/kuaishou/web/gql.js +11 -0
  107. package/dist/platforms/kuaishou/web/live.js +125 -0
  108. package/dist/platforms/kuaishou/web/normalize.js +241 -0
  109. package/dist/platforms/kuaishou/web/oracle.js +329 -0
  110. package/dist/platforms/kuaishou/web/profile.js +259 -0
  111. package/dist/platforms/kuaishou/web/resolve.js +84 -0
  112. package/dist/platforms/kuaishou/web/session.js +592 -0
  113. package/dist/platforms/kuaishou/web/sign.js +568 -0
  114. package/dist/platforms/taobao/index.js +56 -0
  115. package/dist/platforms/taobao/web/api.js +96 -0
  116. package/dist/platforms/taobao/web/client.js +102 -0
  117. package/dist/platforms/taobao/web/commands.js +172 -0
  118. package/dist/platforms/taobao/web/im.js +68 -0
  119. package/dist/platforms/taobao/web/normalize.js +103 -0
  120. package/dist/platforms/taobao/web/profile.js +85 -0
  121. package/dist/platforms/taobao/web/resolve.js +51 -0
  122. package/dist/platforms/taobao/web/sign.js +35 -0
  123. package/dist/platforms/tiktok/index.js +120 -0
  124. package/dist/platforms/tiktok/web/api.js +1234 -0
  125. package/dist/platforms/tiktok/web/client.js +362 -0
  126. package/dist/platforms/tiktok/web/commands.js +821 -0
  127. package/dist/platforms/tiktok/web/im.js +133 -0
  128. package/dist/platforms/tiktok/web/jsrun.js +126 -0
  129. package/dist/platforms/tiktok/web/normalize.js +286 -0
  130. package/dist/platforms/tiktok/web/profile.js +169 -0
  131. package/dist/platforms/tiktok/web/resolve.js +156 -0
  132. package/dist/platforms/tiktok/web/sign.js +585 -0
  133. package/dist/platforms/tiktok/web/upload.js +805 -0
  134. package/dist/platforms/tiktok/web/wire.js +490 -0
  135. package/dist/platforms/weibo/index.js +91 -0
  136. package/dist/platforms/weibo/web/api.js +206 -0
  137. package/dist/platforms/weibo/web/client.js +155 -0
  138. package/dist/platforms/weibo/web/commands.js +202 -0
  139. package/dist/platforms/weibo/web/normalize.js +137 -0
  140. package/dist/platforms/weibo/web/profile.js +246 -0
  141. package/dist/platforms/weibo/web/resolve.js +60 -0
  142. package/dist/platforms/weibo/web/sign.js +85 -0
  143. package/dist/platforms/x/index.js +107 -0
  144. package/dist/platforms/x/web/api.js +443 -0
  145. package/dist/platforms/x/web/article.js +212 -0
  146. package/dist/platforms/x/web/client.js +202 -0
  147. package/dist/platforms/x/web/commands.js +363 -0
  148. package/dist/platforms/x/web/graphql.js +108 -0
  149. package/dist/platforms/x/web/normalize.js +235 -0
  150. package/dist/platforms/x/web/profile.js +99 -0
  151. package/dist/platforms/x/web/resolve.js +44 -0
  152. package/dist/platforms/x/web/transaction.js +171 -0
  153. package/dist/platforms/xhs/index.js +101 -0
  154. package/dist/platforms/xhs/web/api.js +278 -0
  155. package/dist/platforms/xhs/web/client.js +540 -0
  156. package/dist/platforms/xhs/web/commands.js +1046 -0
  157. package/dist/platforms/xhs/web/creator-api.js +609 -0
  158. package/dist/platforms/xhs/web/creator.js +203 -0
  159. package/dist/platforms/xhs/web/js.js +194 -0
  160. package/dist/platforms/xhs/web/login.js +230 -0
  161. package/dist/platforms/xhs/web/normalize.js +166 -0
  162. package/dist/platforms/xhs/web/profile.js +127 -0
  163. package/dist/platforms/xhs/web/push.js +361 -0
  164. package/dist/platforms/xhs/web/resolve.js +69 -0
  165. package/dist/platforms/xhs/web/state.js +368 -0
  166. package/dist/platforms/xianyu/index.js +59 -0
  167. package/dist/platforms/xianyu/web/api.js +312 -0
  168. package/dist/platforms/xianyu/web/client.js +134 -0
  169. package/dist/platforms/xianyu/web/commands.js +305 -0
  170. package/dist/platforms/xianyu/web/im.js +73 -0
  171. package/dist/platforms/xianyu/web/normalize.js +123 -0
  172. package/dist/platforms/xianyu/web/profile.js +146 -0
  173. package/dist/platforms/xianyu/web/resolve.js +48 -0
  174. package/dist/platforms/xianyu/web/sign.js +79 -0
  175. package/package.json +77 -4
  176. package/static/douyin/Live.proto +194 -0
  177. package/static/douyin/Request.proto +89 -0
  178. package/static/douyin/Response.proto +46 -0
  179. package/static/douyin/acrawler_runtime/ac_vm.js +2 -0
  180. package/static/douyin/acrawler_runtime/browser_window_shape.json +1 -0
  181. package/static/douyin/acrawler_runtime/canvas_actual_exact.json +1 -0
  182. package/static/douyin/acrawler_runtime/run_ac_node.js +1005 -0
  183. package/static/douyin/acrawler_runtime/runner_window_keys_baseline.txt +240 -0
  184. package/static/douyin/challenge_profile.json +801 -0
  185. package/static/douyin/challenge_template_runner.js +217 -0
  186. package/static/douyin/dtrait_profile.json +66 -0
  187. package/static/douyin/mstoken_common_profile.json +1 -0
  188. package/static/douyin/mstoken_profile.json +214 -0
  189. package/static/jd/h5st5_env.js +750 -0
  190. package/static/jd/h5st5_lib.js +5 -0
  191. package/static/jd/h5st5_server.js +49 -0
  192. package/static/jd/jcap/env/env_core.js +512 -0
  193. package/static/jd/jcap/env/run.js +1307 -0
  194. package/static/jd/jcap/run/jcap_ujb96b.js +39 -0
  195. package/static/jd/package.json +4 -0
  196. package/static/jd/pc_tk_lib.js +1 -0
  197. package/static/jd/pc_tk_server.js +63 -0
  198. package/static/jd/summer_cryptico_runner.js +50 -0
  199. package/static/jd/webm/env/run.js +453 -0
  200. package/static/jd/webm/run/jdwebm-riskhandle.js +49 -0
  201. package/static/kuaishou/bundles/weapon/kwf-0.0.2.2cee19b4b7dec496.js +1 -0
  202. package/static/kuaishou/bundles/weapon/kws-0-0.0.1-obfuscated.4b7f3de1ab0ddcc2.js +1 -0
  203. package/static/kuaishou/bundles/weapon/kws-1-0.0.1-obfuscated.346ebdb1c78df316.js +1 -0
  204. package/static/kuaishou/bundles/weapon/kws-10-0.0.1-obfuscated.a33db41897b983af.js +1 -0
  205. package/static/kuaishou/bundles/weapon/kws-11-0.0.1-obfuscated.5e0a90af726d8a7e.js +1 -0
  206. package/static/kuaishou/bundles/weapon/kws-12-0.0.1-obfuscated.20ea29345706ec8c.js +1 -0
  207. package/static/kuaishou/bundles/weapon/kws-13-0.0.1-obfuscated.6b74e9640ff18648.js +1 -0
  208. package/static/kuaishou/bundles/weapon/kws-14-0.0.1-obfuscated.551e4429d156bf66.js +1 -0
  209. package/static/kuaishou/bundles/weapon/kws-15-0.0.1-obfuscated.8625b087aaba4a60.js +1 -0
  210. package/static/kuaishou/bundles/weapon/kws-16-0.0.1-obfuscated.d5ffa4020f3be99a.js +1 -0
  211. package/static/kuaishou/bundles/weapon/kws-17-0.0.1-obfuscated.6d13e19b22f50a80.js +1 -0
  212. package/static/kuaishou/bundles/weapon/kws-18-0.0.1-obfuscated.6d31405044166289.js +1 -0
  213. package/static/kuaishou/bundles/weapon/kws-19-0.0.1-obfuscated.a9a8d925942f19e4.js +1 -0
  214. package/static/kuaishou/bundles/weapon/kws-2-0.0.1-obfuscated.b849a136ae4a6b3e.js +1 -0
  215. package/static/kuaishou/bundles/weapon/kws-3-0.0.1-obfuscated.f9e77ebf6186e2ac.js +1 -0
  216. package/static/kuaishou/bundles/weapon/kws-4-0.0.1-obfuscated.2c3c155aa52ceb0e.js +1 -0
  217. package/static/kuaishou/bundles/weapon/kws-5-0.0.1-obfuscated.4e553d17691b3c5a.js +1 -0
  218. package/static/kuaishou/bundles/weapon/kws-6-0.0.1-obfuscated.f73ddd3ff13e1217.js +1 -0
  219. package/static/kuaishou/bundles/weapon/kws-7-0.0.1-obfuscated.1628b8729beaab7e.js +1 -0
  220. package/static/kuaishou/bundles/weapon/kws-8-0.0.1-obfuscated.6da6baef7aa81fff.js +1 -0
  221. package/static/kuaishou/bundles/weapon/kws-9-0.0.1-obfuscated.8645d55e5323b743.js +1 -0
  222. package/static/kuaishou/fixtures/current_follow_script_813.network-response +2 -0
  223. package/static/kuaishou/fixtures/live_ws_maps.json +61 -0
  224. package/static/kuaishou/fixtures/live_ws_proto.json +1342 -0
  225. package/static/kuaishou/js/cp-kwf.js +1 -0
  226. package/static/kuaishou/tools/kwf_oracle.js +799 -0
  227. package/static/kuaishou/tools/kws_oracle.js +885 -0
  228. package/static/kuaishou/tools/like_token_oracle.js +70 -0
  229. package/static/taobao/taobao_js_20260407.js +570 -0
  230. package/static/tiktok/Tiktok_Request.json +597 -0
  231. package/static/tiktok/package.json +3 -0
  232. package/static/tiktok/shop_bsid/core.js +1 -0
  233. package/static/tiktok/shop_bsid/env_core.js +512 -0
  234. package/static/tiktok/shop_bsid/loader.js +1 -0
  235. package/static/tiktok/shop_bsid/run.js +753 -0
  236. package/static/tiktok/shop_bsid/sign.js +100 -0
  237. package/static/tiktok/shop_bsid/webmssdk.js +1 -0
  238. package/static/tiktok/shop_bsid/webmssdk_ex.js +1 -0
  239. package/static/tiktok/signing/env/env_core.js +512 -0
  240. package/static/tiktok/signing/env/sign.js +455 -0
  241. package/static/tiktok/signing/sdk_config.json +230 -0
  242. package/static/tiktok/signing/source/webmssdk.js +1 -0
  243. package/static/tiktok/signing/source/webmssdk_ex.js +1 -0
  244. package/static/tiktok/signing/source/webmssdk_legacy.js +1 -0
  245. package/static/x/graphql.json +7777 -0
  246. package/static/x/transaction_l1.json +12 -0
  247. package/static/xhs/package.json +3 -0
  248. package/static/xhs/xhs_core/js/b1.js +210 -0
  249. package/static/xhs/xhs_core/js/mns.js +340 -0
  250. package/static/xhs/xhs_core/js/mns_0101_keystream.json +5 -0
  251. package/static/xhs/xhs_core/js/mns_keystreams.json +1 -0
  252. package/static/xhs/xhs_core/js/sign.js +225 -0
  253. package/static/xhs/xhs_core/js/websectiga_cli.js +220 -0
  254. package/static/xhs/xhs_core/js/websectiga_env.js +512 -0
  255. package/static/xhs/xhs_core/js/xs_common.js +79 -0
  256. package/static/xhs/xhs_creator/js/profile.js +115 -0
  257. package/static/xhs/xhs_creator/js/rap_fingerprint_creator.json +6 -0
  258. package/static/xhs/xhs_creator/js/reference_profile.json +282 -0
  259. package/static/xhs/xhs_creator/js/xhs_creator_sign.js +29 -0
  260. package/static/xhs/xhs_creator/js/xhs_creator_signature.js +23 -0
  261. package/static/xhs/xhs_pc/js/aes_decrypt.js +22 -0
  262. package/static/xhs/xhs_pc/js/aes_encrypt.js +30 -0
  263. package/static/xhs/xhs_pc/js/b1.js +9 -0
  264. package/static/xhs/xhs_pc/js/deflate.js +320 -0
  265. package/static/xhs/xhs_pc/js/mns.js +4 -0
  266. package/static/xhs/xhs_pc/js/profile.js +141 -0
  267. package/static/xhs/xhs_pc/js/rap.js +173 -0
  268. package/static/xhs/xhs_pc/js/rap_cli.js +30 -0
  269. package/static/xhs/xhs_pc/js/rap_crypto.js +73 -0
  270. package/static/xhs/xhs_pc/js/rap_fingerprint_template.json +8 -0
  271. package/static/xhs/xhs_pc/js/reference_profile.json +262 -0
  272. package/static/xhs/xhs_pc/js/sign.js +6 -0
  273. package/static/xhs/xhs_pc/js/web_ssk.js +82 -0
  274. package/static/xhs/xhs_pc/js/xs_common.js +4 -0
  275. package/static/xianyu/et_f.js +2 -0
  276. package/static/xianyu/gen_tfstk.js +410 -0
  277. package/static/xianyu/goofish_js_version_2.js +568 -0
@@ -0,0 +1,512 @@
1
+ /**
2
+ * env_core.js — 环境补齐引擎(v2)
3
+ *
4
+ * 纯工具集 + Proxy 引擎 + 诊断报告。不含任何环境存根。
5
+ * 存根由 Claude 在 run.js 中按诊断报告按需编写。
6
+ *
7
+ * 导出:
8
+ * setFuncNative(fn, name, len) — 函数伪装三件套
9
+ * setObjNative(obj, name) — 对象伪装两件套
10
+ * getNativeProto(ctorName, attrs) — 原型链工厂
11
+ * wrapFunc(obj, method, callback) — 方法包装
12
+ * monitor(target, name, config) — 定向监控 Proxy
13
+ * createProxy(target, name, depth) — 递归 Proxy 工厂
14
+ * init(config) — 最小初始化(Node 泄露阻断 + 全局引用)
15
+ * report() — 诊断报告
16
+ */
17
+
18
+ const __env__ = (function () {
19
+
20
+ // ==================== 数据收集 ====================
21
+ const _errors = []; // { path, operation, message }
22
+ const _undefinedGets = {}; // path -> count
23
+ const _functionCalls = {}; // path -> { count, args[] }
24
+ const _successfulGets = {}; // path -> count
25
+
26
+ const _proxyCache = new WeakMap(); // target -> proxy
27
+
28
+ // ==================== 函数伪装 ====================
29
+ // 参考 sdenv setFunc.js:name + length + toString 三件套
30
+
31
+ const _origToString = Function.prototype.toString;
32
+ const _nativeNames = new Set();
33
+
34
+ const nativeToString = function toString() {
35
+ if (_nativeNames.has(this)) {
36
+ const name = this.name || '';
37
+ return `function ${name}() { [native code] }`;
38
+ }
39
+ return _origToString.call(this);
40
+ };
41
+ // toString 自身也要伪装
42
+ Object.defineProperty(nativeToString, 'name', { value: 'toString', configurable: true });
43
+ _nativeNames.add(nativeToString);
44
+
45
+ /**
46
+ * 函数伪装三件套:name + length + toString
47
+ * @param {Function} fn - 目标函数
48
+ * @param {string} [name] - 函数名(不传则保留原名)
49
+ * @param {number} [len] - 参数个数
50
+ */
51
+ function setFuncNative(fn, name, len) {
52
+ if (!fn) return undefined;
53
+ if (typeof name === 'number') { len = name; name = undefined; }
54
+ if (typeof name === 'string') {
55
+ Object.defineProperty(fn, 'name', { value: name, configurable: true });
56
+ }
57
+ if (typeof len === 'number') {
58
+ Object.defineProperty(fn, 'length', { value: len, configurable: true });
59
+ }
60
+ _nativeNames.add(fn);
61
+ Object.defineProperty(fn, 'toString', {
62
+ enumerable: false, configurable: true, writable: true,
63
+ value: nativeToString,
64
+ });
65
+ return fn;
66
+ }
67
+
68
+ // 全局接管 Function.prototype.toString
69
+ Function.prototype.toString = nativeToString;
70
+
71
+ // ==================== 对象伪装 ====================
72
+ // 参考 sdenv setObj.js:toString + Symbol.toStringTag 两件套
73
+
74
+ /**
75
+ * 对象伪装两件套:toString + Symbol.toStringTag
76
+ * @param {Object} obj - 目标对象
77
+ * @param {string} name - 类型名(如 "Navigator", "HTMLDocument")
78
+ */
79
+ function setObjNative(obj, name) {
80
+ Object.defineProperty(obj, 'toString', {
81
+ enumerable: false, configurable: true, writable: true,
82
+ value() { return `[object ${name}]`; }
83
+ });
84
+ Object.defineProperty(obj, Symbol.toStringTag, {
85
+ configurable: true, enumerable: false, writable: false,
86
+ value: name
87
+ });
88
+ return obj;
89
+ }
90
+
91
+ // ==================== 原型链工厂 ====================
92
+ // 参考 sdenv getNativeProto.js:Constructor + prototype 实例
93
+
94
+ /**
95
+ * 创建带原型链的构造函数 + 实例
96
+ * @param {string} ctorName - 构造函数名(如 "Navigator")
97
+ * @param {Object} [attrs] - 实例属性
98
+ * @returns {[Function, Object]} [Constructor, instance]
99
+ */
100
+ function getNativeProto(ctorName, attrs) {
101
+ attrs = attrs || {};
102
+ const ctor = setFuncNative(function () {
103
+ throw new TypeError('Illegal constructor');
104
+ }, ctorName, 0);
105
+ const instance = Object.create(ctor.prototype);
106
+ setObjNative(instance, ctorName);
107
+ Object.assign(instance, attrs);
108
+ return [ctor, instance];
109
+ }
110
+
111
+ // ==================== 方法包装 ====================
112
+ // 参考 sdenv setFunc.js wrapFunc:保留原引用 + 自动伪装
113
+
114
+ /**
115
+ * 包装对象方法,保留原函数引用
116
+ * @param {Object} obj - 宿主对象
117
+ * @param {string} method - 方法名
118
+ * @param {Function} callback - (origFn, ...args) => result
119
+ */
120
+ function wrapFunc(obj, method, callback) {
121
+ const orig = obj[method];
122
+ const wrap = function (...args) {
123
+ return callback.call(this, orig.bind(this), ...args);
124
+ };
125
+ setFuncNative(wrap, method, orig ? orig.length : 0);
126
+ obj[method] = wrap;
127
+ return wrap;
128
+ }
129
+
130
+ // ==================== 辅助函数 ====================
131
+
132
+ function summarize(v) {
133
+ if (v === undefined) return 'undefined';
134
+ if (v === null) return 'null';
135
+ const t = typeof v;
136
+ if (t === 'function') return `fn:${v.name || '?'}`;
137
+ if (t === 'string') return v.length > 60 ? `"${v.slice(0, 60)}…"` : `"${v}"`;
138
+ if (t === 'number' || t === 'boolean') return String(v);
139
+ if (t === 'symbol') return v.toString();
140
+ if (Array.isArray(v)) return `Array(${v.length})`;
141
+ try {
142
+ const name = v.constructor?.name;
143
+ return name && name !== 'Object' ? `[${name}]` : '{…}';
144
+ } catch { return '{…}'; }
145
+ }
146
+
147
+ function recordUndefined(path) {
148
+ _undefinedGets[path] = (_undefinedGets[path] || 0) + 1;
149
+ }
150
+ function recordSuccess(path) {
151
+ _successfulGets[path] = (_successfulGets[path] || 0) + 1;
152
+ }
153
+ function recordCall(path, args) {
154
+ if (!_functionCalls[path]) _functionCalls[path] = { count: 0, args: [] };
155
+ const entry = _functionCalls[path];
156
+ entry.count++;
157
+ if (entry.args.length < 3) {
158
+ const summary = args.map(summarize).join(', ');
159
+ if (!entry.args.includes(summary)) entry.args.push(summary);
160
+ }
161
+ }
162
+ function recordError(path, operation, err) {
163
+ const msg = err instanceof Error ? err.message : String(err);
164
+ const key = `${path}|${msg}`;
165
+ if (!_errors.some(e => `${e.path}|${e.message}` === key)) {
166
+ _errors.push({ path, operation, message: msg });
167
+ }
168
+ }
169
+
170
+ // 不记录的属性(引擎内部 / 会导致递归)
171
+ const SKIP = new Set([
172
+ 'constructor', 'prototype', '__proto__',
173
+ 'toJSON', 'hasOwnProperty', 'isPrototypeOf',
174
+ 'propertyIsEnumerable', 'valueOf',
175
+ 'inspect', 'then', 'asymmetricMatch', 'nodeType',
176
+ '$$typeof', '@@__IMMUTABLE_ITERABLE__@@',
177
+ ]);
178
+
179
+ // 不自动递归 Proxy 的对象
180
+ const NO_RECURSE_CTORS = new Set([
181
+ 'ArrayBuffer', 'SharedArrayBuffer', 'DataView',
182
+ 'Int8Array', 'Uint8Array', 'Uint8ClampedArray',
183
+ 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array',
184
+ 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array',
185
+ 'Map', 'Set', 'WeakMap', 'WeakSet',
186
+ 'Date', 'RegExp', 'Promise',
187
+ 'Error', 'TypeError', 'RangeError', 'ReferenceError', 'SyntaxError',
188
+ ]);
189
+
190
+ function shouldProxy(obj) {
191
+ if (obj === null || obj === undefined) return false;
192
+ const t = typeof obj;
193
+ if (t !== 'object' && t !== 'function') return false;
194
+ try {
195
+ const name = obj.constructor?.name;
196
+ if (name && NO_RECURSE_CTORS.has(name)) return false;
197
+ } catch {}
198
+ return true;
199
+ }
200
+
201
+ // ==================== 定向监控 Proxy ====================
202
+ // 参考 sdenv monitor.js:可配置 log/keys/parse/cb/handles
203
+
204
+ /**
205
+ * 定向监控 Proxy —— 对已有对象包一层可配置的 Proxy
206
+ * @param {Object} target - 监控目标
207
+ * @param {string} name - 显示名
208
+ * @param {Object} config
209
+ * config.log — 开启 get/set 日志
210
+ * config.getLog — 仅 get 日志
211
+ * config.setLog — 仅 set 日志
212
+ * config.keys — 触发 debugger 的属性名数组
213
+ * config.getKeys — 仅 get 触发
214
+ * config.setKeys — 仅 set 触发
215
+ * config.cb — 通用回调 (property, value, name)
216
+ * config.getCb — get 回调
217
+ * config.setCb — set 回调
218
+ * config.getParse — get 返回值变换 (key, val) => newVal
219
+ * config.setParse — set 值变换 (key, val) => newVal
220
+ * config.handles — 额外 Proxy handler(展开合并)
221
+ */
222
+ function monitor(target, name, config) {
223
+ config = config || {};
224
+ const {
225
+ getLog, setLog, log,
226
+ getKeys = [], setKeys = [], keys = [],
227
+ getCb, setCb, cb,
228
+ getParse = (k, v) => v,
229
+ setParse = (k, v) => v,
230
+ handles = {},
231
+ } = config;
232
+
233
+ return new Proxy(target, {
234
+ get(obj, prop, receiver) {
235
+ if (typeof prop === 'symbol') return Reflect.get(obj, prop, receiver);
236
+ if (getLog || log) console.log(`[monitor] ${name}.${prop} GET`);
237
+ if (getKeys.includes(prop) || keys.includes(prop)) debugger;
238
+ (getCb || cb)?.(prop, name);
239
+ return getParse(prop, Reflect.get(obj, prop, receiver), obj);
240
+ },
241
+ set(obj, prop, value, receiver) {
242
+ if (typeof prop === 'symbol') return Reflect.set(obj, prop, value, receiver);
243
+ if (setLog || log) console.log(`[monitor] ${name}.${prop} SET =`, value);
244
+ if (setKeys.includes(prop) || keys.includes(prop)) debugger;
245
+ (setCb || cb)?.(prop, value, name);
246
+ return Reflect.set(obj, prop, setParse(prop, value, obj), receiver);
247
+ },
248
+ ...handles,
249
+ });
250
+ }
251
+
252
+ // ==================== 递归 Proxy 工厂 ====================
253
+ // 从现有 proxy_monitor.js 演化,补全到 8 trap
254
+
255
+ /**
256
+ * 递归 Proxy 工厂 —— 自动追踪所有属性访问和函数调用
257
+ * @param {Object} target - 包裹目标
258
+ * @param {string} name - 路径名(如 "window")
259
+ * @param {number} [depth=0] - 递归深度(>8 停止)
260
+ */
261
+ function createProxy(target, name, depth) {
262
+ depth = depth || 0;
263
+ if (depth > 8) return target;
264
+ if (!shouldProxy(target)) return target;
265
+ if (_proxyCache.has(target)) return _proxyCache.get(target);
266
+
267
+ const proxy = new Proxy(target, {
268
+ get(obj, prop, receiver) {
269
+ if (typeof prop === 'symbol') {
270
+ if (prop === Symbol.toStringTag) {
271
+ const tag = Reflect.get(obj, prop, receiver);
272
+ return tag !== undefined ? tag : undefined;
273
+ }
274
+ return Reflect.get(obj, prop, receiver);
275
+ }
276
+ if (SKIP.has(prop)) return Reflect.get(obj, prop, receiver);
277
+
278
+ const chain = `${name}.${prop}`;
279
+ let value;
280
+ try {
281
+ value = Reflect.get(obj, prop, receiver);
282
+ } catch (err) {
283
+ recordError(chain, 'get', err);
284
+ return undefined;
285
+ }
286
+
287
+ if (value === undefined) {
288
+ recordUndefined(chain);
289
+ } else {
290
+ recordSuccess(chain);
291
+ }
292
+
293
+ if (typeof value === 'function') {
294
+ const needsBind = (obj instanceof Map || obj instanceof Set ||
295
+ obj instanceof Date || obj instanceof RegExp ||
296
+ obj instanceof Promise || ArrayBuffer.isView(obj));
297
+
298
+ const wrappedFn = function (...args) {
299
+ recordCall(chain, args);
300
+ try {
301
+ const thisArg = (this === proxy) ? obj : this;
302
+ const result = needsBind
303
+ ? value.apply(obj, args)
304
+ : value.apply(thisArg, args);
305
+ if (shouldProxy(result)) {
306
+ try { return createProxy(result, chain + '()', depth + 1); }
307
+ catch { return result; }
308
+ }
309
+ return result;
310
+ } catch (err) {
311
+ recordError(chain, 'call', err);
312
+ throw err;
313
+ }
314
+ };
315
+ setFuncNative(wrappedFn, prop);
316
+ return wrappedFn;
317
+ }
318
+
319
+ if (shouldProxy(value)) {
320
+ try { return createProxy(value, chain, depth + 1); }
321
+ catch { return value; }
322
+ }
323
+ return value;
324
+ },
325
+
326
+ set(obj, prop, value, receiver) {
327
+ if (typeof prop === 'symbol') return Reflect.set(obj, prop, value, receiver);
328
+ try {
329
+ return Reflect.set(obj, prop, value, receiver);
330
+ } catch (err) {
331
+ recordError(`${name}.${prop}`, 'set', err);
332
+ return false;
333
+ }
334
+ },
335
+
336
+ has(obj, prop) {
337
+ return Reflect.has(obj, prop);
338
+ },
339
+
340
+ deleteProperty(obj, prop) {
341
+ return Reflect.deleteProperty(obj, prop);
342
+ },
343
+
344
+ getOwnPropertyDescriptor(obj, prop) {
345
+ return Reflect.getOwnPropertyDescriptor(obj, prop);
346
+ },
347
+
348
+ defineProperty(obj, prop, desc) {
349
+ return Reflect.defineProperty(obj, prop, desc);
350
+ },
351
+
352
+ ownKeys(obj) {
353
+ return Reflect.ownKeys(obj);
354
+ },
355
+
356
+ getPrototypeOf(obj) {
357
+ return Reflect.getPrototypeOf(obj);
358
+ },
359
+
360
+ ...(typeof target === 'function' ? {
361
+ apply(fn, thisArg, args) {
362
+ recordCall(name, args);
363
+ try {
364
+ const result = Reflect.apply(fn, thisArg, args);
365
+ if (shouldProxy(result)) {
366
+ try { return createProxy(result, name + '()', depth + 1); }
367
+ catch { return result; }
368
+ }
369
+ return result;
370
+ } catch (err) {
371
+ recordError(name, 'call', err);
372
+ throw err;
373
+ }
374
+ },
375
+ construct(fn, args, newTarget) {
376
+ recordCall(`new ${name}`, args);
377
+ try {
378
+ const result = Reflect.construct(fn, args, newTarget);
379
+ if (shouldProxy(result)) {
380
+ try { return createProxy(result, `new ${name}()`, depth + 1); }
381
+ catch { return result; }
382
+ }
383
+ return result;
384
+ } catch (err) {
385
+ recordError(`new ${name}`, 'construct', err);
386
+ throw err;
387
+ }
388
+ }
389
+ } : {})
390
+ });
391
+
392
+ _proxyCache.set(target, proxy);
393
+ return proxy;
394
+ }
395
+
396
+ // ==================== 最小初始化 ====================
397
+
398
+ /**
399
+ * 最小初始化 —— 只做 Node 泄露阻断和全局引用挂载
400
+ * 不创建任何存根对象,存根由 run.js 按需编写
401
+ * @param {Object} [config]
402
+ * config.window — 已构建好的 window 对象
403
+ * config.document — 已构建好的 document 对象
404
+ * config.navigator — 已构建好的 navigator 对象
405
+ * config.location — 已构建好的 location 对象
406
+ */
407
+ function init(config) {
408
+ config = config || {};
409
+
410
+ // Node.js 特征隐藏
411
+ const nodeFeatures = ['process', 'Buffer', '__dirname', '__filename'];
412
+ for (const feat of nodeFeatures) {
413
+ if (feat in global) {
414
+ try {
415
+ Object.defineProperty(global, feat, {
416
+ value: undefined, writable: false, enumerable: false, configurable: true
417
+ });
418
+ } catch {}
419
+ }
420
+ }
421
+
422
+ // 挂载全局引用
423
+ const globals = {};
424
+ if (config.window) {
425
+ globals.window = config.window;
426
+ globals.self = config.window;
427
+ globals.top = config.window;
428
+ globals.parent = config.window;
429
+ globals.globalThis = config.window;
430
+ }
431
+ if (config.document) globals.document = config.document;
432
+ if (config.navigator) globals.navigator = config.navigator;
433
+ if (config.location) globals.location = config.location;
434
+
435
+ for (const [k, v] of Object.entries(globals)) {
436
+ Object.defineProperty(global, k, {
437
+ value: v, writable: true, configurable: true, enumerable: true
438
+ });
439
+ }
440
+ }
441
+
442
+ // ==================== 诊断报告 ====================
443
+
444
+ function report() {
445
+ const lines = [];
446
+ const errorCount = _errors.length;
447
+ const undefCount = Object.keys(_undefinedGets).length;
448
+ const callCount = Object.keys(_functionCalls).length;
449
+ const okCount = Object.keys(_successfulGets).length;
450
+
451
+ lines.push('');
452
+ lines.push('========== ENV PATCH REPORT ==========');
453
+ lines.push('');
454
+
455
+ if (errorCount > 0) {
456
+ lines.push(`[ERRORS] (${errorCount}) — must fix:`);
457
+ for (const e of _errors) {
458
+ lines.push(` ${e.path} [${e.operation}] → ${e.message}`);
459
+ }
460
+ lines.push('');
461
+ }
462
+
463
+ if (undefCount > 0) {
464
+ lines.push(`[UNDEFINED] (${undefCount}) — likely need patching:`);
465
+ const sorted = Object.entries(_undefinedGets).sort((a, b) => b[1] - a[1]);
466
+ for (const [path, count] of sorted) {
467
+ lines.push(` ${path} (×${count})`);
468
+ }
469
+ lines.push('');
470
+ }
471
+
472
+ if (callCount > 0) {
473
+ lines.push(`[CALLS] (${callCount}) — function calls observed:`);
474
+ const sorted = Object.entries(_functionCalls).sort((a, b) => b[1].count - a[1].count);
475
+ for (const [path, info] of sorted) {
476
+ const argSamples = info.args.length > 0 ? ` args: [${info.args.join('] [')}]` : '';
477
+ lines.push(` ${path} (×${info.count})${argSamples}`);
478
+ }
479
+ lines.push('');
480
+ }
481
+
482
+ lines.push(`Summary: ${errorCount} errors, ${undefCount} undefined, ${callCount} calls, ${okCount} ok (hidden)`);
483
+ lines.push('=======================================');
484
+ lines.push('');
485
+
486
+ console.log(lines.join('\n'));
487
+ return { errors: _errors, undefined: _undefinedGets, calls: _functionCalls };
488
+ }
489
+
490
+ process.on('exit', report);
491
+
492
+ function _reset() {
493
+ _errors.length = 0;
494
+ for (const k in _undefinedGets) delete _undefinedGets[k];
495
+ for (const k in _functionCalls) delete _functionCalls[k];
496
+ for (const k in _successfulGets) delete _successfulGets[k];
497
+ }
498
+
499
+ return {
500
+ setFuncNative,
501
+ setObjNative,
502
+ getNativeProto,
503
+ wrapFunc,
504
+ monitor,
505
+ createProxy,
506
+ init,
507
+ report,
508
+ _reset,
509
+ };
510
+ })();
511
+
512
+ module.exports = __env__;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * XHS Web 共用 X-S-Common 纯算(还原自 launcher XsCommon):
3
+ * customB64( utf8( JSON.stringify({s0..x12}) ) )
4
+ * x9 = 变体 CRC32(b1)(多项式 0xedb88320,末值 ~c ^ 0xedb88320)
5
+ * 无 VM / 无静态混淆 JS。
6
+ */
7
+ 'use strict';
8
+
9
+ const XS_ALPHABET = 'ZmserbBoHQtNP+wOcza/LpngG8yJq42KWYj0DSfdikx3VT16IlUAFM97hECvuRX5';
10
+
11
+ const _crcTable = (() => {
12
+ const a = 0xedb88320;
13
+ const s = new Array(256);
14
+ for (let d = 0; d < 256; d++) {
15
+ let r = d;
16
+ for (let c = 8; c > 0; c--) r = 1 & r ? (r >>> 1) ^ a : r >>> 1;
17
+ s[d] = r >>> 0;
18
+ }
19
+ return s;
20
+ })();
21
+
22
+ function gens9(str) {
23
+ const a = 0xedb88320;
24
+ let c = -1;
25
+ for (let r = 0; r < str.length; r++) {
26
+ c = _crcTable[(255 & c) ^ str.charCodeAt(r)] ^ (c >>> 8);
27
+ }
28
+ return (-1 ^ c ^ a) | 0; // signed int32,与 JS 一致
29
+ }
30
+
31
+ function encodeUtf8(e) {
32
+ const r = encodeURIComponent(e), a = [];
33
+ for (let i = 0; i < r.length; i++) { const ch = r.charAt(i); if (ch === '%') { a.push(parseInt(r.charAt(i + 1) + r.charAt(i + 2), 16)); i += 2; } else a.push(ch.charCodeAt(0)); }
34
+ return a;
35
+ }
36
+ function b64Custom(e) {
37
+ const A = XS_ALPHABET, a = e.length, c = a % 3, d = []; const s = 16383; let u = 0; const l = a - c;
38
+ for (u = 0; u < l; u += s) { const end = u + s > l ? l : u + s; for (let k = u; k < end; k += 3) { const t = (e[k] << 16) + ((k + 1 < end ? e[k + 1] : 0) << 8) + (k + 2 < end ? e[k + 2] : 0); d.push(A[(t >> 18) & 63], A[(t >> 12) & 63], A[(t >> 6) & 63], A[t & 63]); } }
39
+ if (c === 1) { const t = e[a - 1]; d.push(A[t >> 2] + A[(t << 4) & 63] + '=='); }
40
+ else if (c === 2) { const t = (e[a - 2] << 8) + e[a - 1]; d.push(A[t >> 10] + A[(t >> 4) & 63] + A[(t << 2) & 63] + '='); }
41
+ return d.join('');
42
+ }
43
+
44
+ function xsCommon(a1, xt, xs, dslPair, b1, options = {}) {
45
+ // Login/security cold paths still send X-S-Common before the b1 collector
46
+ // has produced a snapshot. In that phase x8 is the empty string and x9 is
47
+ // its normal CRC variant; an empty b1 is therefore a real browser state,
48
+ // not a missing-value fallback.
49
+ if (b1 == null) throw new Error('xsCommon: b1 必须显式传入(允许空字符串)');
50
+ if (!dslPair) throw new Error('xsCommon: dslPair 必传');
51
+ const b1Value = String(b1);
52
+ const config = typeof options === 'string' ? { webBuild: options } : options;
53
+ const webBuild = String(config.webBuild || '6.47.2');
54
+ // 2026-07-25 浏览器实证(zones/seccallback X-S-Common 解码):
55
+ // b1 未采集阶段浏览器发 x8: null(JSON null)且 x9 = gens9('null'),
56
+ // 不是空字符串。服务端两种都容忍,字节级对齐以浏览器为准。
57
+ const coldB1 = b1Value === '';
58
+ const d = {
59
+ s0: 5,
60
+ s1: '',
61
+ x0: String(config.b1b1 || '1'),
62
+ x1: String(config.signVersion || '4.4.3'),
63
+ x2: String(config.platform || 'Windows'),
64
+ x3: String(config.appId || 'xhs-pc-web'),
65
+ x4: webBuild,
66
+ x5: a1,
67
+ x6: '',
68
+ x7: '',
69
+ x8: coldB1 ? null : b1Value,
70
+ x9: gens9(coldB1 ? 'null' : b1Value),
71
+ x10: Number(config.signCount || 0),
72
+ x11: 'normal',
73
+ x12: dslPair,
74
+ };
75
+ return b64Custom(encodeUtf8(JSON.stringify(d)));
76
+ }
77
+
78
+ module.exports = { xsCommon, gens9 };
79
+