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.
- package/.claude/agents/check.md +122 -0
- package/.claude/agents/debug.md +106 -0
- package/.claude/agents/dispatch.md +214 -0
- package/.claude/agents/implement.md +96 -0
- package/.claude/agents/plan.md +396 -0
- package/.claude/agents/research.md +120 -0
- package/.claude/commands/evolve/merge.md +80 -0
- package/.claude/commands/trellis/before-backend-dev.md +13 -0
- package/.claude/commands/trellis/before-frontend-dev.md +13 -0
- package/.claude/commands/trellis/break-loop.md +107 -0
- package/.claude/commands/trellis/check-backend.md +13 -0
- package/.claude/commands/trellis/check-cross-layer.md +153 -0
- package/.claude/commands/trellis/check-frontend.md +13 -0
- package/.claude/commands/trellis/create-command.md +154 -0
- package/.claude/commands/trellis/finish-work.md +129 -0
- package/.claude/commands/trellis/integrate-skill.md +219 -0
- package/.claude/commands/trellis/onboard.md +358 -0
- package/.claude/commands/trellis/parallel.md +193 -0
- package/.claude/commands/trellis/record-session.md +62 -0
- package/.claude/commands/trellis/start.md +280 -0
- package/.claude/commands/trellis/update-spec.md +213 -0
- package/.claude/hooks/inject-subagent-context.py +758 -0
- package/.claude/hooks/ralph-loop.py +374 -0
- package/.claude/hooks/session-start.py +126 -0
- package/.claude/settings.json +41 -0
- package/.claude/skills/deepagents-guide/SKILL.md +428 -0
- package/.cursor/commands/trellis-before-backend-dev.md +13 -0
- package/.cursor/commands/trellis-before-frontend-dev.md +13 -0
- package/.cursor/commands/trellis-break-loop.md +107 -0
- package/.cursor/commands/trellis-check-backend.md +13 -0
- package/.cursor/commands/trellis-check-cross-layer.md +153 -0
- package/.cursor/commands/trellis-check-frontend.md +13 -0
- package/.cursor/commands/trellis-create-command.md +154 -0
- package/.cursor/commands/trellis-finish-work.md +129 -0
- package/.cursor/commands/trellis-integrate-skill.md +219 -0
- package/.cursor/commands/trellis-onboard.md +358 -0
- package/.cursor/commands/trellis-record-session.md +62 -0
- package/.cursor/commands/trellis-start.md +156 -0
- package/.cursor/commands/trellis-update-spec.md +213 -0
- package/.env.example +11 -0
- package/.husky/pre-commit +1 -0
- package/.mcp.json +8 -0
- package/.trellis/.template-hashes.json +65 -0
- package/.trellis/.version +1 -0
- package/.trellis/scripts/add-session.sh +384 -0
- package/.trellis/scripts/common/developer.sh +129 -0
- package/.trellis/scripts/common/git-context.sh +263 -0
- package/.trellis/scripts/common/paths.sh +208 -0
- package/.trellis/scripts/common/phase.sh +150 -0
- package/.trellis/scripts/common/registry.sh +247 -0
- package/.trellis/scripts/common/task-queue.sh +142 -0
- package/.trellis/scripts/common/task-utils.sh +151 -0
- package/.trellis/scripts/common/worktree.sh +128 -0
- package/.trellis/scripts/create-bootstrap.sh +299 -0
- package/.trellis/scripts/get-context.sh +7 -0
- package/.trellis/scripts/get-developer.sh +15 -0
- package/.trellis/scripts/init-developer.sh +34 -0
- package/.trellis/scripts/multi-agent/cleanup.sh +396 -0
- package/.trellis/scripts/multi-agent/create-pr.sh +241 -0
- package/.trellis/scripts/multi-agent/plan.sh +207 -0
- package/.trellis/scripts/multi-agent/start.sh +310 -0
- package/.trellis/scripts/multi-agent/status.sh +828 -0
- package/.trellis/scripts/task.sh +1118 -0
- package/.trellis/spec/backend/deepagents-guide.md +337 -0
- package/.trellis/spec/backend/directory-structure.md +126 -0
- package/.trellis/spec/backend/examples/skills/deepagents-guide/README.md +11 -0
- package/.trellis/spec/backend/examples/skills/deepagents-guide/agent.js.template +20 -0
- package/.trellis/spec/backend/examples/skills/deepagents-guide/skills-config.js.template +13 -0
- package/.trellis/spec/backend/examples/skills/deepagents-guide/subagent.js.template +19 -0
- package/.trellis/spec/backend/hook-guidelines.md +178 -0
- package/.trellis/spec/backend/index.md +36 -0
- package/.trellis/spec/backend/quality-guidelines.md +201 -0
- package/.trellis/spec/backend/state-management.md +76 -0
- package/.trellis/spec/backend/tool-guidelines.md +144 -0
- package/.trellis/spec/backend/type-safety.md +71 -0
- package/.trellis/spec/guides/code-reuse-thinking-guide.md +92 -0
- package/.trellis/spec/guides/cross-layer-thinking-guide.md +94 -0
- package/.trellis/spec/guides/index.md +79 -0
- package/.trellis/tasks/archive/02-02-evolving-skills/prd.md +61 -0
- package/.trellis/tasks/archive/02-02-evolving-skills/task.json +29 -0
- package/.trellis/tasks/archive/2026-02/00-bootstrap-guidelines/prd.md +86 -0
- package/.trellis/tasks/archive/2026-02/00-bootstrap-guidelines/task.json +27 -0
- package/.trellis/tasks/archive/2026-02/02-02-skills-system/check.jsonl +3 -0
- package/.trellis/tasks/archive/2026-02/02-02-skills-system/debug.jsonl +2 -0
- package/.trellis/tasks/archive/2026-02/02-02-skills-system/implement.jsonl +5 -0
- package/.trellis/tasks/archive/2026-02/02-02-skills-system/prd.md +33 -0
- package/.trellis/tasks/archive/2026-02/02-02-skills-system/task.json +41 -0
- package/.trellis/workflow.md +407 -0
- package/.trellis/workspace/index.md +123 -0
- package/.trellis/workspace/pony/index.md +40 -0
- package/.trellis/workspace/pony/journal-1.md +7 -0
- package/.trellis/worktree.yaml +47 -0
- package/AGENTS.md +18 -0
- package/CLAUDE.md +292 -0
- package/README.md +134 -0
- package/agents/deepspider.md +142 -0
- package/docs/DEBUG.md +42 -0
- package/docs/GUIDE.md +334 -0
- package/docs/PROMPT.md +60 -0
- package/docs/USAGE.md +226 -0
- package/eslint.config.js +51 -0
- package/package.json +78 -0
- package/requirements-crypto.txt +14 -0
- package/src/agent/index.js +97 -0
- package/src/agent/logger.js +164 -0
- package/src/agent/middleware/filterTools.js +64 -0
- package/src/agent/middleware/report.js +79 -0
- package/src/agent/prompts/system.js +315 -0
- package/src/agent/run.js +575 -0
- package/src/agent/skills/anti-detect/SKILL.md +28 -0
- package/src/agent/skills/anti-detect/evolved.md +12 -0
- package/src/agent/skills/captcha/SKILL.md +37 -0
- package/src/agent/skills/captcha/evolved.md +12 -0
- package/src/agent/skills/config.js +30 -0
- package/src/agent/skills/crawler/SKILL.md +9 -0
- package/src/agent/skills/crawler/evolved.md +16 -0
- package/src/agent/skills/dynamic-analysis/SKILL.md +91 -0
- package/src/agent/skills/dynamic-analysis/evolved.md +12 -0
- package/src/agent/skills/env/SKILL.md +72 -0
- package/src/agent/skills/env/evolved.md +12 -0
- package/src/agent/skills/evolve.js +79 -0
- package/src/agent/skills/general/SKILL.md +12 -0
- package/src/agent/skills/general/evolved.md +12 -0
- package/src/agent/skills/js2python/SKILL.md +30 -0
- package/src/agent/skills/js2python/evolved.md +13 -0
- package/src/agent/skills/report/SKILL.md +21 -0
- package/src/agent/skills/report/evolved.md +12 -0
- package/src/agent/skills/sandbox/SKILL.md +22 -0
- package/src/agent/skills/sandbox/evolved.md +16 -0
- package/src/agent/skills/static-analysis/SKILL.md +93 -0
- package/src/agent/skills/static-analysis/evolved.md +12 -0
- package/src/agent/skills/xpath/SKILL.md +119 -0
- package/src/agent/subagents/anti-detect.js +45 -0
- package/src/agent/subagents/captcha.js +51 -0
- package/src/agent/subagents/crawler.js +138 -0
- package/src/agent/subagents/dynamic.js +64 -0
- package/src/agent/subagents/env-agent.js +82 -0
- package/src/agent/subagents/index.js +37 -0
- package/src/agent/subagents/js2python.js +72 -0
- package/src/agent/subagents/sandbox.js +55 -0
- package/src/agent/subagents/static.js +66 -0
- package/src/agent/tools/analysis.js +135 -0
- package/src/agent/tools/analyzer.js +85 -0
- package/src/agent/tools/anti-detect.js +89 -0
- package/src/agent/tools/antidebug.js +64 -0
- package/src/agent/tools/async.js +43 -0
- package/src/agent/tools/browser.js +324 -0
- package/src/agent/tools/captcha.js +223 -0
- package/src/agent/tools/capture.js +179 -0
- package/src/agent/tools/correlate.js +303 -0
- package/src/agent/tools/crawler.js +116 -0
- package/src/agent/tools/cryptohook.js +80 -0
- package/src/agent/tools/debug.js +246 -0
- package/src/agent/tools/deobfuscator.js +90 -0
- package/src/agent/tools/env.js +83 -0
- package/src/agent/tools/envdump.js +92 -0
- package/src/agent/tools/evolve.js +164 -0
- package/src/agent/tools/extract.js +114 -0
- package/src/agent/tools/extractor.js +54 -0
- package/src/agent/tools/file.js +224 -0
- package/src/agent/tools/hook.js +84 -0
- package/src/agent/tools/hookManager.js +178 -0
- package/src/agent/tools/index.js +137 -0
- package/src/agent/tools/nodejs.js +101 -0
- package/src/agent/tools/patch.js +46 -0
- package/src/agent/tools/preprocess.js +71 -0
- package/src/agent/tools/profile.js +122 -0
- package/src/agent/tools/python.js +627 -0
- package/src/agent/tools/report.js +124 -0
- package/src/agent/tools/runtime.js +132 -0
- package/src/agent/tools/sandbox.js +79 -0
- package/src/agent/tools/store.js +73 -0
- package/src/agent/tools/trace.js +74 -0
- package/src/agent/tools/tracing.js +201 -0
- package/src/agent/tools/utils.js +51 -0
- package/src/agent/tools/verify.js +184 -0
- package/src/agent/tools/webcrack.js +109 -0
- package/src/analyzer/ASTAnalyzer.js +387 -0
- package/src/analyzer/CallStackAnalyzer.js +379 -0
- package/src/analyzer/Deobfuscator.js +289 -0
- package/src/analyzer/EncryptionAnalyzer.js +99 -0
- package/src/analyzer/index.js +22 -0
- package/src/browser/EnvBridge.js +186 -0
- package/src/browser/cdp.js +168 -0
- package/src/browser/client.js +197 -0
- package/src/browser/collector.js +444 -0
- package/src/browser/collectors/RequestCryptoLinker.js +109 -0
- package/src/browser/collectors/ResponseSearcher.js +107 -0
- package/src/browser/collectors/ScriptCollector.js +158 -0
- package/src/browser/collectors/index.js +26 -0
- package/src/browser/defaultHooks.js +932 -0
- package/src/browser/hooks/crypto.js +55 -0
- package/src/browser/hooks/index.js +64 -0
- package/src/browser/hooks/native.js +9 -0
- package/src/browser/hooks/network.js +33 -0
- package/src/browser/index.js +42 -0
- package/src/browser/interceptors/NetworkInterceptor.js +116 -0
- package/src/browser/interceptors/ScriptInterceptor.js +76 -0
- package/src/browser/interceptors/index.js +6 -0
- package/src/browser/ui/analysisPanel.js +1782 -0
- package/src/browser/ui/confirmDialog.js +158 -0
- package/src/browser/ui/panel.html +152 -0
- package/src/browser/ui/selector.js +170 -0
- package/src/config/index.js +5 -0
- package/src/config/paths.js +71 -0
- package/src/config/patterns/crypto.js +36 -0
- package/src/config/profiles/chrome.json +71 -0
- package/src/config/profiles/firefox.json +44 -0
- package/src/config/profiles/safari.json +38 -0
- package/src/core/EnvMonitor.js +200 -0
- package/src/core/PatchGenerator.js +278 -0
- package/src/core/Sandbox.js +181 -0
- package/src/env/AntiAntiDebug.js +111 -0
- package/src/env/AsyncHook.js +68 -0
- package/src/env/BrowserAPIList.js +265 -0
- package/src/env/CookieHook.js +48 -0
- package/src/env/CryptoHook.js +205 -0
- package/src/env/EnvCodeGenerator.js +157 -0
- package/src/env/EnvDumper.js +356 -0
- package/src/env/EnvExtractor.js +220 -0
- package/src/env/HookBase.js +618 -0
- package/src/env/NetworkHook.js +159 -0
- package/src/env/modules/bom/history.js +29 -0
- package/src/env/modules/bom/location.js +26 -0
- package/src/env/modules/bom/navigator.js +70 -0
- package/src/env/modules/bom/screen.js +26 -0
- package/src/env/modules/bom/storage.js +23 -0
- package/src/env/modules/dom/document.js +110 -0
- package/src/env/modules/dom/event.js +51 -0
- package/src/env/modules/index.js +34 -0
- package/src/env/modules/webapi/fetch.js +46 -0
- package/src/env/modules/webapi/url.js +47 -0
- package/src/env/modules/webapi/xhr.js +48 -0
- package/src/index.js +27 -0
- package/src/mcp/server.js +89 -0
- package/src/store/DataStore.js +708 -0
- package/src/store/Store.js +158 -0
- package/src/store/Validator.js +24 -0
- package/test/analyze.test.js +90 -0
- package/test/envdump.test.js +74 -0
- package/test/flow.test.js +90 -0
- package/test/hooks.test.js +138 -0
- package/test/plugin.test.js +35 -0
- package/test/refactor-full.test.js +30 -0
- package/test/refactor.test.js +21 -0
- package/test/samples/obfuscated.js +61 -0
- package/test/samples/original.js +66 -0
- package/test/samples/v10_eval_chain.js +52 -0
- package/test/samples/v11_bytecode_vm.js +81 -0
- package/test/samples/v12_polymorphic.js +69 -0
- package/test/samples/v1_ob_basic.js +98 -0
- package/test/samples/v2_ob_advanced.js +99 -0
- package/test/samples/v3_jjencode.js +77 -0
- package/test/samples/v4_aaencode.js +73 -0
- package/test/samples/v5_control_flow.js +86 -0
- package/test/samples/v6_string_encryption.js +71 -0
- package/test/samples/v7_jsvmp.js +83 -0
- package/test/samples/v8_anti_debug.js +79 -0
- package/test/samples/v9_proxy_trap.js +49 -0
- package/test/samples.test.js +96 -0
- package/test/webcrack.test.js +55 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSpider - 确认弹窗
|
|
3
|
+
* 显示选中内容,支持编辑后确认
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function generateConfirmDialogScript() {
|
|
7
|
+
return `
|
|
8
|
+
(function() {
|
|
9
|
+
const deepspider = window.__deepspider__;
|
|
10
|
+
if (!deepspider || deepspider._confirmDialog) return;
|
|
11
|
+
deepspider._confirmDialog = true;
|
|
12
|
+
|
|
13
|
+
let dialog = null;
|
|
14
|
+
|
|
15
|
+
function createDialog() {
|
|
16
|
+
dialog = document.createElement('div');
|
|
17
|
+
dialog.id = 'deepspider-confirm-dialog';
|
|
18
|
+
dialog.innerHTML = \`
|
|
19
|
+
<div class="deepspider-dialog-mask"></div>
|
|
20
|
+
<div class="deepspider-dialog-content">
|
|
21
|
+
<div class="deepspider-dialog-header">
|
|
22
|
+
<span>确认分析内容</span>
|
|
23
|
+
<button class="deepspider-dialog-close">×</button>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="deepspider-dialog-body">
|
|
26
|
+
<label>选中内容:</label>
|
|
27
|
+
<textarea class="deepspider-dialog-text" rows="5"></textarea>
|
|
28
|
+
<label>XPath:</label>
|
|
29
|
+
<input class="deepspider-dialog-xpath" type="text" readonly />
|
|
30
|
+
</div>
|
|
31
|
+
<div class="deepspider-dialog-footer">
|
|
32
|
+
<button class="deepspider-btn-cancel">取消</button>
|
|
33
|
+
<button class="deepspider-btn-confirm">发送分析</button>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
\`;
|
|
37
|
+
|
|
38
|
+
// 样式
|
|
39
|
+
const style = document.createElement('style');
|
|
40
|
+
style.textContent = \`
|
|
41
|
+
#deepspider-confirm-dialog { display: none; }
|
|
42
|
+
#deepspider-confirm-dialog.active { display: block; }
|
|
43
|
+
.deepspider-dialog-mask {
|
|
44
|
+
position: fixed; inset: 0;
|
|
45
|
+
background: rgba(0,0,0,0.5);
|
|
46
|
+
z-index: 2147483640;
|
|
47
|
+
}
|
|
48
|
+
.deepspider-dialog-content {
|
|
49
|
+
position: fixed;
|
|
50
|
+
top: 50%; left: 50%;
|
|
51
|
+
transform: translate(-50%, -50%);
|
|
52
|
+
background: #fff; border-radius: 8px;
|
|
53
|
+
width: 450px; max-width: 90vw;
|
|
54
|
+
z-index: 2147483641;
|
|
55
|
+
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
|
|
56
|
+
}
|
|
57
|
+
.deepspider-dialog-header {
|
|
58
|
+
padding: 12px 16px;
|
|
59
|
+
border-bottom: 1px solid #eee;
|
|
60
|
+
display: flex; justify-content: space-between;
|
|
61
|
+
align-items: center; font-weight: 600;
|
|
62
|
+
}
|
|
63
|
+
.deepspider-dialog-close {
|
|
64
|
+
background: none; border: none;
|
|
65
|
+
font-size: 20px; cursor: pointer;
|
|
66
|
+
color: #666;
|
|
67
|
+
}
|
|
68
|
+
.deepspider-dialog-body {
|
|
69
|
+
padding: 16px;
|
|
70
|
+
}
|
|
71
|
+
.deepspider-dialog-body label {
|
|
72
|
+
display: block; margin-bottom: 4px;
|
|
73
|
+
font-size: 12px; color: #666;
|
|
74
|
+
}
|
|
75
|
+
.deepspider-dialog-text {
|
|
76
|
+
width: 100%; padding: 8px;
|
|
77
|
+
border: 1px solid #ddd; border-radius: 4px;
|
|
78
|
+
font-size: 13px; resize: vertical;
|
|
79
|
+
margin-bottom: 12px; box-sizing: border-box;
|
|
80
|
+
}
|
|
81
|
+
.deepspider-dialog-xpath {
|
|
82
|
+
width: 100%; padding: 8px;
|
|
83
|
+
border: 1px solid #ddd; border-radius: 4px;
|
|
84
|
+
font-size: 12px; color: #666;
|
|
85
|
+
background: #f5f5f5; box-sizing: border-box;
|
|
86
|
+
}
|
|
87
|
+
.deepspider-dialog-footer {
|
|
88
|
+
padding: 12px 16px;
|
|
89
|
+
border-top: 1px solid #eee;
|
|
90
|
+
text-align: right;
|
|
91
|
+
}
|
|
92
|
+
.deepspider-dialog-footer button {
|
|
93
|
+
padding: 8px 16px; margin-left: 8px;
|
|
94
|
+
border-radius: 4px; cursor: pointer;
|
|
95
|
+
font-size: 14px;
|
|
96
|
+
}
|
|
97
|
+
.deepspider-btn-cancel {
|
|
98
|
+
background: #f5f5f5; border: 1px solid #ddd;
|
|
99
|
+
color: #666;
|
|
100
|
+
}
|
|
101
|
+
.deepspider-btn-confirm {
|
|
102
|
+
background: #4A90D9; border: none;
|
|
103
|
+
color: #fff;
|
|
104
|
+
}
|
|
105
|
+
\`;
|
|
106
|
+
|
|
107
|
+
document.head.appendChild(style);
|
|
108
|
+
document.body.appendChild(dialog);
|
|
109
|
+
bindEvents();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function bindEvents() {
|
|
113
|
+
dialog.querySelector('.deepspider-dialog-close').onclick = hideDialog;
|
|
114
|
+
dialog.querySelector('.deepspider-btn-cancel').onclick = hideDialog;
|
|
115
|
+
dialog.querySelector('.deepspider-dialog-mask').onclick = hideDialog;
|
|
116
|
+
|
|
117
|
+
dialog.querySelector('.deepspider-btn-confirm').onclick = () => {
|
|
118
|
+
const text = dialog.querySelector('.deepspider-dialog-text').value;
|
|
119
|
+
const xpath = dialog.querySelector('.deepspider-dialog-xpath').value;
|
|
120
|
+
|
|
121
|
+
// 设置待分析数据
|
|
122
|
+
deepspider.pendingAnalysis = {
|
|
123
|
+
text,
|
|
124
|
+
xpath,
|
|
125
|
+
timestamp: Date.now()
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
hideDialog();
|
|
129
|
+
|
|
130
|
+
// 打开分析面板
|
|
131
|
+
if (deepspider.showAnalysisPanel) {
|
|
132
|
+
deepspider.showAnalysisPanel();
|
|
133
|
+
deepspider.addPanelMessage('user', '分析这段数据:' + text.slice(0, 100));
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function showDialog(data) {
|
|
139
|
+
if (!dialog) createDialog();
|
|
140
|
+
|
|
141
|
+
dialog.querySelector('.deepspider-dialog-text').value = data.text || '';
|
|
142
|
+
dialog.querySelector('.deepspider-dialog-xpath').value = data.xpath || '';
|
|
143
|
+
dialog.classList.add('active');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function hideDialog() {
|
|
147
|
+
if (dialog) dialog.classList.remove('active');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
deepspider.showConfirmDialog = showDialog;
|
|
151
|
+
deepspider.hideConfirmDialog = hideDialog;
|
|
152
|
+
|
|
153
|
+
console.log('[DeepSpider] ConfirmDialog 已加载');
|
|
154
|
+
})();
|
|
155
|
+
`;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export default { generateConfirmDialogScript };
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>DeepSpider Panel</title>
|
|
6
|
+
<style>
|
|
7
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
8
|
+
body {
|
|
9
|
+
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
|
10
|
+
background: #1e1e1e;
|
|
11
|
+
color: #d4d4d4;
|
|
12
|
+
height: 100vh;
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
}
|
|
16
|
+
.header {
|
|
17
|
+
padding: 12px 16px;
|
|
18
|
+
background: #2d2d2d;
|
|
19
|
+
border-bottom: 1px solid #3c3c3c;
|
|
20
|
+
display: flex;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
align-items: center;
|
|
23
|
+
}
|
|
24
|
+
.header-title { font-weight: 600; color: #4fc3f7; font-size: 14px; }
|
|
25
|
+
.header-btns button {
|
|
26
|
+
background: none; border: none;
|
|
27
|
+
color: #808080; font-size: 14px;
|
|
28
|
+
cursor: pointer; margin-left: 8px;
|
|
29
|
+
padding: 4px 8px;
|
|
30
|
+
}
|
|
31
|
+
.header-btns button:hover { color: #fff; }
|
|
32
|
+
.header-btns button.active { color: #4fc3f7; background: #3c3c3c; border-radius: 4px; }
|
|
33
|
+
.messages {
|
|
34
|
+
flex: 1;
|
|
35
|
+
overflow-y: auto;
|
|
36
|
+
padding: 12px;
|
|
37
|
+
}
|
|
38
|
+
.msg {
|
|
39
|
+
margin-bottom: 10px;
|
|
40
|
+
padding: 10px 12px;
|
|
41
|
+
border-radius: 6px;
|
|
42
|
+
line-height: 1.5;
|
|
43
|
+
word-break: break-word;
|
|
44
|
+
white-space: pre-wrap;
|
|
45
|
+
font-size: 13px;
|
|
46
|
+
}
|
|
47
|
+
.msg-user { background: #094771; margin-left: 40px; }
|
|
48
|
+
.msg-assistant { background: #2d2d2d; margin-right: 40px; }
|
|
49
|
+
.msg-system { background: #3c3c3c; text-align: center; font-size: 12px; color: #808080; }
|
|
50
|
+
.input-area {
|
|
51
|
+
padding: 12px;
|
|
52
|
+
border-top: 1px solid #3c3c3c;
|
|
53
|
+
display: flex;
|
|
54
|
+
gap: 8px;
|
|
55
|
+
}
|
|
56
|
+
.input-area textarea {
|
|
57
|
+
flex: 1;
|
|
58
|
+
padding: 10px;
|
|
59
|
+
background: #2d2d2d;
|
|
60
|
+
border: 1px solid #3c3c3c;
|
|
61
|
+
border-radius: 4px;
|
|
62
|
+
color: #d4d4d4;
|
|
63
|
+
resize: none;
|
|
64
|
+
font-size: 13px;
|
|
65
|
+
font-family: inherit;
|
|
66
|
+
}
|
|
67
|
+
.input-area textarea:focus { outline: none; border-color: #4fc3f7; }
|
|
68
|
+
.input-area button {
|
|
69
|
+
padding: 10px 16px;
|
|
70
|
+
background: #4fc3f7;
|
|
71
|
+
border: none;
|
|
72
|
+
border-radius: 4px;
|
|
73
|
+
color: #1e1e1e;
|
|
74
|
+
cursor: pointer;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
}
|
|
77
|
+
.input-area button:hover { background: #81d4fa; }
|
|
78
|
+
</style>
|
|
79
|
+
</head>
|
|
80
|
+
<body>
|
|
81
|
+
<div class="header">
|
|
82
|
+
<span class="header-title">DeepSpider</span>
|
|
83
|
+
<div class="header-btns">
|
|
84
|
+
<button id="btn-select" title="选择元素">⦿ 选择</button>
|
|
85
|
+
<button id="btn-clear" title="清空消息">清空</button>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="messages" id="messages"></div>
|
|
89
|
+
<div class="input-area">
|
|
90
|
+
<textarea id="chat-input" placeholder="输入问题..." rows="2"></textarea>
|
|
91
|
+
<button id="btn-send">发送</button>
|
|
92
|
+
</div>
|
|
93
|
+
<script>
|
|
94
|
+
const messages = [];
|
|
95
|
+
const messagesEl = document.getElementById('messages');
|
|
96
|
+
const chatInput = document.getElementById('chat-input');
|
|
97
|
+
|
|
98
|
+
function escapeHtml(str) {
|
|
99
|
+
return String(str).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function renderMessages() {
|
|
103
|
+
messagesEl.innerHTML = messages.map(m =>
|
|
104
|
+
'<div class="msg msg-' + m.role + '">' + escapeHtml(m.content) + '</div>'
|
|
105
|
+
).join('');
|
|
106
|
+
messagesEl.scrollTop = messagesEl.scrollHeight;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function addMessage(role, content) {
|
|
110
|
+
messages.push({ role, content, time: Date.now() });
|
|
111
|
+
renderMessages();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 暴露给后端调用
|
|
115
|
+
window.__panel__ = {
|
|
116
|
+
addMessage,
|
|
117
|
+
clearMessages: () => { messages.length = 0; renderMessages(); }
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// 发送消息
|
|
121
|
+
function sendChat() {
|
|
122
|
+
const text = chatInput.value.trim();
|
|
123
|
+
if (!text) return;
|
|
124
|
+
chatInput.value = '';
|
|
125
|
+
addMessage('user', text);
|
|
126
|
+
if (typeof __deepspider_send__ === 'function') {
|
|
127
|
+
__deepspider_send__(JSON.stringify({ type: 'chat', text }));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
document.getElementById('btn-send').onclick = sendChat;
|
|
132
|
+
chatInput.onkeydown = (e) => {
|
|
133
|
+
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendChat(); }
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// 选择模式
|
|
137
|
+
document.getElementById('btn-select').onclick = () => {
|
|
138
|
+
if (typeof __deepspider_send__ === 'function') {
|
|
139
|
+
__deepspider_send__(JSON.stringify({ type: 'start-select' }));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
// 清空
|
|
144
|
+
document.getElementById('btn-clear').onclick = () => {
|
|
145
|
+
messages.length = 0;
|
|
146
|
+
renderMessages();
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
addMessage('system', '面板已就绪,点击「选择」按钮选择页面元素进行分析');
|
|
150
|
+
</script>
|
|
151
|
+
</body>
|
|
152
|
+
</html>
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSpider - 元素选择器模式
|
|
3
|
+
* 类似开发者工具的元素选择功能
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function generateSelectorScript() {
|
|
7
|
+
return `
|
|
8
|
+
(function() {
|
|
9
|
+
const deepspider = window.__deepspider__;
|
|
10
|
+
if (!deepspider || deepspider._selector) return;
|
|
11
|
+
deepspider._selector = true;
|
|
12
|
+
|
|
13
|
+
let isActive = false;
|
|
14
|
+
let overlay = null;
|
|
15
|
+
let infoBox = null;
|
|
16
|
+
let currentElement = null;
|
|
17
|
+
|
|
18
|
+
// 创建高亮覆盖层
|
|
19
|
+
function createOverlay() {
|
|
20
|
+
overlay = document.createElement('div');
|
|
21
|
+
overlay.id = 'deepspider-selector-overlay';
|
|
22
|
+
overlay.style.cssText = \`
|
|
23
|
+
position: fixed;
|
|
24
|
+
pointer-events: none;
|
|
25
|
+
border: 2px solid #4A90D9;
|
|
26
|
+
background: rgba(74, 144, 217, 0.1);
|
|
27
|
+
z-index: 2147483646;
|
|
28
|
+
display: none;
|
|
29
|
+
transition: all 0.1s ease;
|
|
30
|
+
\`;
|
|
31
|
+
document.body.appendChild(overlay);
|
|
32
|
+
|
|
33
|
+
// 元素信息框
|
|
34
|
+
infoBox = document.createElement('div');
|
|
35
|
+
infoBox.id = 'deepspider-selector-info';
|
|
36
|
+
infoBox.style.cssText = \`
|
|
37
|
+
position: fixed;
|
|
38
|
+
background: #333;
|
|
39
|
+
color: #fff;
|
|
40
|
+
padding: 4px 8px;
|
|
41
|
+
font-size: 12px;
|
|
42
|
+
font-family: monospace;
|
|
43
|
+
border-radius: 3px;
|
|
44
|
+
z-index: 2147483647;
|
|
45
|
+
display: none;
|
|
46
|
+
pointer-events: none;
|
|
47
|
+
\`;
|
|
48
|
+
document.body.appendChild(infoBox);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 生成 XPath
|
|
52
|
+
function getXPath(element) {
|
|
53
|
+
if (!element) return '';
|
|
54
|
+
if (element.id) return '//*[@id="' + element.id + '"]';
|
|
55
|
+
|
|
56
|
+
const parts = [];
|
|
57
|
+
while (element && element.nodeType === 1) {
|
|
58
|
+
let index = 1;
|
|
59
|
+
let sibling = element.previousSibling;
|
|
60
|
+
while (sibling) {
|
|
61
|
+
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
|
|
62
|
+
index++;
|
|
63
|
+
}
|
|
64
|
+
sibling = sibling.previousSibling;
|
|
65
|
+
}
|
|
66
|
+
const tagName = element.tagName.toLowerCase();
|
|
67
|
+
parts.unshift(tagName + '[' + index + ']');
|
|
68
|
+
element = element.parentNode;
|
|
69
|
+
}
|
|
70
|
+
return '/' + parts.join('/');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 鼠标移动处理
|
|
74
|
+
function onMouseMove(e) {
|
|
75
|
+
if (!isActive) return;
|
|
76
|
+
|
|
77
|
+
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
78
|
+
if (!target || target === overlay || target === infoBox) return;
|
|
79
|
+
if (target.id?.startsWith('deepspider-')) return;
|
|
80
|
+
|
|
81
|
+
currentElement = target;
|
|
82
|
+
const rect = target.getBoundingClientRect();
|
|
83
|
+
|
|
84
|
+
// 更新高亮位置
|
|
85
|
+
overlay.style.left = rect.left + 'px';
|
|
86
|
+
overlay.style.top = rect.top + 'px';
|
|
87
|
+
overlay.style.width = rect.width + 'px';
|
|
88
|
+
overlay.style.height = rect.height + 'px';
|
|
89
|
+
overlay.style.display = 'block';
|
|
90
|
+
|
|
91
|
+
// 更新信息框
|
|
92
|
+
const tagName = target.tagName.toLowerCase();
|
|
93
|
+
const className = target.className ? '.' + target.className.split(' ')[0] : '';
|
|
94
|
+
const id = target.id ? '#' + target.id : '';
|
|
95
|
+
infoBox.textContent = tagName + id + className + ' | ' + Math.round(rect.width) + 'x' + Math.round(rect.height);
|
|
96
|
+
infoBox.style.left = rect.left + 'px';
|
|
97
|
+
infoBox.style.top = Math.max(0, rect.top - 24) + 'px';
|
|
98
|
+
infoBox.style.display = 'block';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 点击选中
|
|
102
|
+
function onClick(e) {
|
|
103
|
+
if (!isActive || !currentElement) return;
|
|
104
|
+
|
|
105
|
+
e.preventDefault();
|
|
106
|
+
e.stopPropagation();
|
|
107
|
+
|
|
108
|
+
const element = currentElement;
|
|
109
|
+
const text = element.innerText?.trim().slice(0, 500) || '';
|
|
110
|
+
const xpath = getXPath(element);
|
|
111
|
+
|
|
112
|
+
// 停止选择模式
|
|
113
|
+
stopSelector();
|
|
114
|
+
|
|
115
|
+
// 显示确认弹窗
|
|
116
|
+
deepspider.showConfirmDialog({
|
|
117
|
+
text,
|
|
118
|
+
xpath,
|
|
119
|
+
tagName: element.tagName.toLowerCase(),
|
|
120
|
+
element
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ESC 退出
|
|
125
|
+
function onKeyDown(e) {
|
|
126
|
+
if (e.key === 'Escape' && isActive) {
|
|
127
|
+
stopSelector();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 启动选择器
|
|
132
|
+
function startSelector() {
|
|
133
|
+
if (isActive) return;
|
|
134
|
+
isActive = true;
|
|
135
|
+
|
|
136
|
+
if (!overlay) createOverlay();
|
|
137
|
+
|
|
138
|
+
document.addEventListener('mousemove', onMouseMove, true);
|
|
139
|
+
document.addEventListener('click', onClick, true);
|
|
140
|
+
document.addEventListener('keydown', onKeyDown, true);
|
|
141
|
+
document.body.style.cursor = 'crosshair';
|
|
142
|
+
|
|
143
|
+
console.log('[DeepSpider] 选择器模式已开启,点击选择元素,ESC 退出');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 停止选择器
|
|
147
|
+
function stopSelector() {
|
|
148
|
+
isActive = false;
|
|
149
|
+
|
|
150
|
+
document.removeEventListener('mousemove', onMouseMove, true);
|
|
151
|
+
document.removeEventListener('click', onClick, true);
|
|
152
|
+
document.removeEventListener('keydown', onKeyDown, true);
|
|
153
|
+
document.body.style.cursor = '';
|
|
154
|
+
|
|
155
|
+
if (overlay) overlay.style.display = 'none';
|
|
156
|
+
if (infoBox) infoBox.style.display = 'none';
|
|
157
|
+
currentElement = null;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 暴露 API
|
|
161
|
+
deepspider.startSelector = startSelector;
|
|
162
|
+
deepspider.stopSelector = stopSelector;
|
|
163
|
+
deepspider.isSelectingMode = () => isActive;
|
|
164
|
+
|
|
165
|
+
console.log('[DeepSpider] Selector 已加载');
|
|
166
|
+
})();
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default { generateSelectorScript };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSpider - 统一路径配置
|
|
3
|
+
* 所有存储路径统一到 ~/.deepspider/ 目录
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
import { mkdirSync, existsSync } from 'fs';
|
|
9
|
+
|
|
10
|
+
// 基础目录:~/.deepspider/
|
|
11
|
+
export const DEEPSPIDER_HOME = join(homedir(), '.deepspider');
|
|
12
|
+
|
|
13
|
+
// 子目录
|
|
14
|
+
export const PATHS = {
|
|
15
|
+
// 采集数据(响应、脚本)
|
|
16
|
+
DATA_DIR: join(DEEPSPIDER_HOME, 'data'),
|
|
17
|
+
SITES_DIR: join(DEEPSPIDER_HOME, 'data', 'sites'),
|
|
18
|
+
|
|
19
|
+
// 知识库(加密模式、环境补丁等)
|
|
20
|
+
STORE_DIR: join(DEEPSPIDER_HOME, 'store'),
|
|
21
|
+
|
|
22
|
+
// Agent 输出
|
|
23
|
+
OUTPUT_DIR: join(DEEPSPIDER_HOME, 'output'),
|
|
24
|
+
REPORTS_DIR: join(DEEPSPIDER_HOME, 'output', 'reports'),
|
|
25
|
+
SCREENSHOTS_DIR: join(DEEPSPIDER_HOME, 'output', 'screenshots'),
|
|
26
|
+
UNPACKED_DIR: join(DEEPSPIDER_HOME, 'output', 'unpacked'),
|
|
27
|
+
|
|
28
|
+
// 配置(预留)
|
|
29
|
+
CONFIG_DIR: join(DEEPSPIDER_HOME, 'config'),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 确保目录存在
|
|
34
|
+
*/
|
|
35
|
+
export function ensureDir(dir) {
|
|
36
|
+
if (dir && !existsSync(dir)) {
|
|
37
|
+
mkdirSync(dir, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 初始化所有目录
|
|
43
|
+
*/
|
|
44
|
+
export function initDirectories() {
|
|
45
|
+
Object.values(PATHS).forEach(dir => ensureDir(dir));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 获取站点数据目录
|
|
50
|
+
*/
|
|
51
|
+
export function getSiteDataDir(hostname) {
|
|
52
|
+
return join(PATHS.SITES_DIR, hostname);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 获取报告目录(按域名)
|
|
57
|
+
*/
|
|
58
|
+
export function getReportDir(domain) {
|
|
59
|
+
const safeDomain = domain.replace(/[^a-zA-Z0-9.-]/g, '_');
|
|
60
|
+
return join(PATHS.REPORTS_DIR, safeDomain);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 生成带时间戳的文件名
|
|
65
|
+
*/
|
|
66
|
+
export function generateFilename(prefix, ext) {
|
|
67
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
68
|
+
return `${prefix}_${timestamp}.${ext}`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export default PATHS;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSpider - 加密模式配置
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const cryptoPatterns = {
|
|
6
|
+
md5: {
|
|
7
|
+
name: 'MD5',
|
|
8
|
+
type: 'hash',
|
|
9
|
+
signatures: [/md5\s*\(/i, /[0-9a-f]{32}/i],
|
|
10
|
+
outputLength: 32
|
|
11
|
+
},
|
|
12
|
+
sha256: {
|
|
13
|
+
name: 'SHA256',
|
|
14
|
+
type: 'hash',
|
|
15
|
+
signatures: [/sha256|SHA256/, /[0-9a-f]{64}/i],
|
|
16
|
+
outputLength: 64
|
|
17
|
+
},
|
|
18
|
+
aes: {
|
|
19
|
+
name: 'AES',
|
|
20
|
+
type: 'symmetric',
|
|
21
|
+
signatures: [/CryptoJS\.AES/, /aes.*encrypt/i],
|
|
22
|
+
keyLengths: [16, 24, 32]
|
|
23
|
+
},
|
|
24
|
+
rsa: {
|
|
25
|
+
name: 'RSA',
|
|
26
|
+
type: 'asymmetric',
|
|
27
|
+
signatures: [/JSEncrypt/, /RSAKey/]
|
|
28
|
+
},
|
|
29
|
+
base64: {
|
|
30
|
+
name: 'Base64',
|
|
31
|
+
type: 'encoding',
|
|
32
|
+
signatures: [/btoa|atob/]
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default cryptoPatterns;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Chrome 120 Windows",
|
|
3
|
+
"browser": "chrome",
|
|
4
|
+
"version": "120.0.0.0",
|
|
5
|
+
"platform": "Win32",
|
|
6
|
+
|
|
7
|
+
"navigator": {
|
|
8
|
+
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
9
|
+
"appVersion": "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
10
|
+
"platform": "Win32",
|
|
11
|
+
"language": "zh-CN",
|
|
12
|
+
"languages": ["zh-CN", "zh", "en"],
|
|
13
|
+
"cookieEnabled": true,
|
|
14
|
+
"doNotTrack": null,
|
|
15
|
+
"maxTouchPoints": 0,
|
|
16
|
+
"hardwareConcurrency": 8,
|
|
17
|
+
"deviceMemory": 8,
|
|
18
|
+
"vendor": "Google Inc.",
|
|
19
|
+
"vendorSub": "",
|
|
20
|
+
"productSub": "20030107",
|
|
21
|
+
"webdriver": false,
|
|
22
|
+
"plugins": [
|
|
23
|
+
{ "name": "PDF Viewer", "filename": "internal-pdf-viewer" },
|
|
24
|
+
{ "name": "Chrome PDF Viewer", "filename": "internal-pdf-viewer" },
|
|
25
|
+
{ "name": "Chromium PDF Viewer", "filename": "internal-pdf-viewer" }
|
|
26
|
+
],
|
|
27
|
+
"mimeTypes": [
|
|
28
|
+
{ "type": "application/pdf", "suffixes": "pdf" },
|
|
29
|
+
{ "type": "text/pdf", "suffixes": "pdf" }
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
"screen": {
|
|
34
|
+
"width": 1920,
|
|
35
|
+
"height": 1080,
|
|
36
|
+
"availWidth": 1920,
|
|
37
|
+
"availHeight": 1040,
|
|
38
|
+
"colorDepth": 24,
|
|
39
|
+
"pixelDepth": 24
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
"window": {
|
|
43
|
+
"innerWidth": 1920,
|
|
44
|
+
"innerHeight": 937,
|
|
45
|
+
"outerWidth": 1920,
|
|
46
|
+
"outerHeight": 1040,
|
|
47
|
+
"devicePixelRatio": 1
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
"document": {
|
|
51
|
+
"characterSet": "UTF-8",
|
|
52
|
+
"compatMode": "CSS1Compat",
|
|
53
|
+
"contentType": "text/html"
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
"chrome": {
|
|
57
|
+
"app": {},
|
|
58
|
+
"runtime": {
|
|
59
|
+
"id": null
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
"canvas": {
|
|
64
|
+
"fingerprint": "canvas-fp-chrome-120"
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"webgl": {
|
|
68
|
+
"vendor": "Google Inc. (NVIDIA)",
|
|
69
|
+
"renderer": "ANGLE (NVIDIA, NVIDIA GeForce GTX 1060 Direct3D11 vs_5_0 ps_5_0)"
|
|
70
|
+
}
|
|
71
|
+
}
|