deepspider 0.1.0

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 (261) hide show
  1. package/.claude/agents/check.md +122 -0
  2. package/.claude/agents/debug.md +106 -0
  3. package/.claude/agents/dispatch.md +214 -0
  4. package/.claude/agents/implement.md +96 -0
  5. package/.claude/agents/plan.md +396 -0
  6. package/.claude/agents/research.md +120 -0
  7. package/.claude/commands/evolve/merge.md +80 -0
  8. package/.claude/commands/trellis/before-backend-dev.md +13 -0
  9. package/.claude/commands/trellis/before-frontend-dev.md +13 -0
  10. package/.claude/commands/trellis/break-loop.md +107 -0
  11. package/.claude/commands/trellis/check-backend.md +13 -0
  12. package/.claude/commands/trellis/check-cross-layer.md +153 -0
  13. package/.claude/commands/trellis/check-frontend.md +13 -0
  14. package/.claude/commands/trellis/create-command.md +154 -0
  15. package/.claude/commands/trellis/finish-work.md +129 -0
  16. package/.claude/commands/trellis/integrate-skill.md +219 -0
  17. package/.claude/commands/trellis/onboard.md +358 -0
  18. package/.claude/commands/trellis/parallel.md +193 -0
  19. package/.claude/commands/trellis/record-session.md +62 -0
  20. package/.claude/commands/trellis/start.md +280 -0
  21. package/.claude/commands/trellis/update-spec.md +213 -0
  22. package/.claude/hooks/inject-subagent-context.py +758 -0
  23. package/.claude/hooks/ralph-loop.py +374 -0
  24. package/.claude/hooks/session-start.py +126 -0
  25. package/.claude/settings.json +41 -0
  26. package/.claude/skills/deepagents-guide/SKILL.md +428 -0
  27. package/.cursor/commands/trellis-before-backend-dev.md +13 -0
  28. package/.cursor/commands/trellis-before-frontend-dev.md +13 -0
  29. package/.cursor/commands/trellis-break-loop.md +107 -0
  30. package/.cursor/commands/trellis-check-backend.md +13 -0
  31. package/.cursor/commands/trellis-check-cross-layer.md +153 -0
  32. package/.cursor/commands/trellis-check-frontend.md +13 -0
  33. package/.cursor/commands/trellis-create-command.md +154 -0
  34. package/.cursor/commands/trellis-finish-work.md +129 -0
  35. package/.cursor/commands/trellis-integrate-skill.md +219 -0
  36. package/.cursor/commands/trellis-onboard.md +358 -0
  37. package/.cursor/commands/trellis-record-session.md +62 -0
  38. package/.cursor/commands/trellis-start.md +156 -0
  39. package/.cursor/commands/trellis-update-spec.md +213 -0
  40. package/.env.example +11 -0
  41. package/.husky/pre-commit +1 -0
  42. package/.mcp.json +8 -0
  43. package/.trellis/.template-hashes.json +65 -0
  44. package/.trellis/.version +1 -0
  45. package/.trellis/scripts/add-session.sh +384 -0
  46. package/.trellis/scripts/common/developer.sh +129 -0
  47. package/.trellis/scripts/common/git-context.sh +263 -0
  48. package/.trellis/scripts/common/paths.sh +208 -0
  49. package/.trellis/scripts/common/phase.sh +150 -0
  50. package/.trellis/scripts/common/registry.sh +247 -0
  51. package/.trellis/scripts/common/task-queue.sh +142 -0
  52. package/.trellis/scripts/common/task-utils.sh +151 -0
  53. package/.trellis/scripts/common/worktree.sh +128 -0
  54. package/.trellis/scripts/create-bootstrap.sh +299 -0
  55. package/.trellis/scripts/get-context.sh +7 -0
  56. package/.trellis/scripts/get-developer.sh +15 -0
  57. package/.trellis/scripts/init-developer.sh +34 -0
  58. package/.trellis/scripts/multi-agent/cleanup.sh +396 -0
  59. package/.trellis/scripts/multi-agent/create-pr.sh +241 -0
  60. package/.trellis/scripts/multi-agent/plan.sh +207 -0
  61. package/.trellis/scripts/multi-agent/start.sh +310 -0
  62. package/.trellis/scripts/multi-agent/status.sh +828 -0
  63. package/.trellis/scripts/task.sh +1118 -0
  64. package/.trellis/spec/backend/deepagents-guide.md +337 -0
  65. package/.trellis/spec/backend/directory-structure.md +126 -0
  66. package/.trellis/spec/backend/examples/skills/deepagents-guide/README.md +11 -0
  67. package/.trellis/spec/backend/examples/skills/deepagents-guide/agent.js.template +20 -0
  68. package/.trellis/spec/backend/examples/skills/deepagents-guide/skills-config.js.template +13 -0
  69. package/.trellis/spec/backend/examples/skills/deepagents-guide/subagent.js.template +19 -0
  70. package/.trellis/spec/backend/hook-guidelines.md +178 -0
  71. package/.trellis/spec/backend/index.md +36 -0
  72. package/.trellis/spec/backend/quality-guidelines.md +201 -0
  73. package/.trellis/spec/backend/state-management.md +76 -0
  74. package/.trellis/spec/backend/tool-guidelines.md +144 -0
  75. package/.trellis/spec/backend/type-safety.md +71 -0
  76. package/.trellis/spec/guides/code-reuse-thinking-guide.md +92 -0
  77. package/.trellis/spec/guides/cross-layer-thinking-guide.md +94 -0
  78. package/.trellis/spec/guides/index.md +79 -0
  79. package/.trellis/tasks/archive/02-02-evolving-skills/prd.md +61 -0
  80. package/.trellis/tasks/archive/02-02-evolving-skills/task.json +29 -0
  81. package/.trellis/tasks/archive/2026-02/00-bootstrap-guidelines/prd.md +86 -0
  82. package/.trellis/tasks/archive/2026-02/00-bootstrap-guidelines/task.json +27 -0
  83. package/.trellis/tasks/archive/2026-02/02-02-skills-system/check.jsonl +3 -0
  84. package/.trellis/tasks/archive/2026-02/02-02-skills-system/debug.jsonl +2 -0
  85. package/.trellis/tasks/archive/2026-02/02-02-skills-system/implement.jsonl +5 -0
  86. package/.trellis/tasks/archive/2026-02/02-02-skills-system/prd.md +33 -0
  87. package/.trellis/tasks/archive/2026-02/02-02-skills-system/task.json +41 -0
  88. package/.trellis/workflow.md +407 -0
  89. package/.trellis/workspace/index.md +123 -0
  90. package/.trellis/workspace/pony/index.md +40 -0
  91. package/.trellis/workspace/pony/journal-1.md +7 -0
  92. package/.trellis/worktree.yaml +47 -0
  93. package/AGENTS.md +18 -0
  94. package/CLAUDE.md +292 -0
  95. package/README.md +134 -0
  96. package/agents/deepspider.md +142 -0
  97. package/docs/DEBUG.md +42 -0
  98. package/docs/GUIDE.md +334 -0
  99. package/docs/PROMPT.md +60 -0
  100. package/docs/USAGE.md +226 -0
  101. package/eslint.config.js +51 -0
  102. package/package.json +78 -0
  103. package/requirements-crypto.txt +14 -0
  104. package/src/agent/index.js +97 -0
  105. package/src/agent/logger.js +164 -0
  106. package/src/agent/middleware/filterTools.js +64 -0
  107. package/src/agent/middleware/report.js +79 -0
  108. package/src/agent/prompts/system.js +315 -0
  109. package/src/agent/run.js +575 -0
  110. package/src/agent/skills/anti-detect/SKILL.md +28 -0
  111. package/src/agent/skills/anti-detect/evolved.md +12 -0
  112. package/src/agent/skills/captcha/SKILL.md +37 -0
  113. package/src/agent/skills/captcha/evolved.md +12 -0
  114. package/src/agent/skills/config.js +30 -0
  115. package/src/agent/skills/crawler/SKILL.md +9 -0
  116. package/src/agent/skills/crawler/evolved.md +16 -0
  117. package/src/agent/skills/dynamic-analysis/SKILL.md +91 -0
  118. package/src/agent/skills/dynamic-analysis/evolved.md +12 -0
  119. package/src/agent/skills/env/SKILL.md +72 -0
  120. package/src/agent/skills/env/evolved.md +12 -0
  121. package/src/agent/skills/evolve.js +79 -0
  122. package/src/agent/skills/general/SKILL.md +12 -0
  123. package/src/agent/skills/general/evolved.md +12 -0
  124. package/src/agent/skills/js2python/SKILL.md +30 -0
  125. package/src/agent/skills/js2python/evolved.md +13 -0
  126. package/src/agent/skills/report/SKILL.md +21 -0
  127. package/src/agent/skills/report/evolved.md +12 -0
  128. package/src/agent/skills/sandbox/SKILL.md +22 -0
  129. package/src/agent/skills/sandbox/evolved.md +16 -0
  130. package/src/agent/skills/static-analysis/SKILL.md +93 -0
  131. package/src/agent/skills/static-analysis/evolved.md +12 -0
  132. package/src/agent/skills/xpath/SKILL.md +119 -0
  133. package/src/agent/subagents/anti-detect.js +45 -0
  134. package/src/agent/subagents/captcha.js +51 -0
  135. package/src/agent/subagents/crawler.js +138 -0
  136. package/src/agent/subagents/dynamic.js +64 -0
  137. package/src/agent/subagents/env-agent.js +82 -0
  138. package/src/agent/subagents/index.js +37 -0
  139. package/src/agent/subagents/js2python.js +72 -0
  140. package/src/agent/subagents/sandbox.js +55 -0
  141. package/src/agent/subagents/static.js +66 -0
  142. package/src/agent/tools/analysis.js +135 -0
  143. package/src/agent/tools/analyzer.js +85 -0
  144. package/src/agent/tools/anti-detect.js +89 -0
  145. package/src/agent/tools/antidebug.js +64 -0
  146. package/src/agent/tools/async.js +43 -0
  147. package/src/agent/tools/browser.js +324 -0
  148. package/src/agent/tools/captcha.js +223 -0
  149. package/src/agent/tools/capture.js +179 -0
  150. package/src/agent/tools/correlate.js +303 -0
  151. package/src/agent/tools/crawler.js +116 -0
  152. package/src/agent/tools/cryptohook.js +80 -0
  153. package/src/agent/tools/debug.js +246 -0
  154. package/src/agent/tools/deobfuscator.js +90 -0
  155. package/src/agent/tools/env.js +83 -0
  156. package/src/agent/tools/envdump.js +92 -0
  157. package/src/agent/tools/evolve.js +164 -0
  158. package/src/agent/tools/extract.js +114 -0
  159. package/src/agent/tools/extractor.js +54 -0
  160. package/src/agent/tools/file.js +224 -0
  161. package/src/agent/tools/hook.js +84 -0
  162. package/src/agent/tools/hookManager.js +178 -0
  163. package/src/agent/tools/index.js +137 -0
  164. package/src/agent/tools/nodejs.js +101 -0
  165. package/src/agent/tools/patch.js +46 -0
  166. package/src/agent/tools/preprocess.js +71 -0
  167. package/src/agent/tools/profile.js +122 -0
  168. package/src/agent/tools/python.js +627 -0
  169. package/src/agent/tools/report.js +124 -0
  170. package/src/agent/tools/runtime.js +132 -0
  171. package/src/agent/tools/sandbox.js +79 -0
  172. package/src/agent/tools/store.js +73 -0
  173. package/src/agent/tools/trace.js +74 -0
  174. package/src/agent/tools/tracing.js +201 -0
  175. package/src/agent/tools/utils.js +51 -0
  176. package/src/agent/tools/verify.js +184 -0
  177. package/src/agent/tools/webcrack.js +109 -0
  178. package/src/analyzer/ASTAnalyzer.js +387 -0
  179. package/src/analyzer/CallStackAnalyzer.js +379 -0
  180. package/src/analyzer/Deobfuscator.js +289 -0
  181. package/src/analyzer/EncryptionAnalyzer.js +99 -0
  182. package/src/analyzer/index.js +22 -0
  183. package/src/browser/EnvBridge.js +186 -0
  184. package/src/browser/cdp.js +168 -0
  185. package/src/browser/client.js +197 -0
  186. package/src/browser/collector.js +444 -0
  187. package/src/browser/collectors/RequestCryptoLinker.js +109 -0
  188. package/src/browser/collectors/ResponseSearcher.js +107 -0
  189. package/src/browser/collectors/ScriptCollector.js +158 -0
  190. package/src/browser/collectors/index.js +26 -0
  191. package/src/browser/defaultHooks.js +932 -0
  192. package/src/browser/hooks/crypto.js +55 -0
  193. package/src/browser/hooks/index.js +64 -0
  194. package/src/browser/hooks/native.js +9 -0
  195. package/src/browser/hooks/network.js +33 -0
  196. package/src/browser/index.js +42 -0
  197. package/src/browser/interceptors/NetworkInterceptor.js +116 -0
  198. package/src/browser/interceptors/ScriptInterceptor.js +76 -0
  199. package/src/browser/interceptors/index.js +6 -0
  200. package/src/browser/ui/analysisPanel.js +1782 -0
  201. package/src/browser/ui/confirmDialog.js +158 -0
  202. package/src/browser/ui/panel.html +152 -0
  203. package/src/browser/ui/selector.js +170 -0
  204. package/src/config/index.js +5 -0
  205. package/src/config/paths.js +71 -0
  206. package/src/config/patterns/crypto.js +36 -0
  207. package/src/config/profiles/chrome.json +71 -0
  208. package/src/config/profiles/firefox.json +44 -0
  209. package/src/config/profiles/safari.json +38 -0
  210. package/src/core/EnvMonitor.js +200 -0
  211. package/src/core/PatchGenerator.js +278 -0
  212. package/src/core/Sandbox.js +181 -0
  213. package/src/env/AntiAntiDebug.js +111 -0
  214. package/src/env/AsyncHook.js +68 -0
  215. package/src/env/BrowserAPIList.js +265 -0
  216. package/src/env/CookieHook.js +48 -0
  217. package/src/env/CryptoHook.js +205 -0
  218. package/src/env/EnvCodeGenerator.js +157 -0
  219. package/src/env/EnvDumper.js +356 -0
  220. package/src/env/EnvExtractor.js +220 -0
  221. package/src/env/HookBase.js +618 -0
  222. package/src/env/NetworkHook.js +159 -0
  223. package/src/env/modules/bom/history.js +29 -0
  224. package/src/env/modules/bom/location.js +26 -0
  225. package/src/env/modules/bom/navigator.js +70 -0
  226. package/src/env/modules/bom/screen.js +26 -0
  227. package/src/env/modules/bom/storage.js +23 -0
  228. package/src/env/modules/dom/document.js +110 -0
  229. package/src/env/modules/dom/event.js +51 -0
  230. package/src/env/modules/index.js +34 -0
  231. package/src/env/modules/webapi/fetch.js +46 -0
  232. package/src/env/modules/webapi/url.js +47 -0
  233. package/src/env/modules/webapi/xhr.js +48 -0
  234. package/src/index.js +27 -0
  235. package/src/mcp/server.js +89 -0
  236. package/src/store/DataStore.js +708 -0
  237. package/src/store/Store.js +158 -0
  238. package/src/store/Validator.js +24 -0
  239. package/test/analyze.test.js +90 -0
  240. package/test/envdump.test.js +74 -0
  241. package/test/flow.test.js +90 -0
  242. package/test/hooks.test.js +138 -0
  243. package/test/plugin.test.js +35 -0
  244. package/test/refactor-full.test.js +30 -0
  245. package/test/refactor.test.js +21 -0
  246. package/test/samples/obfuscated.js +61 -0
  247. package/test/samples/original.js +66 -0
  248. package/test/samples/v10_eval_chain.js +52 -0
  249. package/test/samples/v11_bytecode_vm.js +81 -0
  250. package/test/samples/v12_polymorphic.js +69 -0
  251. package/test/samples/v1_ob_basic.js +98 -0
  252. package/test/samples/v2_ob_advanced.js +99 -0
  253. package/test/samples/v3_jjencode.js +77 -0
  254. package/test/samples/v4_aaencode.js +73 -0
  255. package/test/samples/v5_control_flow.js +86 -0
  256. package/test/samples/v6_string_encryption.js +71 -0
  257. package/test/samples/v7_jsvmp.js +83 -0
  258. package/test/samples/v8_anti_debug.js +79 -0
  259. package/test/samples/v9_proxy_trap.js +49 -0
  260. package/test/samples.test.js +96 -0
  261. package/test/webcrack.test.js +55 -0
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "Firefox 121 Windows",
3
+ "browser": "firefox",
4
+ "version": "121.0",
5
+ "platform": "Win32",
6
+
7
+ "navigator": {
8
+ "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
9
+ "appVersion": "5.0 (Windows)",
10
+ "platform": "Win32",
11
+ "language": "zh-CN",
12
+ "languages": ["zh-CN", "zh", "en-US", "en"],
13
+ "cookieEnabled": true,
14
+ "doNotTrack": "unspecified",
15
+ "maxTouchPoints": 0,
16
+ "hardwareConcurrency": 8,
17
+ "webdriver": false,
18
+ "vendor": "",
19
+ "vendorSub": "",
20
+ "productSub": "20100101"
21
+ },
22
+
23
+ "screen": {
24
+ "width": 1920,
25
+ "height": 1080,
26
+ "availWidth": 1920,
27
+ "availHeight": 1040,
28
+ "colorDepth": 24,
29
+ "pixelDepth": 24
30
+ },
31
+
32
+ "window": {
33
+ "innerWidth": 1903,
34
+ "innerHeight": 937,
35
+ "outerWidth": 1920,
36
+ "outerHeight": 1040,
37
+ "devicePixelRatio": 1
38
+ },
39
+
40
+ "webgl": {
41
+ "vendor": "Mozilla",
42
+ "renderer": "NVIDIA GeForce GTX 1060/PCIe/SSE2"
43
+ }
44
+ }
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "Safari 17 macOS",
3
+ "browser": "safari",
4
+ "version": "17.0",
5
+ "platform": "MacIntel",
6
+
7
+ "navigator": {
8
+ "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",
9
+ "appVersion": "5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",
10
+ "platform": "MacIntel",
11
+ "language": "zh-CN",
12
+ "languages": ["zh-CN", "zh"],
13
+ "cookieEnabled": true,
14
+ "maxTouchPoints": 0,
15
+ "hardwareConcurrency": 8,
16
+ "webdriver": false,
17
+ "vendor": "Apple Computer, Inc.",
18
+ "vendorSub": "",
19
+ "productSub": "20030107"
20
+ },
21
+
22
+ "screen": {
23
+ "width": 1440,
24
+ "height": 900,
25
+ "availWidth": 1440,
26
+ "availHeight": 875,
27
+ "colorDepth": 30,
28
+ "pixelDepth": 30
29
+ },
30
+
31
+ "window": {
32
+ "innerWidth": 1440,
33
+ "innerHeight": 789,
34
+ "outerWidth": 1440,
35
+ "outerHeight": 875,
36
+ "devicePixelRatio": 2
37
+ }
38
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * DeepSpider - 环境监控系统
3
+ * Node.js 端监控核心,API 风格与浏览器端 __deepspider__ 保持一致
4
+ */
5
+
6
+ export class EnvMonitor {
7
+ constructor() {
8
+ this.config = {
9
+ enabled: true,
10
+ logLevel: 'all',
11
+ maxLogSize: 10000,
12
+ trackPropertyAccess: true,
13
+ trackMethodCalls: true,
14
+ mockEnabled: true
15
+ };
16
+
17
+ // 统一日志结构,与浏览器端 __deepspider__ 保持一致
18
+ this.logs = {
19
+ env: [], // 环境访问
20
+ call: [], // 方法调用
21
+ missing: [], // 缺失属性
22
+ };
23
+
24
+ this.mocks = {
25
+ properties: {},
26
+ methods: {},
27
+ returnValues: {}
28
+ };
29
+
30
+ this._logId = 0;
31
+ }
32
+
33
+ _generateId() {
34
+ return `log_${++this._logId}_${Date.now()}`;
35
+ }
36
+
37
+ // 统一日志方法,与 __deepspider__.log() 风格一致
38
+ log(type, data) {
39
+ if (!this.config.enabled) return;
40
+
41
+ const entry = {
42
+ id: this._generateId(),
43
+ timestamp: Date.now(),
44
+ ...data
45
+ };
46
+
47
+ if (this.logs[type]) {
48
+ this.logs[type].push(entry);
49
+ if (this.logs[type].length > this.config.maxLogSize) {
50
+ this.logs[type].shift();
51
+ }
52
+ }
53
+
54
+ return entry;
55
+ }
56
+
57
+ // 记录缺失属性访问
58
+ logMissing(path, context = {}) {
59
+ const exists = this.logs.missing.find(l => l.path === path);
60
+ if (exists) return exists;
61
+
62
+ return this.log('missing', { path, context, fixed: false });
63
+ }
64
+
65
+ // 记录方法调用
66
+ logCall(path, args, result) {
67
+ if (!this.config.enabled || !this.config.trackMethodCalls) return;
68
+
69
+ return this.log('call', {
70
+ path,
71
+ args: this._serializeArgs(args),
72
+ result: this._serializeValue(result)
73
+ });
74
+ }
75
+
76
+ // 记录属性访问
77
+ logAccess(path, value) {
78
+ if (!this.config.enabled || !this.config.trackPropertyAccess) return;
79
+
80
+ return this.log('env', {
81
+ path,
82
+ value: this._serializeValue(value)
83
+ });
84
+ }
85
+
86
+ // Mock 管理
87
+ setMock(type, path, value) {
88
+ switch (type) {
89
+ case 'property':
90
+ this.mocks.properties[path] = value;
91
+ break;
92
+ case 'method':
93
+ this.mocks.methods[path] = value;
94
+ break;
95
+ case 'returnValue':
96
+ this.mocks.returnValues[path] = value;
97
+ break;
98
+ }
99
+ }
100
+
101
+ getMock(path) {
102
+ if (path in this.mocks.properties) {
103
+ return { type: 'property', value: this.mocks.properties[path] };
104
+ }
105
+ if (path in this.mocks.methods) {
106
+ return { type: 'method', value: this.mocks.methods[path] };
107
+ }
108
+ return null;
109
+ }
110
+
111
+ hasMock(path) {
112
+ return path in this.mocks.properties ||
113
+ path in this.mocks.methods ||
114
+ path in this.mocks.returnValues;
115
+ }
116
+
117
+ // 查询方法 - 与 __deepspider__.getLogs() 风格一致
118
+ getLogs(type) {
119
+ if (type) {
120
+ return this.logs[type] || [];
121
+ }
122
+ // 返回所有日志,按时间排序
123
+ return Object.entries(this.logs)
124
+ .flatMap(([t, logs]) => logs.map(l => ({ type: t, ...l })))
125
+ .sort((a, b) => a.timestamp - b.timestamp);
126
+ }
127
+
128
+ getMissingLogs(options = {}) {
129
+ let logs = this.logs.missing;
130
+ if (options.unfixedOnly) {
131
+ logs = logs.filter(l => !l.fixed);
132
+ }
133
+ if (options.limit) {
134
+ logs = logs.slice(-options.limit);
135
+ }
136
+ return logs;
137
+ }
138
+
139
+ getCallLogs(options = {}) {
140
+ let logs = this.logs.call;
141
+ if (options.path) {
142
+ logs = logs.filter(l => l.path.includes(options.path));
143
+ }
144
+ if (options.limit) {
145
+ logs = logs.slice(-options.limit);
146
+ }
147
+ return logs;
148
+ }
149
+
150
+ // 标记已修复
151
+ markFixed(path) {
152
+ const log = this.logs.missing.find(l => l.path === path);
153
+ if (log) {
154
+ log.fixed = true;
155
+ log.fixedAt = Date.now();
156
+ }
157
+ }
158
+
159
+ // 统计信息
160
+ getStats() {
161
+ return {
162
+ totalEnv: this.logs.env.length,
163
+ totalCalls: this.logs.call.length,
164
+ totalMissing: this.logs.missing.length,
165
+ unfixedMissing: this.logs.missing.filter(l => !l.fixed).length,
166
+ mockCount: {
167
+ properties: Object.keys(this.mocks.properties).length,
168
+ methods: Object.keys(this.mocks.methods).length
169
+ }
170
+ };
171
+ }
172
+
173
+ // 清空日志
174
+ clearLogs(type) {
175
+ if (type && this.logs[type]) {
176
+ this.logs[type] = [];
177
+ } else if (!type) {
178
+ this.logs = { env: [], call: [], missing: [] };
179
+ }
180
+ }
181
+
182
+ // 序列化辅助
183
+ _serializeArgs(args) {
184
+ if (!args) return [];
185
+ return Array.from(args).map(a => this._serializeValue(a));
186
+ }
187
+
188
+ _serializeValue(val) {
189
+ if (val === undefined) return 'undefined';
190
+ if (val === null) return 'null';
191
+ if (typeof val === 'function') return '[Function]';
192
+ if (typeof val === 'object') {
193
+ try { return JSON.stringify(val).slice(0, 200); }
194
+ catch { return '[Object]'; }
195
+ }
196
+ return String(val).slice(0, 200);
197
+ }
198
+ }
199
+
200
+ export default EnvMonitor;
@@ -0,0 +1,278 @@
1
+ /**
2
+ * DeepSpider - 补丁生成器
3
+ * 多级生成策略:模式规则 → 模板生成
4
+ */
5
+
6
+ import { Store } from '../store/Store.js';
7
+
8
+ // 属性类型推断规则
9
+ const TYPE_RULES = {
10
+ // 字符串类型
11
+ string: [
12
+ /userAgent$/, /platform$/, /language$/, /vendor$/,
13
+ /href$/, /hostname$/, /pathname$/, /protocol$/,
14
+ /cookie$/, /title$/, /referrer$/, /domain$/
15
+ ],
16
+ // 数字类型
17
+ number: [
18
+ /width$/, /height$/, /devicePixelRatio$/, /colorDepth$/,
19
+ /hardwareConcurrency$/, /maxTouchPoints$/, /length$/
20
+ ],
21
+ // 布尔类型
22
+ boolean: [
23
+ /cookieEnabled$/, /onLine$/, /hidden$/, /webdriver$/
24
+ ],
25
+ // 数组类型
26
+ array: [
27
+ /languages$/, /plugins$/, /mimeTypes$/
28
+ ],
29
+ // 对象类型
30
+ object: [
31
+ /connection$/, /geolocation$/, /mediaDevices$/,
32
+ /style$/, /dataset$/, /classList$/
33
+ ],
34
+ // 函数类型
35
+ function: [
36
+ /getElementById$/, /querySelector/, /createElement$/,
37
+ /addEventListener$/, /getAttribute$/, /setAttribute$/
38
+ ]
39
+ };
40
+
41
+ export class PatchGenerator {
42
+ constructor() {
43
+ this.store = new Store();
44
+ this.patterns = this._initPatterns();
45
+ this.generated = new Map();
46
+ }
47
+
48
+ async generate(property, context = {}) {
49
+ // 检查缓存
50
+ if (this.generated.has(property)) {
51
+ return { ...this.generated.get(property), cached: true };
52
+ }
53
+
54
+ // 1. 知识库精确匹配
55
+ const libResult = this._searchLibrary(property);
56
+ if (libResult) {
57
+ this.generated.set(property, libResult);
58
+ return libResult;
59
+ }
60
+
61
+ // 2. 模式规则匹配
62
+ const patternResult = this._matchPattern(property);
63
+ if (patternResult) {
64
+ this.generated.set(property, patternResult);
65
+ return patternResult;
66
+ }
67
+
68
+ // 3. 智能模板生成
69
+ const templateResult = this._generateSmartTemplate(property, context);
70
+ this.generated.set(property, templateResult);
71
+ return templateResult;
72
+ }
73
+
74
+ _searchLibrary(property) {
75
+ // 精确匹配
76
+ const results = this.store.query('env-module', property);
77
+ if (results.length > 0) {
78
+ return {
79
+ source: 'store',
80
+ code: results[0].code,
81
+ property,
82
+ confidence: 1.0,
83
+ entry: results[0].name
84
+ };
85
+ }
86
+
87
+ // 模糊匹配
88
+ const parts = property.split('.');
89
+ const rootObj = parts[0];
90
+ const rootResults = this.store.query('env-module', rootObj);
91
+
92
+ for (const result of rootResults) {
93
+ if (result.code?.includes(property)) {
94
+ return {
95
+ source: 'store-partial',
96
+ code: result.code,
97
+ property,
98
+ confidence: 0.8,
99
+ entry: result.name
100
+ };
101
+ }
102
+ }
103
+
104
+ return null;
105
+ }
106
+
107
+ _initPatterns() {
108
+ return {
109
+ // Navigator
110
+ 'navigator.userAgent': `navigator.userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36";`,
111
+ 'navigator.platform': `navigator.platform = "Win32";`,
112
+ 'navigator.language': `navigator.language = "zh-CN";`,
113
+ 'navigator.languages': `navigator.languages = ["zh-CN", "en"];`,
114
+ 'navigator.cookieEnabled': `navigator.cookieEnabled = true;`,
115
+ 'navigator.onLine': `navigator.onLine = true;`,
116
+ 'navigator.hardwareConcurrency': `navigator.hardwareConcurrency = 8;`,
117
+ 'navigator.webdriver': `Object.defineProperty(navigator, 'webdriver', { get: () => false });`,
118
+ // Location
119
+ 'location.href': `location.href = "https://example.com/";`,
120
+ 'location.hostname': `location.hostname = "example.com";`,
121
+ 'location.protocol': `location.protocol = "https:";`,
122
+ // Document
123
+ 'document.cookie': `document.cookie = "";`,
124
+ 'document.referrer': `document.referrer = "";`,
125
+ 'document.domain': `document.domain = "example.com";`,
126
+ // Screen
127
+ 'screen.width': `screen.width = 1920;`,
128
+ 'screen.height': `screen.height = 1080;`,
129
+ 'screen.colorDepth': `screen.colorDepth = 24;`,
130
+ // Window
131
+ 'window.innerWidth': `window.innerWidth = 1920;`,
132
+ 'window.innerHeight': `window.innerHeight = 1080;`,
133
+ 'window.devicePixelRatio': `window.devicePixelRatio = 1;`
134
+ };
135
+ }
136
+
137
+ _matchPattern(property) {
138
+ const pattern = this.patterns[property];
139
+ if (pattern) {
140
+ return {
141
+ source: 'pattern',
142
+ code: pattern,
143
+ property,
144
+ confidence: 0.9
145
+ };
146
+ }
147
+ return null;
148
+ }
149
+
150
+ _inferType(property) {
151
+ for (const [type, patterns] of Object.entries(TYPE_RULES)) {
152
+ if (patterns.some(p => p.test(property))) {
153
+ return type;
154
+ }
155
+ }
156
+ return 'unknown';
157
+ }
158
+
159
+ _getDefaultValue(type) {
160
+ const defaults = {
161
+ string: '""',
162
+ number: '0',
163
+ boolean: 'false',
164
+ array: '[]',
165
+ object: '{}',
166
+ function: 'function() {}',
167
+ unknown: 'undefined'
168
+ };
169
+ return defaults[type] || 'undefined';
170
+ }
171
+
172
+ _generateSmartTemplate(property, context = {}) {
173
+ const parts = property.split('.');
174
+ const propName = parts[parts.length - 1];
175
+ const type = this._inferType(property);
176
+ const defaultVal = this._getDefaultValue(type);
177
+
178
+ let code;
179
+ if (parts.length === 1) {
180
+ code = `window.${property} = ${defaultVal};`;
181
+ } else {
182
+ const parent = parts.slice(0, -1).join('.');
183
+ code = `${parent}.${propName} = ${defaultVal};`;
184
+ }
185
+
186
+ return {
187
+ source: 'template',
188
+ code,
189
+ property,
190
+ inferredType: type,
191
+ confidence: 0.5,
192
+ needsLLM: true
193
+ };
194
+ }
195
+
196
+ // 批量生成补丁
197
+ async generateBatch(properties) {
198
+ const results = [];
199
+ const conflicts = this._detectConflicts(properties);
200
+
201
+ for (const prop of properties) {
202
+ const result = await this.generate(prop);
203
+ result.hasConflict = conflicts.has(prop);
204
+ results.push(result);
205
+ }
206
+
207
+ return {
208
+ patches: results,
209
+ conflicts: Array.from(conflicts),
210
+ stats: {
211
+ total: results.length,
212
+ fromLibrary: results.filter(r => r.source === 'library').length,
213
+ fromPattern: results.filter(r => r.source === 'pattern').length,
214
+ needsLLM: results.filter(r => r.needsLLM).length
215
+ }
216
+ };
217
+ }
218
+
219
+ // 冲突检测
220
+ _detectConflicts(properties) {
221
+ const conflicts = new Set();
222
+ const roots = new Map();
223
+
224
+ for (const prop of properties) {
225
+ const parts = prop.split('.');
226
+ const root = parts[0];
227
+
228
+ if (!roots.has(root)) {
229
+ roots.set(root, []);
230
+ }
231
+ roots.get(root).push(prop);
232
+ }
233
+
234
+ // 检测同一对象的重复定义
235
+ for (const [root, props] of roots) {
236
+ if (props.length > 1) {
237
+ const seen = new Set();
238
+ for (const p of props) {
239
+ if (seen.has(p)) {
240
+ conflicts.add(p);
241
+ }
242
+ seen.add(p);
243
+ }
244
+ }
245
+ }
246
+
247
+ return conflicts;
248
+ }
249
+
250
+ // 合并补丁代码
251
+ mergePatchCode(patches) {
252
+ const grouped = new Map();
253
+
254
+ for (const patch of patches) {
255
+ const root = patch.property.split('.')[0];
256
+ if (!grouped.has(root)) {
257
+ grouped.set(root, []);
258
+ }
259
+ grouped.get(root).push(patch);
260
+ }
261
+
262
+ const merged = [];
263
+ for (const [root, group] of grouped) {
264
+ merged.push(`// ${root} patches`);
265
+ merged.push(...group.map(p => p.code));
266
+ merged.push('');
267
+ }
268
+
269
+ return merged.join('\n');
270
+ }
271
+
272
+ // 清除缓存
273
+ clearCache() {
274
+ this.generated.clear();
275
+ }
276
+ }
277
+
278
+ export default PatchGenerator;