splitagent 0.0.3__py3-none-any.whl
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.
- splitagent/__init__.py +8 -0
- splitagent/__main__.py +6 -0
- splitagent/agents/__init__.py +10 -0
- splitagent/agents/base.py +477 -0
- splitagent/agents/blue.py +57 -0
- splitagent/agents/chat.py +60 -0
- splitagent/agents/prompts.py +462 -0
- splitagent/agents/red.py +75 -0
- splitagent/cli.py +701 -0
- splitagent/config.py +697 -0
- splitagent/core/__init__.py +19 -0
- splitagent/core/bus.py +62 -0
- splitagent/core/context.py +587 -0
- splitagent/core/context_manager.py +381 -0
- splitagent/core/engine.py +424 -0
- splitagent/core/models.py +310 -0
- splitagent/core/proc.py +73 -0
- splitagent/core/sandbox.py +184 -0
- splitagent/core/toolbox.py +520 -0
- splitagent/core/workspace.py +420 -0
- splitagent/desktop/__init__.py +7 -0
- splitagent/desktop/api.py +525 -0
- splitagent/desktop/app.py +1131 -0
- splitagent/desktop/web/app.js +3067 -0
- splitagent/desktop/web/assets/Inter.ttf +0 -0
- splitagent/desktop/web/assets/JetBrainsMonoNerdFontMono-Regular.woff2 +0 -0
- splitagent/desktop/web/index.html +760 -0
- splitagent/desktop/web/styles.css +1612 -0
- splitagent/errors.py +27 -0
- splitagent/llm/__init__.py +8 -0
- splitagent/llm/client.py +488 -0
- splitagent/llm/types.py +172 -0
- splitagent/report/__init__.py +9 -0
- splitagent/report/cvss.py +93 -0
- splitagent/report/generator.py +733 -0
- splitagent/tools/__init__.py +8 -0
- splitagent/tools/base.py +135 -0
- splitagent/tools/defense.py +475 -0
- splitagent/tools/exploit.py +318 -0
- splitagent/tools/http_pool.py +109 -0
- splitagent/tools/knowledge.py +376 -0
- splitagent/tools/recon.py +182 -0
- splitagent/tools/registry.py +62 -0
- splitagent/tools/validate.py +908 -0
- splitagent/tools/web.py +386 -0
- splitagent/tools/workspace_tools.py +411 -0
- splitagent/ui/__init__.py +5 -0
- splitagent/ui/app.py +389 -0
- splitagent/ui/stream.py +234 -0
- splitagent/ui/theme.py +72 -0
- splitagent-0.0.3.dist-info/METADATA +987 -0
- splitagent-0.0.3.dist-info/RECORD +56 -0
- splitagent-0.0.3.dist-info/WHEEL +5 -0
- splitagent-0.0.3.dist-info/entry_points.txt +2 -0
- splitagent-0.0.3.dist-info/licenses/LICENSE +21 -0
- splitagent-0.0.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,760 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>SplitAgent</title>
|
|
7
|
+
<link rel="stylesheet" href="styles.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app">
|
|
11
|
+
<!-- Titlebar -->
|
|
12
|
+
<header class="titlebar pywebview-drag-region">
|
|
13
|
+
<div class="tb-left">
|
|
14
|
+
<div class="brand">
|
|
15
|
+
<svg class="brand-mark" viewBox="0 0 24 24" aria-hidden="true">
|
|
16
|
+
<path d="M12 2.2 20.5 7v10L12 21.8 3.5 17V7L12 2.2Z" fill="none"
|
|
17
|
+
stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/>
|
|
18
|
+
<path d="M12 2.2V21.8" stroke="var(--red)" stroke-width="1.6"/>
|
|
19
|
+
<path d="M12 12 20.5 7M12 12 3.5 7" stroke="var(--blue)" stroke-width="1.2" opacity=".8"/>
|
|
20
|
+
</svg>
|
|
21
|
+
<span class="brand-name">SplitAgent</span>
|
|
22
|
+
<span class="brand-ver" id="brand-ver"></span>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="mode-switch" id="mode-switch">
|
|
25
|
+
<button class="mode-btn active" data-mode="audit">
|
|
26
|
+
<svg viewBox="0 0 16 16"><path d="M8 1.5 14 5v6l-6 3.5L2 11V5l6-3.5Z" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M8 8 14 5M8 8 2 5M8 8v6.5" fill="none" stroke="currentColor" stroke-width="1.1"/></svg>
|
|
27
|
+
Audit
|
|
28
|
+
</button>
|
|
29
|
+
<button class="mode-btn" data-mode="chat">
|
|
30
|
+
<svg viewBox="0 0 16 16"><path d="M2.5 3.5h11v7h-6l-3 2.5v-2.5h-2z" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/></svg>
|
|
31
|
+
Copilot
|
|
32
|
+
</button>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="tb-right">
|
|
36
|
+
<button class="icon-btn" id="btn-toggle-sidebar" title="Toggle sidebar (Ctrl+B)">
|
|
37
|
+
<svg viewBox="0 0 16 16"><rect x="2" y="3" width="12" height="10" rx="1.4" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M6.5 3v10" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
38
|
+
</button>
|
|
39
|
+
<button class="icon-btn" id="btn-toggle-review" title="Toggle panel (Ctrl+J)">
|
|
40
|
+
<svg viewBox="0 0 16 16"><rect x="2" y="3" width="12" height="10" rx="1.4" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M9.5 3v10" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
41
|
+
</button>
|
|
42
|
+
<button class="icon-btn" id="btn-command" title="Command palette (Ctrl+K)">
|
|
43
|
+
<svg viewBox="0 0 16 16"><path d="M6.5 6.5 2 2m8 4.5L14 2M6.5 9.5 2 14m8-4.5L14 14" stroke="currentColor" stroke-width="1.3" fill="none" stroke-linecap="round"/></svg>
|
|
44
|
+
</button>
|
|
45
|
+
<button class="icon-btn" id="btn-settings" title="Model settings">
|
|
46
|
+
<svg viewBox="0 0 16 16"><circle cx="8" cy="8" r="2.2" fill="none" stroke="currentColor" stroke-width="1.3"/><path d="M8 1.6v2M8 12.4v2M1.6 8h2M12.4 8h2M3.5 3.5l1.4 1.4M11.1 11.1l1.4 1.4M12.5 3.5l-1.4 1.4M4.9 11.1l-1.4 1.4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
|
|
47
|
+
</button>
|
|
48
|
+
<div class="window-controls">
|
|
49
|
+
<button class="wc" id="win-min" title="Minimize"><svg viewBox="0 0 12 12"><path d="M2 6h8" stroke="currentColor" stroke-width="1.2"/></svg></button>
|
|
50
|
+
<button class="wc" id="win-max" title="Maximize"><svg viewBox="0 0 12 12"><rect x="2.5" y="2.5" width="7" height="7" rx="1" fill="none" stroke="currentColor" stroke-width="1.1"/></svg></button>
|
|
51
|
+
<button class="wc close" id="win-close" title="Close"><svg viewBox="0 0 12 12"><path d="M3 3l6 6M9 3l-6 6" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></button>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</header>
|
|
55
|
+
|
|
56
|
+
<div class="body" id="body">
|
|
57
|
+
<div class="resizer" id="resize-sidebar" title="Drag to resize"></div>
|
|
58
|
+
<!-- Sidebar -->
|
|
59
|
+
<aside class="sidebar">
|
|
60
|
+
<div class="side-block">
|
|
61
|
+
<div class="side-label">Engagement</div>
|
|
62
|
+
<div class="target-card" id="target-card">
|
|
63
|
+
<div class="target-row">
|
|
64
|
+
<span class="badge kind" id="tgt-kind">web</span>
|
|
65
|
+
<span class="target-url" id="tgt-url">not configured</span>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="target-meta" id="tgt-meta">Run the guided setup to begin.</div>
|
|
68
|
+
<div class="target-actions">
|
|
69
|
+
<button class="mini-btn accent" id="btn-wizard">New audit</button>
|
|
70
|
+
<button class="mini-btn" id="btn-project">Advanced…</button>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="side-label ws-label">Workspace</div>
|
|
73
|
+
<button class="workspace-card" id="btn-workspace" title="Open the agents' working directory">
|
|
74
|
+
<svg viewBox="0 0 16 16"><path d="M1.5 4.5h5l1.2 1.5h6.8v6.5h-13z" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/></svg>
|
|
75
|
+
<span class="ws-name" id="ws-name">splitagent-workspace</span>
|
|
76
|
+
<span class="ws-badge" id="ws-badge">—</span>
|
|
77
|
+
</button>
|
|
78
|
+
<div class="side-label ws-label">Environment</div>
|
|
79
|
+
<button class="workspace-card" id="btn-toolbox" title="Isolated execution environment">
|
|
80
|
+
<svg viewBox="0 0 16 16"><path d="M2 5.5h12v7H2z" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/><path d="M6 5.5V4a2 2 0 0 1 4 0v1.5" fill="none" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
81
|
+
<span class="ws-name" id="tb-name">toolbox</span>
|
|
82
|
+
<span class="ws-badge" id="tb-badge">—</span>
|
|
83
|
+
</button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div class="side-block grow">
|
|
88
|
+
<div class="side-label">Sessions</div>
|
|
89
|
+
<div class="session-list" id="session-list"></div>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<div class="side-footer">
|
|
93
|
+
<button class="model-chip" id="side-model-btn" title="Choose model">
|
|
94
|
+
<span class="dot" id="side-model-dot"></span>
|
|
95
|
+
<span class="model-name" id="side-model-name">no model</span>
|
|
96
|
+
<svg viewBox="0 0 12 12" class="chev"><path d="M3 5l3 3 3-3" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
|
97
|
+
</button>
|
|
98
|
+
</div>
|
|
99
|
+
</aside>
|
|
100
|
+
|
|
101
|
+
<!-- Center -->
|
|
102
|
+
<main class="center">
|
|
103
|
+
<!-- AUDIT VIEW -->
|
|
104
|
+
<div class="view" id="view-audit">
|
|
105
|
+
<div class="stream" id="stream">
|
|
106
|
+
<div class="empty-state" id="stream-empty">
|
|
107
|
+
<div class="empty-mark">
|
|
108
|
+
<svg viewBox="0 0 24 24"><path d="M12 2.2 20.5 7v10L12 21.8 3.5 17V7L12 2.2Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/><path d="M12 2.2V21.8" stroke="var(--red)" stroke-width="1.4"/></svg>
|
|
109
|
+
</div>
|
|
110
|
+
<div>
|
|
111
|
+
<h1>Purple-team your target</h1>
|
|
112
|
+
<p>The <b class="red">Red Agent</b> maps the attack surface and proves weaknesses with
|
|
113
|
+
non-destructive evidence. The <b class="blue">Blue Agent</b> detects the activity,
|
|
114
|
+
applies countermeasures and verifies them.</p>
|
|
115
|
+
<button class="btn primary big" id="empty-start">Start guided setup</button>
|
|
116
|
+
<p class="muted">A few questions about the target and the system does the rest.
|
|
117
|
+
Prefer to ask first? Switch to <b>Copilot</b>.</p>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="todo-dock hidden" id="todo-dock">
|
|
123
|
+
<div class="td-head" id="td-toggle" role="button" tabindex="0">
|
|
124
|
+
<span class="td-progress"><b id="td-done">0</b> of <b id="td-total">0</b> todos completed</span>
|
|
125
|
+
<span class="td-preview" id="td-preview"></span>
|
|
126
|
+
<svg class="td-chevron" viewBox="0 0 12 12"><path d="M3 5l3 3 3-3" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
|
127
|
+
</div>
|
|
128
|
+
<div class="td-list" id="td-list"></div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<div class="composer">
|
|
132
|
+
<div class="composer-card audit-bar">
|
|
133
|
+
<div class="composer-bar">
|
|
134
|
+
<button class="pill model-trigger" id="model-pill" title="Choose model">
|
|
135
|
+
<span class="dot" id="pill-dot"></span>
|
|
136
|
+
<span id="pill-model">configure model</span>
|
|
137
|
+
<svg viewBox="0 0 12 12" class="chev"><path d="M3 5l3 3 3-3" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
|
138
|
+
</button>
|
|
139
|
+
<button class="btn ghost" id="btn-objective" title="What the audit is trying to achieve (set from the plan)">Objective: —</button>
|
|
140
|
+
<div class="spacer"></div>
|
|
141
|
+
<span class="dev-only-inline">
|
|
142
|
+
<label class="chip" title="Run in a disposable Docker container">
|
|
143
|
+
<input type="checkbox" id="opt-sandbox" /> Sandbox
|
|
144
|
+
</label>
|
|
145
|
+
<label class="chip num" title="Red/Blue rounds">
|
|
146
|
+
<span>rounds</span>
|
|
147
|
+
<input type="number" id="opt-rounds" min="1" max="10" value="3" />
|
|
148
|
+
</label>
|
|
149
|
+
</span>
|
|
150
|
+
<button class="btn ghost" id="btn-guided">New audit</button>
|
|
151
|
+
<button class="btn ghost" id="btn-plan-chat" title="Plan and ask the planner">Plan chat</button>
|
|
152
|
+
<button class="btn primary" id="btn-run">Run audit</button>
|
|
153
|
+
<button class="btn danger hidden" id="btn-stop">Stop</button>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<!-- CHAT VIEW -->
|
|
160
|
+
<div class="view hidden" id="view-chat">
|
|
161
|
+
<div class="stream" id="chat-stream">
|
|
162
|
+
<div class="empty-state" id="chat-empty">
|
|
163
|
+
<div class="empty-mark">
|
|
164
|
+
<svg viewBox="0 0 24 24"><path d="M3.5 5.5h17v10h-9l-4.5 4v-4H3.5z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
|
|
165
|
+
</div>
|
|
166
|
+
<h1>Pentest copilot</h1>
|
|
167
|
+
<p>Let's talk about the engagement first. Tell me what you want to test
|
|
168
|
+
and what matters, and I'll propose a plan. Nothing runs until you
|
|
169
|
+
approve it.</p>
|
|
170
|
+
<div class="suggestions">
|
|
171
|
+
<button class="suggestion">I want to test my web app — where do we start?</button>
|
|
172
|
+
<button class="suggestion">Help me scope a pentest for my target</button>
|
|
173
|
+
<button class="suggestion">What should I consider before testing?</button>
|
|
174
|
+
<button class="suggestion">Explain CVSS and how you score findings</button>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<div class="composer">
|
|
180
|
+
<div class="composer-card">
|
|
181
|
+
<textarea id="chat-input" rows="1"
|
|
182
|
+
placeholder="Ask the copilot… (Ctrl+Enter to send)"></textarea>
|
|
183
|
+
<div class="composer-bar">
|
|
184
|
+
<button class="pill model-trigger" id="chat-model-pill" title="Choose model">
|
|
185
|
+
<span class="dot" id="chat-pill-dot"></span>
|
|
186
|
+
<span id="chat-pill-model">configure model</span>
|
|
187
|
+
<svg viewBox="0 0 12 12" class="chev"><path d="M3 5l3 3 3-3" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
|
188
|
+
</button>
|
|
189
|
+
<div class="spacer"></div>
|
|
190
|
+
<button class="btn ghost" id="chat-clear">Clear</button>
|
|
191
|
+
<button class="btn primary" id="chat-send">Send</button>
|
|
192
|
+
<button class="btn danger hidden" id="chat-stop">Stop</button>
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</div>
|
|
197
|
+
</main>
|
|
198
|
+
|
|
199
|
+
<div class="resizer" id="resize-review" title="Drag to resize"></div>
|
|
200
|
+
<!-- Review panel -->
|
|
201
|
+
<aside class="review">
|
|
202
|
+
<div class="review-tabs" id="review-tabs">
|
|
203
|
+
<button class="rtab active" data-tab="dashboard">Dashboard</button>
|
|
204
|
+
<button class="rtab" data-tab="plan">Plan chat</button>
|
|
205
|
+
<button class="rtab" data-tab="findings">Findings <span class="count" id="count-findings">0</span></button>
|
|
206
|
+
<button class="rtab" data-tab="mitigations">Mitigations <span class="count" id="count-mitigations">0</span></button>
|
|
207
|
+
<button class="rtab" data-tab="report">Report</button>
|
|
208
|
+
<button class="rtab" data-tab="trace">Trace</button>
|
|
209
|
+
<button class="rtab" data-tab="activity">Activity</button>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="review-body">
|
|
212
|
+
<div class="rpanel active" id="panel-dashboard">
|
|
213
|
+
<div class="panel-empty">Run an audit to see the results here.</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="rpanel" id="panel-plan">
|
|
216
|
+
<div class="plan-chat-log" id="plan-chat-log">
|
|
217
|
+
<div class="panel-empty">Talk to the planner about the plan here. It only plans — it never tests.</div>
|
|
218
|
+
</div>
|
|
219
|
+
<div class="plan-chat-row">
|
|
220
|
+
<input id="plan-chat-input" placeholder="Ask about the plan or the environment…" />
|
|
221
|
+
<button class="mini-btn accent" id="plan-chat-send">Send</button>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
<div class="rpanel" id="panel-findings">
|
|
225
|
+
<div class="panel-empty">No findings yet.</div>
|
|
226
|
+
</div>
|
|
227
|
+
<div class="rpanel" id="panel-mitigations">
|
|
228
|
+
<div class="panel-empty">No mitigations yet.</div>
|
|
229
|
+
</div>
|
|
230
|
+
<div class="rpanel" id="panel-report">
|
|
231
|
+
<div class="panel-empty">The report is generated at the end of a run.</div>
|
|
232
|
+
</div>
|
|
233
|
+
<div class="rpanel" id="panel-trace">
|
|
234
|
+
<div class="trace-head">
|
|
235
|
+
<span>Full replay: every reasoning step, tool call with arguments and
|
|
236
|
+
output, token usage and context event.</span>
|
|
237
|
+
<button class="mini-btn" id="btn-dump-trace">Dump JSON</button>
|
|
238
|
+
</div>
|
|
239
|
+
<div class="trace-empty">Nothing captured yet.</div>
|
|
240
|
+
</div>
|
|
241
|
+
<div class="rpanel" id="panel-activity"></div>
|
|
242
|
+
</div>
|
|
243
|
+
<div class="review-footer">
|
|
244
|
+
<button class="btn ghost" id="btn-export">Export report</button>
|
|
245
|
+
<button class="btn ghost" id="btn-open-reports" disabled>Open folder</button>
|
|
246
|
+
</div>
|
|
247
|
+
</aside>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<footer class="statusbar">
|
|
251
|
+
<span class="st" id="st-mode">audit</span>
|
|
252
|
+
<span class="st sep">·</span>
|
|
253
|
+
<span class="st" id="st-provider">—</span>
|
|
254
|
+
<span class="st sep">·</span>
|
|
255
|
+
<span class="st" id="st-round">round 0/0</span>
|
|
256
|
+
<span class="st sep">·</span>
|
|
257
|
+
<span class="st phase" id="st-phase">idle</span>
|
|
258
|
+
<span class="st spacer"></span>
|
|
259
|
+
<span class="st" id="st-events">0 events</span>
|
|
260
|
+
<span class="st" id="st-context">context —</span>
|
|
261
|
+
<span class="resilience" title="Share of the discovered attack surface that is mitigated">
|
|
262
|
+
<span class="bar"><i id="res-bar" style="width:100%"></i></span>
|
|
263
|
+
<b id="st-resilience">100</b>
|
|
264
|
+
</span>
|
|
265
|
+
</footer>
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<!-- Model picker popover (OpenCode-style) -->
|
|
269
|
+
<div class="model-popover hidden" id="model-popover">
|
|
270
|
+
<div class="mp-search">
|
|
271
|
+
<svg viewBox="0 0 16 16"><circle cx="7" cy="7" r="4.2" fill="none" stroke="currentColor" stroke-width="1.3"/><path d="M10.2 10.2 14 14" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
|
|
272
|
+
<input id="mp-input" placeholder="Search models" spellcheck="false" autocomplete="off" />
|
|
273
|
+
<button id="mp-clear" class="mp-clear hidden" title="Clear">✕</button>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="mp-divider"></div>
|
|
276
|
+
<div class="mp-list" id="mp-list"></div>
|
|
277
|
+
<div class="mp-divider"></div>
|
|
278
|
+
<div class="mp-manage" id="mp-manage">
|
|
279
|
+
<svg viewBox="0 0 16 16"><path d="M2 4h12M2 8h12M2 12h12" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/><circle cx="6" cy="4" r="1.6" fill="var(--bg-base)" stroke="currentColor" stroke-width="1.2"/><circle cx="11" cy="8" r="1.6" fill="var(--bg-base)" stroke="currentColor" stroke-width="1.2"/><circle cx="7" cy="12" r="1.6" fill="var(--bg-base)" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
280
|
+
<span>Manage models…</span>
|
|
281
|
+
</div>
|
|
282
|
+
</div>
|
|
283
|
+
|
|
284
|
+
<!-- Guided audit wizard -->
|
|
285
|
+
<div class="overlay hidden" id="modal-wizard">
|
|
286
|
+
<div class="dialog wizard">
|
|
287
|
+
<div class="wizard-head">
|
|
288
|
+
<div>
|
|
289
|
+
<h2>New audit</h2>
|
|
290
|
+
<p class="dialog-sub" id="wiz-hint">What kind of target are you testing?</p>
|
|
291
|
+
</div>
|
|
292
|
+
<button class="icon-btn" data-close>✕</button>
|
|
293
|
+
</div>
|
|
294
|
+
<div class="wizard-progress" id="wiz-progress">
|
|
295
|
+
<span class="wdot active"></span><span class="wdot"></span><span class="wdot"></span><span class="wdot"></span><span class="wdot"></span><span class="wdot"></span>
|
|
296
|
+
</div>
|
|
297
|
+
<div class="wizard-body">
|
|
298
|
+
<!-- Step 0: kind -->
|
|
299
|
+
<section class="wstep active" data-step="0">
|
|
300
|
+
<div class="kind-grid" id="kind-grid">
|
|
301
|
+
<button class="kind-card" data-kind="web">
|
|
302
|
+
<svg viewBox="0 0 20 20"><circle cx="10" cy="10" r="7" fill="none" stroke="currentColor" stroke-width="1.3"/><path d="M3 10h14M10 3c2 2 2 12 0 14M10 3c-2 2-2 12 0 14" fill="none" stroke="currentColor" stroke-width="1.1"/></svg>
|
|
303
|
+
<b>Web application</b><span>Site or app with a browser UI</span>
|
|
304
|
+
</button>
|
|
305
|
+
<button class="kind-card" data-kind="api">
|
|
306
|
+
<svg viewBox="0 0 20 20"><path d="M6 5 2 10l4 5M14 5l4 5-4 5M11 4l-2 12" fill="none" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
|
|
307
|
+
<b>API</b><span>REST / GraphQL endpoint</span>
|
|
308
|
+
</button>
|
|
309
|
+
<button class="kind-card" data-kind="network">
|
|
310
|
+
<svg viewBox="0 0 20 20"><rect x="7" y="2" width="6" height="4" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/><rect x="2" y="14" width="6" height="4" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/><rect x="12" y="14" width="6" height="4" rx="1" fill="none" stroke="currentColor" stroke-width="1.2"/><path d="M10 6v4M5 14v-2h10v2" fill="none" stroke="currentColor" stroke-width="1.2"/></svg>
|
|
311
|
+
<b>Network / host</b><span>IP range or single host</span>
|
|
312
|
+
</button>
|
|
313
|
+
<button class="kind-card" data-kind="repo">
|
|
314
|
+
<svg viewBox="0 0 20 20"><path d="M4 3h9l3 3v11H4z" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/><path d="M13 3v3h3M7 9h6M7 12h6" fill="none" stroke="currentColor" stroke-width="1.1"/></svg>
|
|
315
|
+
<b>Repository</b><span>Source code review</span>
|
|
316
|
+
</button>
|
|
317
|
+
</div>
|
|
318
|
+
</section>
|
|
319
|
+
|
|
320
|
+
<!-- Step 1: address -->
|
|
321
|
+
<section class="wstep" data-step="1">
|
|
322
|
+
<label class="field span2">
|
|
323
|
+
<span id="wiz-url-label">Target URL</span>
|
|
324
|
+
<input id="wiz-url" placeholder="http://localhost:3000" />
|
|
325
|
+
</label>
|
|
326
|
+
<label class="field span2">
|
|
327
|
+
<span>In scope (auto-filled, comma separated)</span>
|
|
328
|
+
<input id="wiz-scope" placeholder="localhost" />
|
|
329
|
+
</label>
|
|
330
|
+
<label class="field span2">
|
|
331
|
+
<span>Out of scope — never touch (optional)</span>
|
|
332
|
+
<input id="wiz-out" placeholder="production.example.com" />
|
|
333
|
+
</label>
|
|
334
|
+
<label class="field span2">
|
|
335
|
+
<span>Ports to scan (optional)</span>
|
|
336
|
+
<input id="wiz-ports" placeholder="80, 443, 3000, 8080" />
|
|
337
|
+
</label>
|
|
338
|
+
<div class="preset-row" id="wiz-presets">
|
|
339
|
+
<span class="preset-label">Lab presets:</span>
|
|
340
|
+
<button class="mini-btn" data-preset="juice-shop">juice-shop</button>
|
|
341
|
+
<button class="mini-btn" data-preset="dvwa">dvwa</button>
|
|
342
|
+
<button class="mini-btn" data-preset="bwapp">bwapp</button>
|
|
343
|
+
<button class="mini-btn" data-preset="webgoat">webgoat</button>
|
|
344
|
+
</div>
|
|
345
|
+
</section>
|
|
346
|
+
|
|
347
|
+
<!-- Step 2: environment -->
|
|
348
|
+
<section class="wstep" data-step="2">
|
|
349
|
+
<div class="choice-list">
|
|
350
|
+
<label class="choice">
|
|
351
|
+
<input type="radio" name="env" value="sandbox" checked />
|
|
352
|
+
<div><b>Launch a disposable sandbox</b><span>A Docker container is created, tested and removed. Recommended.</span></div>
|
|
353
|
+
</label>
|
|
354
|
+
<label class="choice">
|
|
355
|
+
<input type="radio" name="env" value="existing" />
|
|
356
|
+
<div><b>Test the target as-is</b><span>Run against the real endpoint. Make sure you are authorised.</span></div>
|
|
357
|
+
</label>
|
|
358
|
+
</div>
|
|
359
|
+
<label class="field span2" id="wiz-image-field">
|
|
360
|
+
<span>Sandbox image</span>
|
|
361
|
+
<input id="wiz-image" placeholder="bkimminich/juice-shop:latest" />
|
|
362
|
+
</label>
|
|
363
|
+
<label class="field check">
|
|
364
|
+
<input type="checkbox" id="wiz-network" /> <span>Allow testing hosts outside the scope (lab only)</span>
|
|
365
|
+
</label>
|
|
366
|
+
</section>
|
|
367
|
+
|
|
368
|
+
<!-- Step 3: access -->
|
|
369
|
+
<section class="wstep" data-step="3">
|
|
370
|
+
<p class="wiz-note">Optional. If you have credentials, the agents test authenticated
|
|
371
|
+
surfaces too. Stored locally in <code>splitagent.yaml</code>.</p>
|
|
372
|
+
<div class="form-grid">
|
|
373
|
+
<label class="field"><span>Username</span><input id="wiz-user" placeholder="admin" /></label>
|
|
374
|
+
<label class="field"><span>Password</span><input id="wiz-pass" type="password" placeholder="••••••" /></label>
|
|
375
|
+
<label class="field span2"><span>Bearer token / API key</span><input id="wiz-token" type="password" placeholder="eyJ…" /></label>
|
|
376
|
+
<label class="field span2"><span>Cookie header</span><input id="wiz-cookies" placeholder="session=abc; csrf=xyz" /></label>
|
|
377
|
+
<label class="field span2"><span>Extra headers (one per line, <code>Name: value</code>)</span><textarea id="wiz-headers" rows="3" placeholder="X-API-Key: …"></textarea></label>
|
|
378
|
+
</div>
|
|
379
|
+
</section>
|
|
380
|
+
|
|
381
|
+
<!-- Step 4: depth + objective -->
|
|
382
|
+
<section class="wstep" data-step="4">
|
|
383
|
+
<div class="depth-grid" id="depth-grid">
|
|
384
|
+
<button class="depth-card" data-depth="quick"><b>Quick</b><span>1 round · 6 steps</span><em>~ a few minutes</em></button>
|
|
385
|
+
<button class="depth-card active" data-depth="standard"><b>Standard</b><span>3 rounds · 12 steps</span><em>balanced</em></button>
|
|
386
|
+
<button class="depth-card" data-depth="deep"><b>Deep</b><span>5 rounds · 20 steps</span><em>thorough</em></button>
|
|
387
|
+
</div>
|
|
388
|
+
<label class="field span2">
|
|
389
|
+
<span>Objective / notes for the agents (optional)</span>
|
|
390
|
+
<textarea id="wiz-objective" rows="3" placeholder="Focus on authentication and the search endpoint. Ignore marketing pages."></textarea>
|
|
391
|
+
</label>
|
|
392
|
+
<div class="form-grid">
|
|
393
|
+
<label class="field span2">
|
|
394
|
+
<span>Agent workspace — directory for tools, recon and notes</span>
|
|
395
|
+
<input id="wiz-ws-path" placeholder="splitagent-workspace (default)" />
|
|
396
|
+
</label>
|
|
397
|
+
<label class="field check">
|
|
398
|
+
<input type="checkbox" id="wiz-ws-install" checked />
|
|
399
|
+
<span>Let the agents install tooling</span>
|
|
400
|
+
</label>
|
|
401
|
+
<label class="field check">
|
|
402
|
+
<input type="checkbox" id="wiz-ws-external" checked />
|
|
403
|
+
<span>Let them run external tools</span>
|
|
404
|
+
</label>
|
|
405
|
+
<label class="field span2">
|
|
406
|
+
<span>Operator instructions (written to workspace/AGENTS.md)</span>
|
|
407
|
+
<textarea id="wiz-ws-instructions" rows="3" placeholder="Prefer passive recon first. Rotate user agents. Avoid noisy scanners."></textarea>
|
|
408
|
+
</label>
|
|
409
|
+
</div>
|
|
410
|
+
<div class="wiz-summary" id="wiz-summary"></div>
|
|
411
|
+
</section>
|
|
412
|
+
|
|
413
|
+
<!-- Step 5: brief (all optional) -->
|
|
414
|
+
<section class="wstep" data-step="5">
|
|
415
|
+
<p class="wiz-note">All optional. The more context you give, the better the
|
|
416
|
+
plan the planner proposes for this specific environment.</p>
|
|
417
|
+
<div class="scope-doc-row">
|
|
418
|
+
<button class="mini-btn accent" id="wiz-scope-upload">Upload scope document</button>
|
|
419
|
+
<span class="scope-doc-name" id="wiz-scope-name">No document attached.</span>
|
|
420
|
+
<button class="mini-btn ghostish hidden" id="wiz-scope-clear">Remove</button>
|
|
421
|
+
</div>
|
|
422
|
+
<div class="form-grid">
|
|
423
|
+
<label class="field span2">
|
|
424
|
+
<span>What matters most? (crown jewels)</span>
|
|
425
|
+
<input id="wiz-crown" placeholder="login & SSO, payments, admin panel, customer PII…" />
|
|
426
|
+
</label>
|
|
427
|
+
<label class="field">
|
|
428
|
+
<span>Engagement goal</span>
|
|
429
|
+
<select id="wiz-goal">
|
|
430
|
+
<option value="">full audit</option>
|
|
431
|
+
<option value="focused area">focused area</option>
|
|
432
|
+
<option value="compliance evidence">compliance evidence</option>
|
|
433
|
+
<option value="retest">retest</option>
|
|
434
|
+
<option value="research">research</option>
|
|
435
|
+
</select>
|
|
436
|
+
</label>
|
|
437
|
+
<label class="field">
|
|
438
|
+
<span>Noise profile</span>
|
|
439
|
+
<select id="wiz-noise">
|
|
440
|
+
<option value="normal">normal</option>
|
|
441
|
+
<option value="stealth">stealth</option>
|
|
442
|
+
<option value="aggressive">aggressive</option>
|
|
443
|
+
</select>
|
|
444
|
+
</label>
|
|
445
|
+
<label class="field span2">
|
|
446
|
+
<span>Areas / endpoints to exclude (optional)</span>
|
|
447
|
+
<input id="wiz-areas-exclude" placeholder="/billing/checkout, /admin/delete-*" />
|
|
448
|
+
</label>
|
|
449
|
+
<label class="field span2">
|
|
450
|
+
<span>Window / rate constraints (optional)</span>
|
|
451
|
+
<input id="wiz-window" placeholder="only after 20:00, max 5 req/s, avoid weekends" />
|
|
452
|
+
</label>
|
|
453
|
+
<label class="field span2">
|
|
454
|
+
<span>Authorization reference (optional)</span>
|
|
455
|
+
<input id="wiz-authorization" placeholder="ticket SEC-1234, signed SOW 2026-05" />
|
|
456
|
+
</label>
|
|
457
|
+
<label class="field span2">
|
|
458
|
+
<span>Additional notes for the planner (optional)</span>
|
|
459
|
+
<textarea id="wiz-notes" rows="3" placeholder="Legacy Windows host, WAF in front, staging only…"></textarea>
|
|
460
|
+
</label>
|
|
461
|
+
</div>
|
|
462
|
+
<div class="brief-refine">
|
|
463
|
+
<div class="brief-refine-head">
|
|
464
|
+
<span>Need to clarify something? Open the planner chat — it only plans, it never tests.</span>
|
|
465
|
+
</div>
|
|
466
|
+
<button class="mini-btn accent" id="wiz-open-planner">Open planner chat</button>
|
|
467
|
+
</div>
|
|
468
|
+
</section>
|
|
469
|
+
</div>
|
|
470
|
+
<div class="wizard-foot">
|
|
471
|
+
<button class="btn ghost" id="wiz-back">Back</button>
|
|
472
|
+
<span class="spacer"></span>
|
|
473
|
+
<button class="btn ghost" data-close>Cancel</button>
|
|
474
|
+
<button class="btn primary" id="wiz-next">Next</button>
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
</div>
|
|
478
|
+
|
|
479
|
+
<!-- Settings -->
|
|
480
|
+
<div class="overlay hidden" id="modal-settings">
|
|
481
|
+
<div class="dialog settings">
|
|
482
|
+
<div class="settings-head">
|
|
483
|
+
<div class="settings-tabs" id="settings-tabs">
|
|
484
|
+
<button class="stab active" data-stab="models">Models</button>
|
|
485
|
+
<button class="stab" data-stab="providers">Providers</button>
|
|
486
|
+
<button class="stab" data-stab="general">General</button>
|
|
487
|
+
</div>
|
|
488
|
+
<button class="icon-btn" data-close>✕</button>
|
|
489
|
+
</div>
|
|
490
|
+
|
|
491
|
+
<!-- Models tab -->
|
|
492
|
+
<section class="spanel active" id="spanel-models">
|
|
493
|
+
<div class="spanel-head">
|
|
494
|
+
<h2 class="spanel-title">Models</h2>
|
|
495
|
+
<button class="btn ghost" id="btn-add-model">+ Custom model</button>
|
|
496
|
+
</div>
|
|
497
|
+
<div class="ssearch">
|
|
498
|
+
<svg viewBox="0 0 16 16"><circle cx="7" cy="7" r="4.2" fill="none" stroke="currentColor" stroke-width="1.3"/><path d="M10.2 10.2 14 14" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/></svg>
|
|
499
|
+
<input id="s-model-search" placeholder="Search models" spellcheck="false" autocomplete="off" />
|
|
500
|
+
<button class="mp-clear hidden" id="s-model-search-clear">✕</button>
|
|
501
|
+
</div>
|
|
502
|
+
<div class="spanel-body" id="s-models-list"></div>
|
|
503
|
+
<p class="settings-hint">Toggle models to control what appears in the model picker.
|
|
504
|
+
Your active model is marked with a dot.</p>
|
|
505
|
+
</section>
|
|
506
|
+
|
|
507
|
+
<!-- Providers tab -->
|
|
508
|
+
<section class="spanel" id="spanel-providers">
|
|
509
|
+
<div class="spanel-head">
|
|
510
|
+
<h2 class="spanel-title">Providers</h2>
|
|
511
|
+
<button class="btn ghost" id="btn-connect-provider">+ Connect provider</button>
|
|
512
|
+
</div>
|
|
513
|
+
<div class="spanel-body">
|
|
514
|
+
<div class="s-section">
|
|
515
|
+
<div class="s-section-title">Connected</div>
|
|
516
|
+
<div class="s-list" id="s-connected"></div>
|
|
517
|
+
</div>
|
|
518
|
+
<div class="s-section">
|
|
519
|
+
<div class="s-section-title">Popular</div>
|
|
520
|
+
<div class="s-list" id="s-popular"></div>
|
|
521
|
+
</div>
|
|
522
|
+
</div>
|
|
523
|
+
</section>
|
|
524
|
+
|
|
525
|
+
<!-- General tab -->
|
|
526
|
+
<section class="spanel" id="spanel-general">
|
|
527
|
+
<div class="spanel-head"><h2 class="spanel-title">General</h2></div>
|
|
528
|
+
<div class="spanel-body">
|
|
529
|
+
<div class="s-section">
|
|
530
|
+
<div class="s-section-title">Inference</div>
|
|
531
|
+
<div class="form-grid">
|
|
532
|
+
<label class="field">
|
|
533
|
+
<span>Temperature</span>
|
|
534
|
+
<input id="f-temperature" type="number" step="0.1" min="0" max="2" />
|
|
535
|
+
</label>
|
|
536
|
+
<label class="field">
|
|
537
|
+
<span>Max tokens</span>
|
|
538
|
+
<input id="f-max-tokens" type="number" step="256" min="256" />
|
|
539
|
+
</label>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
542
|
+
<div class="s-section">
|
|
543
|
+
<div class="s-section-title">Configuration file</div>
|
|
544
|
+
<div class="config-row">
|
|
545
|
+
<code id="settings-path"></code>
|
|
546
|
+
<button class="btn ghost" id="btn-open-config">Open folder</button>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
<div class="test-row">
|
|
550
|
+
<button class="btn ghost" id="btn-test">Test connection</button>
|
|
551
|
+
<span class="test-result" id="test-result"></span>
|
|
552
|
+
</div>
|
|
553
|
+
</div>
|
|
554
|
+
</section>
|
|
555
|
+
|
|
556
|
+
<div class="settings-foot">
|
|
557
|
+
<span class="settings-status" id="settings-status"></span>
|
|
558
|
+
<span class="spacer"></span>
|
|
559
|
+
<button class="btn ghost" data-close>Close</button>
|
|
560
|
+
<button class="btn primary" id="btn-save-settings">Save</button>
|
|
561
|
+
</div>
|
|
562
|
+
</div>
|
|
563
|
+
</div>
|
|
564
|
+
|
|
565
|
+
<!-- Connect provider modal -->
|
|
566
|
+
<div class="overlay hidden" id="modal-provider">
|
|
567
|
+
<div class="dialog wide">
|
|
568
|
+
<div class="dialog-head">
|
|
569
|
+
<h2 id="provider-title">Connect provider</h2>
|
|
570
|
+
<button class="icon-btn" data-close>✕</button>
|
|
571
|
+
</div>
|
|
572
|
+
<p class="dialog-sub">Keys are stored locally in <code>splitagent config.yaml</code>.</p>
|
|
573
|
+
<div class="form-grid">
|
|
574
|
+
<label class="field span2">
|
|
575
|
+
<span>Provider</span>
|
|
576
|
+
<select id="pr-provider"></select>
|
|
577
|
+
</label>
|
|
578
|
+
<label class="field span2">
|
|
579
|
+
<span>Base URL</span>
|
|
580
|
+
<input id="pr-base-url" placeholder="https://api.openai.com/v1" />
|
|
581
|
+
</label>
|
|
582
|
+
<label class="field span2">
|
|
583
|
+
<span>API key</span>
|
|
584
|
+
<input id="pr-api-key" type="password" placeholder="sk-…" />
|
|
585
|
+
</label>
|
|
586
|
+
<label class="field span2">
|
|
587
|
+
<span>Default model (optional — the catalogue is fetched on connect)</span>
|
|
588
|
+
<input id="pr-model" placeholder="gpt-4o-mini" />
|
|
589
|
+
</label>
|
|
590
|
+
</div>
|
|
591
|
+
<label class="field check">
|
|
592
|
+
<input type="checkbox" id="pr-activate" checked /> <span>Make this the active provider</span>
|
|
593
|
+
</label>
|
|
594
|
+
<div class="dialog-foot">
|
|
595
|
+
<button class="btn ghost" data-close>Cancel</button>
|
|
596
|
+
<button class="btn primary" id="btn-provider-connect">Connect</button>
|
|
597
|
+
</div>
|
|
598
|
+
</div>
|
|
599
|
+
</div>
|
|
600
|
+
|
|
601
|
+
<!-- Add custom model -->
|
|
602
|
+
<div class="overlay hidden" id="modal-model">
|
|
603
|
+
<div class="dialog">
|
|
604
|
+
<div class="dialog-head">
|
|
605
|
+
<h2>Custom model</h2>
|
|
606
|
+
<button class="icon-btn" data-close>✕</button>
|
|
607
|
+
</div>
|
|
608
|
+
<p class="dialog-sub">Add a model id that the provider catalogue does not list.</p>
|
|
609
|
+
<div class="form-grid">
|
|
610
|
+
<label class="field span2">
|
|
611
|
+
<span>Provider</span>
|
|
612
|
+
<select id="cm-provider"></select>
|
|
613
|
+
</label>
|
|
614
|
+
<label class="field span2">
|
|
615
|
+
<span>Model id</span>
|
|
616
|
+
<input id="cm-id" placeholder="my-model-id" />
|
|
617
|
+
</label>
|
|
618
|
+
<label class="field span2">
|
|
619
|
+
<span>Display name (optional)</span>
|
|
620
|
+
<input id="cm-name" placeholder="My model" />
|
|
621
|
+
</label>
|
|
622
|
+
</div>
|
|
623
|
+
<div class="dialog-foot">
|
|
624
|
+
<button class="btn ghost" data-close>Cancel</button>
|
|
625
|
+
<button class="btn primary" id="btn-model-add">Add</button>
|
|
626
|
+
</div>
|
|
627
|
+
</div>
|
|
628
|
+
</div>
|
|
629
|
+
|
|
630
|
+
<!-- Project modal -->
|
|
631
|
+
<div class="overlay hidden" id="modal-project">
|
|
632
|
+
<div class="dialog wide">
|
|
633
|
+
<div class="dialog-head">
|
|
634
|
+
<h2>Engagement</h2>
|
|
635
|
+
<button class="icon-btn" data-close>✕</button>
|
|
636
|
+
</div>
|
|
637
|
+
<p class="dialog-sub">Target scope and run parameters, saved to <code id="project-path"></code>.</p>
|
|
638
|
+
<div class="form-grid">
|
|
639
|
+
<label class="field">
|
|
640
|
+
<span>Kind</span>
|
|
641
|
+
<select id="p-kind">
|
|
642
|
+
<option value="web">web</option>
|
|
643
|
+
<option value="api">api</option>
|
|
644
|
+
<option value="network">network</option>
|
|
645
|
+
<option value="repo">repo</option>
|
|
646
|
+
</select>
|
|
647
|
+
</label>
|
|
648
|
+
<label class="field">
|
|
649
|
+
<span>Target URL</span>
|
|
650
|
+
<input id="p-url" placeholder="http://localhost:3000" />
|
|
651
|
+
</label>
|
|
652
|
+
<label class="field span2">
|
|
653
|
+
<span>Scope (comma separated)</span>
|
|
654
|
+
<input id="p-scope" placeholder="localhost, 10.0.0.0/24" />
|
|
655
|
+
</label>
|
|
656
|
+
<label class="field span2">
|
|
657
|
+
<span>Out of scope (comma separated)</span>
|
|
658
|
+
<input id="p-out" placeholder="production.example.com" />
|
|
659
|
+
</label>
|
|
660
|
+
<label class="field">
|
|
661
|
+
<span>Rounds</span>
|
|
662
|
+
<input id="p-rounds" type="number" min="1" max="10" />
|
|
663
|
+
</label>
|
|
664
|
+
<label class="field">
|
|
665
|
+
<span>Max steps / turn</span>
|
|
666
|
+
<input id="p-steps" type="number" min="1" max="40" />
|
|
667
|
+
</label>
|
|
668
|
+
<label class="field">
|
|
669
|
+
<span>Sandbox image</span>
|
|
670
|
+
<input id="p-image" placeholder="bkimminich/juice-shop:latest" />
|
|
671
|
+
</label>
|
|
672
|
+
<label class="field check">
|
|
673
|
+
<input type="checkbox" id="p-sandbox" /> <span>Use Docker sandbox</span>
|
|
674
|
+
</label>
|
|
675
|
+
</div>
|
|
676
|
+
<div class="dialog-foot">
|
|
677
|
+
<button class="btn ghost" id="btn-load-project">Open file…</button>
|
|
678
|
+
<span class="spacer"></span>
|
|
679
|
+
<button class="btn ghost" data-close>Cancel</button>
|
|
680
|
+
<button class="btn primary" id="btn-save-project">Save</button>
|
|
681
|
+
</div>
|
|
682
|
+
</div>
|
|
683
|
+
</div>
|
|
684
|
+
|
|
685
|
+
<!-- Toolbox consent -->
|
|
686
|
+
<div class="overlay hidden" id="modal-toolbox">
|
|
687
|
+
<div class="dialog wide">
|
|
688
|
+
<div class="dialog-head">
|
|
689
|
+
<h2>Set up the isolated environment</h2>
|
|
690
|
+
<button class="icon-btn" data-close>✕</button>
|
|
691
|
+
</div>
|
|
692
|
+
<p class="dialog-sub">
|
|
693
|
+
SplitAgent installs and runs its security tools inside a disposable Docker
|
|
694
|
+
container, so your computer is never modified. Recommended for a
|
|
695
|
+
professional, reproducible workflow.
|
|
696
|
+
</p>
|
|
697
|
+
<div class="setup-box" id="tb-setup-box">
|
|
698
|
+
<div class="setup-row"><span>Docker</span><b id="tb-docker">checking…</b></div>
|
|
699
|
+
<div class="setup-row"><span>Engine</span><b id="tb-daemon">checking…</b></div>
|
|
700
|
+
<div class="setup-row"><span>Image</span><b id="tb-image">checking…</b></div>
|
|
701
|
+
<div class="setup-row"><span>Workspace</span><b id="tb-workspace">—</b></div>
|
|
702
|
+
</div>
|
|
703
|
+
<label class="field span2">
|
|
704
|
+
<span>Edition</span>
|
|
705
|
+
<select id="tb-edition">
|
|
706
|
+
<option value="standard">Standard — Debian + curated recon tools (~450 MB)</option>
|
|
707
|
+
<option value="kali">Professional — Kali Linux, everything (~2.5 GB)</option>
|
|
708
|
+
</select>
|
|
709
|
+
</label>
|
|
710
|
+
<p class="wiz-note" id="tb-hint">
|
|
711
|
+
The image is built once. After that the toolbox starts silently in the
|
|
712
|
+
background and you never have to touch Docker again.
|
|
713
|
+
</p>
|
|
714
|
+
<label class="field check">
|
|
715
|
+
<input type="checkbox" id="tb-autostart" checked />
|
|
716
|
+
<span>Start Docker automatically when needed</span>
|
|
717
|
+
</label>
|
|
718
|
+
<div class="test-row">
|
|
719
|
+
<span class="test-result" id="tb-progress"></span>
|
|
720
|
+
</div>
|
|
721
|
+
<div class="dialog-foot">
|
|
722
|
+
<button class="btn ghost" id="tb-skip">Continue without it</button>
|
|
723
|
+
<span class="spacer"></span>
|
|
724
|
+
<button class="btn ghost" data-close>Later</button>
|
|
725
|
+
<button class="btn primary" id="tb-install">Install environment</button>
|
|
726
|
+
</div>
|
|
727
|
+
</div>
|
|
728
|
+
</div>
|
|
729
|
+
|
|
730
|
+
<!-- Command palette -->
|
|
731
|
+
<div class="overlay hidden" id="modal-command">
|
|
732
|
+
<div class="dialog palette">
|
|
733
|
+
<input id="command-input" placeholder="Type a command…" autocomplete="off" />
|
|
734
|
+
<div class="command-list" id="command-list"></div>
|
|
735
|
+
</div>
|
|
736
|
+
</div>
|
|
737
|
+
|
|
738
|
+
<!-- Toast -->
|
|
739
|
+
<div class="toast hidden" id="toast"></div>
|
|
740
|
+
|
|
741
|
+
<!-- Boot intro -->
|
|
742
|
+
<div class="intro" id="intro">
|
|
743
|
+
<canvas class="intro-canvas" id="intro-canvas"></canvas>
|
|
744
|
+
<div class="intro-inner">
|
|
745
|
+
<svg class="intro-mark" viewBox="0 0 24 24" aria-hidden="true">
|
|
746
|
+
<path d="M12 2.2 20.5 7v10L12 21.8 3.5 17V7L12 2.2Z" fill="none"
|
|
747
|
+
stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/>
|
|
748
|
+
<path d="M12 2.2V21.8" stroke="var(--red)" stroke-width="1.4"/>
|
|
749
|
+
<path d="M12 12 20.5 7M12 12 3.5 7" stroke="var(--blue)" stroke-width="1" opacity=".8"/>
|
|
750
|
+
</svg>
|
|
751
|
+
<div class="intro-title">SplitAgent</div>
|
|
752
|
+
<div class="intro-sub">autonomous dual-team security</div>
|
|
753
|
+
<div class="intro-scan"><span></span></div>
|
|
754
|
+
<div class="intro-lines" id="intro-lines"></div>
|
|
755
|
+
</div>
|
|
756
|
+
</div>
|
|
757
|
+
|
|
758
|
+
<script src="app.js"></script>
|
|
759
|
+
</body>
|
|
760
|
+
</html>
|