dsh-pentester 2.2.0 → 2.3.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/README.md +54 -6
- package/agents/vulnerability/profile.yml +6 -3
- package/lib/build-id.json +1 -1
- package/lib/client.js +668 -165
- package/lib/client.js.map +3 -3
- package/lib/index.js +97 -38
- package/lib/index.js.map +1 -1
- package/package.json +5 -3
package/lib/client.js
CHANGED
|
@@ -16117,170 +16117,587 @@ var SEVERITY_COLORS = {
|
|
|
16117
16117
|
low: "#3b82f6",
|
|
16118
16118
|
info: "#6b7280"
|
|
16119
16119
|
};
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
|
|
16123
|
-
|
|
16124
|
-
{ style: { marginBottom: "4px" } },
|
|
16125
|
-
import_react10.default.createElement(
|
|
16126
|
-
"div",
|
|
16127
|
-
{
|
|
16128
|
-
onClick: () => setOpen(!open),
|
|
16129
|
-
style: {
|
|
16130
|
-
display: "flex",
|
|
16131
|
-
alignItems: "center",
|
|
16132
|
-
gap: "6px",
|
|
16133
|
-
padding: "6px 8px",
|
|
16134
|
-
cursor: "pointer",
|
|
16135
|
-
borderRadius: "4px",
|
|
16136
|
-
fontSize: "13px",
|
|
16137
|
-
fontWeight: 600,
|
|
16138
|
-
color: "var(--dsw-fg)",
|
|
16139
|
-
userSelect: "none"
|
|
16140
|
-
}
|
|
16141
|
-
},
|
|
16142
|
-
import_react10.default.createElement("span", {
|
|
16143
|
-
style: { fontSize: "12px", transition: "transform 0.15s", transform: open ? "rotate(90deg)" : "rotate(0deg)" }
|
|
16144
|
-
}, "\u25B6"),
|
|
16145
|
-
import_react10.default.createElement("span", null, props.title)
|
|
16146
|
-
),
|
|
16147
|
-
open && import_react10.default.createElement("div", { style: { paddingLeft: "20px" } }, props.children)
|
|
16148
|
-
);
|
|
16149
|
-
}
|
|
16120
|
+
var FILTER_TABS = [
|
|
16121
|
+
{ id: "all", label: "All" },
|
|
16122
|
+
...SEVERITY_ORDER.map((s) => ({ id: s, label: SEVERITY_LABELS[s] }))
|
|
16123
|
+
];
|
|
16150
16124
|
function FindingsView(props) {
|
|
16151
|
-
const { snapshot, command, sessionId } = props;
|
|
16152
|
-
const
|
|
16125
|
+
const { snapshot, command, sessionId, onNavigate } = props;
|
|
16126
|
+
const findings = snapshot?.findings ?? [];
|
|
16127
|
+
const [selectedId, setSelectedId] = (0, import_react10.useState)(null);
|
|
16153
16128
|
const [detailContent, setDetailContent] = (0, import_react10.useState)(null);
|
|
16154
16129
|
const [detailLoading, setDetailLoading] = (0, import_react10.useState)(false);
|
|
16155
|
-
const
|
|
16156
|
-
const
|
|
16157
|
-
|
|
16158
|
-
|
|
16159
|
-
|
|
16160
|
-
|
|
16161
|
-
|
|
16162
|
-
|
|
16163
|
-
|
|
16164
|
-
}
|
|
16165
|
-
return groups;
|
|
16130
|
+
const [detailError, setDetailError] = (0, import_react10.useState)(false);
|
|
16131
|
+
const [filter, setFilter] = (0, import_react10.useState)("all");
|
|
16132
|
+
const [search, setSearch] = (0, import_react10.useState)("");
|
|
16133
|
+
const [focusDone, setFocusDone] = (0, import_react10.useState)(false);
|
|
16134
|
+
const loadSeqRef = (0, import_react10.useRef)(0);
|
|
16135
|
+
const severityCounts = (0, import_react10.useMemo)(() => {
|
|
16136
|
+
const counts = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };
|
|
16137
|
+
for (const f of findings) counts[f.severity]++;
|
|
16138
|
+
return counts;
|
|
16166
16139
|
}, [findings]);
|
|
16167
|
-
const
|
|
16168
|
-
|
|
16140
|
+
const filtered = (0, import_react10.useMemo)(() => {
|
|
16141
|
+
let list = [...findings];
|
|
16142
|
+
if (filter !== "all") list = list.filter((f) => f.severity === filter);
|
|
16143
|
+
if (search.trim() !== "") {
|
|
16144
|
+
const q = search.toLowerCase();
|
|
16145
|
+
list = list.filter(
|
|
16146
|
+
(f) => f.title.toLowerCase().includes(q) || (f.affectedAsset?.toLowerCase().includes(q) ?? false) || f.sourceStage.toLowerCase().includes(q) || f.sourceDelegationId.toLowerCase().includes(q)
|
|
16147
|
+
);
|
|
16148
|
+
}
|
|
16149
|
+
const orderMap = new Map(SEVERITY_ORDER.map((s, i) => [s, i]));
|
|
16150
|
+
list.sort((a, b) => {
|
|
16151
|
+
const oa = orderMap.get(a.severity) ?? 99;
|
|
16152
|
+
const ob = orderMap.get(b.severity) ?? 99;
|
|
16153
|
+
if (oa !== ob) return oa - ob;
|
|
16154
|
+
return 0;
|
|
16155
|
+
});
|
|
16156
|
+
return list;
|
|
16157
|
+
}, [findings, filter, search]);
|
|
16158
|
+
const selectedFinding = (0, import_react10.useMemo)(
|
|
16159
|
+
() => selectedId !== null ? findings.find((f) => f.id === selectedId) ?? null : null,
|
|
16160
|
+
[findings, selectedId]
|
|
16161
|
+
);
|
|
16162
|
+
(0, import_react10.useEffect)(() => {
|
|
16163
|
+
if (props.focusFinding !== void 0 && !focusDone) {
|
|
16164
|
+
const match = findings.find((f) => f.id === props.focusFinding);
|
|
16165
|
+
if (match !== void 0) {
|
|
16166
|
+
setSelectedId(match.id);
|
|
16167
|
+
setFilter("all");
|
|
16168
|
+
setSearch("");
|
|
16169
|
+
setFocusDone(true);
|
|
16170
|
+
}
|
|
16171
|
+
}
|
|
16172
|
+
}, [props.focusFinding, focusDone, findings]);
|
|
16173
|
+
(0, import_react10.useEffect)(() => {
|
|
16174
|
+
setFocusDone(false);
|
|
16175
|
+
}, [props.focusFinding]);
|
|
16176
|
+
const loadDetail = (0, import_react10.useCallback)(async (finding) => {
|
|
16177
|
+
setSelectedId(finding.id);
|
|
16169
16178
|
setDetailContent(null);
|
|
16170
16179
|
setDetailLoading(true);
|
|
16180
|
+
setDetailError(false);
|
|
16181
|
+
const seq = ++loadSeqRef.current;
|
|
16171
16182
|
try {
|
|
16172
16183
|
const result = await command({
|
|
16173
16184
|
kind: "readFinding",
|
|
16174
16185
|
detailFile: finding.detailFile,
|
|
16175
16186
|
sessionId
|
|
16176
16187
|
});
|
|
16188
|
+
if (seq !== loadSeqRef.current) return;
|
|
16177
16189
|
if (result.ok) {
|
|
16178
16190
|
const fileResult = result.value;
|
|
16179
16191
|
setDetailContent(fileResult.content ?? "");
|
|
16192
|
+
setDetailError(false);
|
|
16180
16193
|
} else {
|
|
16181
|
-
setDetailContent(
|
|
16194
|
+
setDetailContent(null);
|
|
16195
|
+
setDetailError(true);
|
|
16182
16196
|
}
|
|
16183
16197
|
} catch {
|
|
16184
|
-
|
|
16198
|
+
if (seq !== loadSeqRef.current) return;
|
|
16199
|
+
setDetailContent(null);
|
|
16200
|
+
setDetailError(true);
|
|
16185
16201
|
} finally {
|
|
16186
|
-
setDetailLoading(false);
|
|
16202
|
+
if (seq === loadSeqRef.current) setDetailLoading(false);
|
|
16187
16203
|
}
|
|
16188
16204
|
}, [command, sessionId]);
|
|
16189
|
-
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
|
|
16193
|
-
|
|
16194
|
-
|
|
16195
|
-
|
|
16196
|
-
|
|
16197
|
-
|
|
16198
|
-
|
|
16199
|
-
|
|
16200
|
-
|
|
16201
|
-
|
|
16202
|
-
|
|
16205
|
+
return import_react10.default.createElement(
|
|
16206
|
+
"div",
|
|
16207
|
+
{
|
|
16208
|
+
style: {
|
|
16209
|
+
display: "flex",
|
|
16210
|
+
flexDirection: "column",
|
|
16211
|
+
height: "100%",
|
|
16212
|
+
minHeight: 0,
|
|
16213
|
+
overflow: "hidden"
|
|
16214
|
+
}
|
|
16215
|
+
},
|
|
16216
|
+
// ── Top: severity summary strip ──────────────────────────────────────
|
|
16217
|
+
import_react10.default.createElement(SeveritySummary, {
|
|
16218
|
+
total: findings.length,
|
|
16219
|
+
counts: severityCounts,
|
|
16220
|
+
activeFilter: filter,
|
|
16221
|
+
onFilter: setFilter
|
|
16222
|
+
}),
|
|
16223
|
+
// ── Bottom: split view ───────────────────────────────────────────────
|
|
16224
|
+
import_react10.default.createElement(
|
|
16225
|
+
"div",
|
|
16226
|
+
{
|
|
16227
|
+
style: {
|
|
16228
|
+
flex: 1,
|
|
16229
|
+
minHeight: 0,
|
|
16230
|
+
display: "flex",
|
|
16231
|
+
overflow: "hidden"
|
|
16232
|
+
}
|
|
16233
|
+
},
|
|
16234
|
+
// ── Left: Navigator ───────────────────────────────────────────────
|
|
16235
|
+
import_react10.default.createElement(
|
|
16236
|
+
"div",
|
|
16237
|
+
{
|
|
16238
|
+
style: {
|
|
16239
|
+
flex: "0 0 340px",
|
|
16240
|
+
minWidth: "280px",
|
|
16241
|
+
maxWidth: "380px",
|
|
16242
|
+
minHeight: 0,
|
|
16243
|
+
display: "flex",
|
|
16244
|
+
flexDirection: "column",
|
|
16245
|
+
overflow: "hidden",
|
|
16246
|
+
borderRight: "1px solid var(--dsw-alias-border-l2)"
|
|
16247
|
+
}
|
|
16248
|
+
},
|
|
16249
|
+
// Search + filter (fixed header)
|
|
16250
|
+
import_react10.default.createElement(
|
|
16251
|
+
"div",
|
|
16252
|
+
{
|
|
16253
|
+
style: {
|
|
16254
|
+
flex: "none",
|
|
16255
|
+
padding: "8px 12px 4px"
|
|
16256
|
+
}
|
|
16257
|
+
},
|
|
16258
|
+
import_react10.default.createElement("input", {
|
|
16259
|
+
type: "text",
|
|
16260
|
+
placeholder: "Search findings...",
|
|
16261
|
+
value: search,
|
|
16262
|
+
onChange: (e) => setSearch(e.target.value),
|
|
16263
|
+
style: {
|
|
16264
|
+
width: "100%",
|
|
16265
|
+
boxSizing: "border-box",
|
|
16266
|
+
padding: "6px 10px",
|
|
16267
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
16268
|
+
borderRadius: "6px",
|
|
16269
|
+
background: "var(--dsw-alias-bg-base)",
|
|
16270
|
+
color: "var(--dsw-alias-label-primary)",
|
|
16271
|
+
fontSize: "13px",
|
|
16272
|
+
outline: "none",
|
|
16273
|
+
marginBottom: "4px"
|
|
16274
|
+
}
|
|
16275
|
+
}),
|
|
16276
|
+
import_react10.default.createElement(PentesterTabBar, {
|
|
16277
|
+
items: FILTER_TABS,
|
|
16278
|
+
active: filter,
|
|
16279
|
+
onSelect: (id) => setFilter(id),
|
|
16280
|
+
variant: "compact"
|
|
16281
|
+
})
|
|
16282
|
+
),
|
|
16283
|
+
// FindingList (scrollable)
|
|
16284
|
+
import_react10.default.createElement(
|
|
16285
|
+
"div",
|
|
16286
|
+
{
|
|
16287
|
+
style: {
|
|
16288
|
+
flex: 1,
|
|
16289
|
+
minHeight: 0,
|
|
16290
|
+
overflowY: "auto",
|
|
16291
|
+
overflowX: "hidden",
|
|
16292
|
+
overscrollBehaviorY: "contain",
|
|
16293
|
+
scrollbarGutter: "stable"
|
|
16294
|
+
}
|
|
16295
|
+
},
|
|
16296
|
+
filtered.length === 0 ? import_react10.default.createElement("div", {
|
|
16297
|
+
style: {
|
|
16298
|
+
padding: "24px 12px",
|
|
16299
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
16300
|
+
fontSize: "13px",
|
|
16301
|
+
textAlign: "center"
|
|
16302
|
+
}
|
|
16303
|
+
}, findings.length === 0 ? "No findings yet" : "No matching findings") : filtered.map(
|
|
16304
|
+
(finding) => import_react10.default.createElement(FindingRow, {
|
|
16305
|
+
key: finding.id,
|
|
16306
|
+
finding,
|
|
16307
|
+
isSelected: finding.id === selectedId,
|
|
16308
|
+
onClick: () => loadDetail(finding)
|
|
16309
|
+
})
|
|
16310
|
+
)
|
|
16311
|
+
)
|
|
16312
|
+
),
|
|
16313
|
+
// ── Right: Detail ──────────────────────────────────────────────────
|
|
16314
|
+
import_react10.default.createElement(
|
|
16203
16315
|
"div",
|
|
16204
16316
|
{
|
|
16205
|
-
key: finding.id,
|
|
16206
16317
|
style: {
|
|
16318
|
+
flex: 1,
|
|
16319
|
+
minWidth: 0,
|
|
16320
|
+
minHeight: 0,
|
|
16207
16321
|
display: "flex",
|
|
16322
|
+
flexDirection: "column",
|
|
16323
|
+
overflow: "hidden"
|
|
16324
|
+
}
|
|
16325
|
+
},
|
|
16326
|
+
selectedFinding === null ? import_react10.default.createElement(
|
|
16327
|
+
"div",
|
|
16328
|
+
{
|
|
16329
|
+
style: {
|
|
16330
|
+
flex: 1,
|
|
16331
|
+
display: "flex",
|
|
16332
|
+
alignItems: "center",
|
|
16333
|
+
justifyContent: "center",
|
|
16334
|
+
flexDirection: "column",
|
|
16335
|
+
gap: "8px",
|
|
16336
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
16337
|
+
fontSize: "13px"
|
|
16338
|
+
}
|
|
16339
|
+
},
|
|
16340
|
+
findings.length === 0 ? import_react10.default.createElement(
|
|
16341
|
+
import_react10.default.Fragment,
|
|
16342
|
+
null,
|
|
16343
|
+
import_react10.default.createElement("div", { style: { fontWeight: 500, color: "var(--dsw-alias-label-primary)" } }, "No findings yet"),
|
|
16344
|
+
import_react10.default.createElement("div", null, "Validated findings will appear here as the assessment progresses.")
|
|
16345
|
+
) : "Select a finding to inspect"
|
|
16346
|
+
) : import_react10.default.createElement(FindingDetail, {
|
|
16347
|
+
finding: selectedFinding,
|
|
16348
|
+
content: detailContent,
|
|
16349
|
+
loading: detailLoading,
|
|
16350
|
+
error: detailError,
|
|
16351
|
+
onNavigate
|
|
16352
|
+
})
|
|
16353
|
+
)
|
|
16354
|
+
)
|
|
16355
|
+
);
|
|
16356
|
+
}
|
|
16357
|
+
function SeveritySummary(props) {
|
|
16358
|
+
const { total, counts, activeFilter, onFilter } = props;
|
|
16359
|
+
const items = [
|
|
16360
|
+
{ key: "all", label: "Total", count: total },
|
|
16361
|
+
...SEVERITY_ORDER.map((s) => ({
|
|
16362
|
+
key: s,
|
|
16363
|
+
label: SEVERITY_LABELS[s],
|
|
16364
|
+
count: counts[s],
|
|
16365
|
+
color: SEVERITY_COLORS[s]
|
|
16366
|
+
}))
|
|
16367
|
+
];
|
|
16368
|
+
return import_react10.default.createElement(
|
|
16369
|
+
"div",
|
|
16370
|
+
{
|
|
16371
|
+
style: {
|
|
16372
|
+
flex: "none",
|
|
16373
|
+
display: "flex",
|
|
16374
|
+
alignItems: "center",
|
|
16375
|
+
gap: "4px",
|
|
16376
|
+
padding: "8px 12px",
|
|
16377
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
16378
|
+
flexWrap: "wrap",
|
|
16379
|
+
fontSize: "13px",
|
|
16380
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
16381
|
+
}
|
|
16382
|
+
},
|
|
16383
|
+
...items.map((item) => {
|
|
16384
|
+
const isActive = activeFilter === item.key;
|
|
16385
|
+
return import_react10.default.createElement(
|
|
16386
|
+
"button",
|
|
16387
|
+
{
|
|
16388
|
+
key: item.key,
|
|
16389
|
+
type: "button",
|
|
16390
|
+
onClick: () => onFilter(item.key),
|
|
16391
|
+
style: {
|
|
16392
|
+
display: "inline-flex",
|
|
16208
16393
|
alignItems: "center",
|
|
16209
|
-
gap: "
|
|
16210
|
-
padding: "
|
|
16394
|
+
gap: "5px",
|
|
16395
|
+
padding: "3px 10px",
|
|
16396
|
+
borderRadius: "12px",
|
|
16397
|
+
border: "none",
|
|
16398
|
+
background: isActive ? "var(--dsw-alias-interactive-bg-hover)" : "transparent",
|
|
16399
|
+
color: isActive ? "var(--dsw-alias-label-primary)" : "var(--dsw-alias-label-secondary)",
|
|
16211
16400
|
cursor: "pointer",
|
|
16212
|
-
borderRadius: "4px",
|
|
16213
16401
|
fontSize: "13px",
|
|
16214
|
-
|
|
16215
|
-
|
|
16216
|
-
|
|
16217
|
-
},
|
|
16218
|
-
onClick: () => openDetail(finding)
|
|
16402
|
+
fontWeight: isActive ? 500 : 400,
|
|
16403
|
+
whiteSpace: "nowrap"
|
|
16404
|
+
}
|
|
16219
16405
|
},
|
|
16220
|
-
import_react10.default.createElement("span", {
|
|
16406
|
+
item.color !== void 0 && import_react10.default.createElement("span", {
|
|
16221
16407
|
style: {
|
|
16222
16408
|
width: "8px",
|
|
16223
16409
|
height: "8px",
|
|
16224
16410
|
borderRadius: "50%",
|
|
16225
|
-
background:
|
|
16411
|
+
background: item.color,
|
|
16226
16412
|
flexShrink: 0
|
|
16227
16413
|
}
|
|
16228
16414
|
}),
|
|
16229
|
-
import_react10.default.createElement("span",
|
|
16230
|
-
|
|
16231
|
-
style: {
|
|
16232
|
-
},
|
|
16233
|
-
)
|
|
16234
|
-
)
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16241
|
-
|
|
16242
|
-
const modalContent = selectedFinding !== null ? import_react10.default.createElement(
|
|
16243
|
-
import_dsh_client_ui_primitives3.Modal,
|
|
16415
|
+
import_react10.default.createElement("span", null, item.label),
|
|
16416
|
+
import_react10.default.createElement("span", {
|
|
16417
|
+
style: { fontWeight: 600, color: isActive ? "var(--dsw-alias-label-primary)" : "var(--dsw-alias-label-tertiary)" }
|
|
16418
|
+
}, String(item.count))
|
|
16419
|
+
);
|
|
16420
|
+
})
|
|
16421
|
+
);
|
|
16422
|
+
}
|
|
16423
|
+
function FindingRow(props) {
|
|
16424
|
+
const { finding, isSelected, onClick } = props;
|
|
16425
|
+
const color = SEVERITY_COLORS[finding.severity];
|
|
16426
|
+
return import_react10.default.createElement(
|
|
16427
|
+
"div",
|
|
16244
16428
|
{
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16429
|
+
role: "button",
|
|
16430
|
+
tabIndex: 0,
|
|
16431
|
+
onClick,
|
|
16432
|
+
onKeyDown: (e) => {
|
|
16433
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
16434
|
+
e.preventDefault();
|
|
16435
|
+
onClick();
|
|
16436
|
+
}
|
|
16437
|
+
},
|
|
16438
|
+
style: {
|
|
16439
|
+
display: "flex",
|
|
16440
|
+
flexDirection: "column",
|
|
16441
|
+
gap: "2px",
|
|
16442
|
+
padding: "8px 12px",
|
|
16443
|
+
cursor: "pointer",
|
|
16444
|
+
borderLeft: `3px solid ${isSelected ? color : "transparent"}`,
|
|
16445
|
+
background: isSelected ? "var(--dsw-alias-state-business-primary)" : "transparent",
|
|
16446
|
+
color: isSelected ? "var(--dsw-alias-state-business-primary-fg, #fff)" : "var(--dsw-alias-label-primary)",
|
|
16447
|
+
fontSize: "13px",
|
|
16448
|
+
lineHeight: "18px",
|
|
16449
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
16450
|
+
transition: "background 0.1s"
|
|
16451
|
+
},
|
|
16452
|
+
onMouseEnter: (e) => {
|
|
16453
|
+
if (!isSelected) e.currentTarget.style.background = "var(--dsw-alias-interactive-bg-hover)";
|
|
16454
|
+
},
|
|
16455
|
+
onMouseLeave: (e) => {
|
|
16456
|
+
if (!isSelected) e.currentTarget.style.background = "transparent";
|
|
16457
|
+
}
|
|
16249
16458
|
},
|
|
16459
|
+
// Row 1: title + severity
|
|
16250
16460
|
import_react10.default.createElement(
|
|
16251
16461
|
"div",
|
|
16252
|
-
{
|
|
16253
|
-
import_react10.default.createElement("div", {
|
|
16462
|
+
{
|
|
16254
16463
|
style: {
|
|
16255
|
-
display: "
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
|
|
16259
|
-
|
|
16260
|
-
|
|
16464
|
+
display: "flex",
|
|
16465
|
+
alignItems: "center",
|
|
16466
|
+
gap: "8px",
|
|
16467
|
+
minWidth: 0
|
|
16468
|
+
}
|
|
16469
|
+
},
|
|
16470
|
+
import_react10.default.createElement("span", {
|
|
16471
|
+
style: {
|
|
16472
|
+
width: "7px",
|
|
16473
|
+
height: "7px",
|
|
16474
|
+
borderRadius: "50%",
|
|
16475
|
+
background: color,
|
|
16476
|
+
flexShrink: 0
|
|
16477
|
+
}
|
|
16478
|
+
}),
|
|
16479
|
+
import_react10.default.createElement("span", {
|
|
16480
|
+
style: {
|
|
16481
|
+
overflow: "hidden",
|
|
16482
|
+
textOverflow: "ellipsis",
|
|
16483
|
+
whiteSpace: "nowrap",
|
|
16484
|
+
fontWeight: 500,
|
|
16485
|
+
flex: 1,
|
|
16486
|
+
minWidth: 0
|
|
16487
|
+
}
|
|
16488
|
+
}, finding.title),
|
|
16489
|
+
import_react10.default.createElement("span", {
|
|
16490
|
+
style: {
|
|
16491
|
+
fontSize: "11px",
|
|
16261
16492
|
fontWeight: 600,
|
|
16262
|
-
|
|
16493
|
+
color: isSelected ? "rgba(255,255,255,0.75)" : color,
|
|
16494
|
+
flexShrink: 0
|
|
16263
16495
|
}
|
|
16264
|
-
}, SEVERITY_LABELS[
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
|
|
16274
|
-
|
|
16275
|
-
|
|
16276
|
-
|
|
16496
|
+
}, SEVERITY_LABELS[finding.severity].toUpperCase())
|
|
16497
|
+
),
|
|
16498
|
+
// Row 2: affected asset (if exists)
|
|
16499
|
+
finding.affectedAsset !== void 0 && import_react10.default.createElement("div", {
|
|
16500
|
+
style: {
|
|
16501
|
+
fontSize: "12px",
|
|
16502
|
+
color: isSelected ? "rgba(255,255,255,0.6)" : "var(--dsw-alias-label-tertiary)",
|
|
16503
|
+
overflow: "hidden",
|
|
16504
|
+
textOverflow: "ellipsis",
|
|
16505
|
+
whiteSpace: "nowrap",
|
|
16506
|
+
marginLeft: "15px"
|
|
16507
|
+
}
|
|
16508
|
+
}, finding.affectedAsset),
|
|
16509
|
+
// Row 3: source stage + delegation
|
|
16510
|
+
import_react10.default.createElement("div", {
|
|
16511
|
+
style: {
|
|
16512
|
+
fontSize: "11px",
|
|
16513
|
+
color: isSelected ? "rgba(255,255,255,0.5)" : "var(--dsw-alias-label-tertiary)",
|
|
16514
|
+
marginLeft: "15px",
|
|
16515
|
+
overflow: "hidden",
|
|
16516
|
+
textOverflow: "ellipsis",
|
|
16517
|
+
whiteSpace: "nowrap"
|
|
16518
|
+
}
|
|
16519
|
+
}, `${finding.sourceStage} \xB7 ${finding.sourceDelegationId}`)
|
|
16520
|
+
);
|
|
16521
|
+
}
|
|
16522
|
+
function FindingDetail(props) {
|
|
16523
|
+
const { finding, content, loading, error: error51, onNavigate } = props;
|
|
16524
|
+
const color = SEVERITY_COLORS[finding.severity];
|
|
16277
16525
|
return import_react10.default.createElement(
|
|
16278
16526
|
"div",
|
|
16279
|
-
{
|
|
16280
|
-
|
|
16281
|
-
|
|
16527
|
+
{
|
|
16528
|
+
style: {
|
|
16529
|
+
flex: 1,
|
|
16530
|
+
minHeight: 0,
|
|
16531
|
+
display: "flex",
|
|
16532
|
+
flexDirection: "column",
|
|
16533
|
+
overflow: "hidden"
|
|
16534
|
+
}
|
|
16535
|
+
},
|
|
16536
|
+
// ── Metadata header (fixed) ─────────────────────────────────────────
|
|
16537
|
+
import_react10.default.createElement(
|
|
16538
|
+
"div",
|
|
16539
|
+
{
|
|
16540
|
+
style: {
|
|
16541
|
+
flex: "none",
|
|
16542
|
+
padding: "12px 16px",
|
|
16543
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
16544
|
+
}
|
|
16545
|
+
},
|
|
16546
|
+
// Title + severity
|
|
16547
|
+
import_react10.default.createElement(
|
|
16548
|
+
"div",
|
|
16549
|
+
{
|
|
16550
|
+
style: {
|
|
16551
|
+
display: "flex",
|
|
16552
|
+
alignItems: "center",
|
|
16553
|
+
gap: "10px",
|
|
16554
|
+
marginBottom: "8px"
|
|
16555
|
+
}
|
|
16556
|
+
},
|
|
16557
|
+
import_react10.default.createElement("span", {
|
|
16558
|
+
style: {
|
|
16559
|
+
fontSize: "15px",
|
|
16560
|
+
fontWeight: 600,
|
|
16561
|
+
color: "var(--dsw-alias-label-primary)",
|
|
16562
|
+
overflow: "hidden",
|
|
16563
|
+
textOverflow: "ellipsis",
|
|
16564
|
+
whiteSpace: "nowrap",
|
|
16565
|
+
flex: 1,
|
|
16566
|
+
minWidth: 0
|
|
16567
|
+
}
|
|
16568
|
+
}, finding.title),
|
|
16569
|
+
import_react10.default.createElement("span", {
|
|
16570
|
+
style: {
|
|
16571
|
+
display: "inline-block",
|
|
16572
|
+
padding: "2px 8px",
|
|
16573
|
+
borderRadius: "10px",
|
|
16574
|
+
background: color,
|
|
16575
|
+
color: "#fff",
|
|
16576
|
+
fontSize: "11px",
|
|
16577
|
+
fontWeight: 600,
|
|
16578
|
+
flexShrink: 0
|
|
16579
|
+
}
|
|
16580
|
+
}, SEVERITY_LABELS[finding.severity].toUpperCase())
|
|
16581
|
+
),
|
|
16582
|
+
// Affected asset
|
|
16583
|
+
finding.affectedAsset !== void 0 && import_react10.default.createElement(
|
|
16584
|
+
"div",
|
|
16585
|
+
{
|
|
16586
|
+
style: {
|
|
16587
|
+
fontSize: "13px",
|
|
16588
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
16589
|
+
marginBottom: "6px",
|
|
16590
|
+
display: "flex",
|
|
16591
|
+
gap: "6px"
|
|
16592
|
+
}
|
|
16593
|
+
},
|
|
16594
|
+
import_react10.default.createElement("span", { style: { color: "var(--dsw-alias-label-tertiary)", flexShrink: 0 } }, "Affected asset"),
|
|
16595
|
+
import_react10.default.createElement("code", {
|
|
16596
|
+
style: {
|
|
16597
|
+
fontSize: "12px",
|
|
16598
|
+
background: "var(--dsw-alias-bg-subtle)",
|
|
16599
|
+
padding: "1px 6px",
|
|
16600
|
+
borderRadius: "3px"
|
|
16601
|
+
}
|
|
16602
|
+
}, finding.affectedAsset)
|
|
16603
|
+
),
|
|
16604
|
+
// Stage + Delegation metadata
|
|
16605
|
+
import_react10.default.createElement(
|
|
16606
|
+
"div",
|
|
16607
|
+
{
|
|
16608
|
+
style: {
|
|
16609
|
+
display: "flex",
|
|
16610
|
+
gap: "20px",
|
|
16611
|
+
fontSize: "12px",
|
|
16612
|
+
color: "var(--dsw-alias-label-tertiary)"
|
|
16613
|
+
}
|
|
16614
|
+
},
|
|
16615
|
+
import_react10.default.createElement(
|
|
16616
|
+
"div",
|
|
16617
|
+
null,
|
|
16618
|
+
import_react10.default.createElement("span", { style: { fontWeight: 500, color: "var(--dsw-alias-label-secondary)" } }, "Stage"),
|
|
16619
|
+
" ",
|
|
16620
|
+
import_react10.default.createElement("span", null, finding.sourceStage)
|
|
16621
|
+
),
|
|
16622
|
+
import_react10.default.createElement(
|
|
16623
|
+
"div",
|
|
16624
|
+
null,
|
|
16625
|
+
import_react10.default.createElement("span", { style: { fontWeight: 500, color: "var(--dsw-alias-label-secondary)" } }, "Delegation"),
|
|
16626
|
+
" ",
|
|
16627
|
+
import_react10.default.createElement("span", null, finding.sourceDelegationId)
|
|
16628
|
+
)
|
|
16629
|
+
)
|
|
16630
|
+
),
|
|
16631
|
+
// ── DetailBody (scrollable) ────────────────────────────────────────
|
|
16632
|
+
import_react10.default.createElement(
|
|
16633
|
+
"div",
|
|
16634
|
+
{
|
|
16635
|
+
style: {
|
|
16636
|
+
flex: 1,
|
|
16637
|
+
minHeight: 0,
|
|
16638
|
+
overflowY: "auto",
|
|
16639
|
+
overflowX: "auto",
|
|
16640
|
+
overscrollBehaviorY: "contain",
|
|
16641
|
+
scrollbarGutter: "stable",
|
|
16642
|
+
padding: "16px",
|
|
16643
|
+
fontSize: "13px",
|
|
16644
|
+
lineHeight: "1.6",
|
|
16645
|
+
color: "var(--dsw-alias-label-primary)"
|
|
16646
|
+
}
|
|
16647
|
+
},
|
|
16648
|
+
loading && import_react10.default.createElement("div", {
|
|
16649
|
+
style: { color: "var(--dsw-alias-label-tertiary)", padding: "16px 0" }
|
|
16650
|
+
}, "Loading finding..."),
|
|
16651
|
+
error51 && import_react10.default.createElement("div", {
|
|
16652
|
+
style: { color: "var(--dsw-status-error)", padding: "16px 0" }
|
|
16653
|
+
}, "Unable to load finding detail"),
|
|
16654
|
+
content !== null && import_react10.default.createElement(import_dsh_client_ui_primitives3.MarkdownText, { text: content })
|
|
16655
|
+
),
|
|
16656
|
+
// ── Footer actions (fixed) ──────────────────────────────────────────
|
|
16657
|
+
import_react10.default.createElement(
|
|
16658
|
+
"div",
|
|
16659
|
+
{
|
|
16660
|
+
style: {
|
|
16661
|
+
flex: "none",
|
|
16662
|
+
padding: "8px 16px",
|
|
16663
|
+
borderTop: "1px solid var(--dsw-alias-border-l2)",
|
|
16664
|
+
display: "flex",
|
|
16665
|
+
gap: "8px"
|
|
16666
|
+
}
|
|
16667
|
+
},
|
|
16668
|
+
import_react10.default.createElement(ActionButton, {
|
|
16669
|
+
label: "View Stage",
|
|
16670
|
+
onClick: () => onNavigate("stages", { stage: finding.sourceStage })
|
|
16671
|
+
}),
|
|
16672
|
+
import_react10.default.createElement(ActionButton, {
|
|
16673
|
+
label: "View in Output",
|
|
16674
|
+
onClick: () => onNavigate("output", { output: `findings/${finding.detailFile}` })
|
|
16675
|
+
})
|
|
16676
|
+
)
|
|
16282
16677
|
);
|
|
16283
16678
|
}
|
|
16679
|
+
function ActionButton(props) {
|
|
16680
|
+
return import_react10.default.createElement("button", {
|
|
16681
|
+
type: "button",
|
|
16682
|
+
onClick: props.onClick,
|
|
16683
|
+
style: {
|
|
16684
|
+
padding: "4px 12px",
|
|
16685
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
16686
|
+
borderRadius: "4px",
|
|
16687
|
+
background: "transparent",
|
|
16688
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
16689
|
+
cursor: "pointer",
|
|
16690
|
+
fontSize: "12px",
|
|
16691
|
+
lineHeight: "20px"
|
|
16692
|
+
},
|
|
16693
|
+
onMouseEnter: (e) => {
|
|
16694
|
+
e.currentTarget.style.background = "var(--dsw-alias-interactive-bg-hover)";
|
|
16695
|
+
},
|
|
16696
|
+
onMouseLeave: (e) => {
|
|
16697
|
+
e.currentTarget.style.background = "transparent";
|
|
16698
|
+
}
|
|
16699
|
+
}, props.label);
|
|
16700
|
+
}
|
|
16284
16701
|
|
|
16285
16702
|
// src/ui/client/pentester/TraceView.tsx
|
|
16286
16703
|
var import_react15 = __toESM(require("react"), 1);
|
|
@@ -17767,7 +18184,7 @@ function TargetRow(props) {
|
|
|
17767
18184
|
);
|
|
17768
18185
|
}
|
|
17769
18186
|
function OutputView(props) {
|
|
17770
|
-
const { snapshot, command, sessionId } = props;
|
|
18187
|
+
const { snapshot, command, sessionId, focusOutput } = props;
|
|
17771
18188
|
const [filter, setFilter] = (0, import_react17.useState)("all");
|
|
17772
18189
|
const [preview, setPreview] = (0, import_react17.useState)(null);
|
|
17773
18190
|
const [previewContent, setPreviewContent] = (0, import_react17.useState)(null);
|
|
@@ -17849,6 +18266,16 @@ function OutputView(props) {
|
|
|
17849
18266
|
setPreview(null);
|
|
17850
18267
|
setPreviewContent(null);
|
|
17851
18268
|
}, []);
|
|
18269
|
+
const focusAppliedRef = (0, import_react17.useRef)(void 0);
|
|
18270
|
+
(0, import_react17.useEffect)(() => {
|
|
18271
|
+
if (focusOutput === void 0 || focusOutput === focusAppliedRef.current) return;
|
|
18272
|
+
if (outputTree === null) return;
|
|
18273
|
+
focusAppliedRef.current = focusOutput;
|
|
18274
|
+
const entry = findEntryByPath(outputTree.children, focusOutput);
|
|
18275
|
+
if (entry !== void 0) {
|
|
18276
|
+
openPreview(entry, outputTree.targetId);
|
|
18277
|
+
}
|
|
18278
|
+
}, [focusOutput, outputTree, openPreview]);
|
|
17852
18279
|
const initialLoading = outputTree === null && outputLoading;
|
|
17853
18280
|
if (initialLoading) {
|
|
17854
18281
|
return import_react17.default.createElement("div", {
|
|
@@ -17907,7 +18334,7 @@ function OutputView(props) {
|
|
|
17907
18334
|
return import_react17.default.createElement(
|
|
17908
18335
|
"div",
|
|
17909
18336
|
{
|
|
17910
|
-
style: { display: "flex", gap: "16px",
|
|
18337
|
+
style: { display: "flex", gap: "16px", flex: 1, height: "100%", minHeight: 0, minWidth: 0, overflow: "hidden" }
|
|
17911
18338
|
},
|
|
17912
18339
|
// Left: file tree
|
|
17913
18340
|
import_react17.default.createElement(
|
|
@@ -17915,16 +18342,24 @@ function OutputView(props) {
|
|
|
17915
18342
|
{
|
|
17916
18343
|
style: {
|
|
17917
18344
|
flex: "0 0 320px",
|
|
17918
|
-
|
|
17919
|
-
|
|
17920
|
-
paddingRight: "12px",
|
|
18345
|
+
minHeight: 0,
|
|
18346
|
+
overflow: "hidden",
|
|
17921
18347
|
display: "flex",
|
|
17922
|
-
flexDirection: "column"
|
|
18348
|
+
flexDirection: "column",
|
|
18349
|
+
borderRight: "1px solid var(--dsw-alias-border-l2)",
|
|
18350
|
+
paddingRight: "12px"
|
|
17923
18351
|
}
|
|
17924
18352
|
},
|
|
18353
|
+
// Filter tabs (fixed)
|
|
17925
18354
|
import_react17.default.createElement(
|
|
17926
18355
|
"div",
|
|
17927
|
-
{
|
|
18356
|
+
{
|
|
18357
|
+
style: {
|
|
18358
|
+
flex: "none",
|
|
18359
|
+
marginBottom: "12px",
|
|
18360
|
+
paddingTop: "2px"
|
|
18361
|
+
}
|
|
18362
|
+
},
|
|
17928
18363
|
import_react17.default.createElement(PentesterTabBar, {
|
|
17929
18364
|
items: OUTPUT_FILTER_TABS,
|
|
17930
18365
|
active: filter,
|
|
@@ -17932,10 +18367,20 @@ function OutputView(props) {
|
|
|
17932
18367
|
variant: "compact"
|
|
17933
18368
|
})
|
|
17934
18369
|
),
|
|
17935
|
-
// ──
|
|
18370
|
+
// ── TreeViewport (scrollable) ──────────────────────────────────
|
|
17936
18371
|
import_react17.default.createElement(
|
|
17937
18372
|
"div",
|
|
17938
|
-
{
|
|
18373
|
+
{
|
|
18374
|
+
style: {
|
|
18375
|
+
flex: 1,
|
|
18376
|
+
minHeight: 0,
|
|
18377
|
+
minWidth: 0,
|
|
18378
|
+
overflowY: "auto",
|
|
18379
|
+
overflowX: "hidden",
|
|
18380
|
+
overscrollBehaviorY: "contain",
|
|
18381
|
+
scrollbarGutter: "stable"
|
|
18382
|
+
}
|
|
18383
|
+
},
|
|
17939
18384
|
import_react17.default.createElement("div", {
|
|
17940
18385
|
style: {
|
|
17941
18386
|
fontSize: "11px",
|
|
@@ -17969,14 +18414,13 @@ function OutputView(props) {
|
|
|
17969
18414
|
style: {
|
|
17970
18415
|
flex: 1,
|
|
17971
18416
|
minWidth: 0,
|
|
18417
|
+
minHeight: 0,
|
|
17972
18418
|
display: "flex",
|
|
17973
18419
|
flexDirection: "column",
|
|
17974
18420
|
overflow: "hidden",
|
|
17975
18421
|
border: "1px solid var(--dsw-alias-border-l2)",
|
|
17976
18422
|
borderRadius: "8px",
|
|
17977
|
-
background: "var(--dsw-alias-bg-base)"
|
|
17978
|
-
minHeight: "320px",
|
|
17979
|
-
maxHeight: "clamp(320px, 65vh, 680px)"
|
|
18423
|
+
background: "var(--dsw-alias-bg-base)"
|
|
17980
18424
|
}
|
|
17981
18425
|
},
|
|
17982
18426
|
preview === null ? import_react17.default.createElement("div", {
|
|
@@ -17991,6 +18435,7 @@ function OutputView(props) {
|
|
|
17991
18435
|
}, "Select a file to preview") : import_react17.default.createElement(
|
|
17992
18436
|
import_react17.default.Fragment,
|
|
17993
18437
|
null,
|
|
18438
|
+
// PreviewHeader (fixed)
|
|
17994
18439
|
import_react17.default.createElement(
|
|
17995
18440
|
"div",
|
|
17996
18441
|
{
|
|
@@ -18019,10 +18464,20 @@ function OutputView(props) {
|
|
|
18019
18464
|
"aria-label": "Close preview"
|
|
18020
18465
|
}, "\xD7")
|
|
18021
18466
|
),
|
|
18467
|
+
// PreviewBody (scrollable)
|
|
18022
18468
|
import_react17.default.createElement(
|
|
18023
18469
|
"div",
|
|
18024
18470
|
{
|
|
18025
|
-
style: {
|
|
18471
|
+
style: {
|
|
18472
|
+
flex: 1,
|
|
18473
|
+
minHeight: 0,
|
|
18474
|
+
minWidth: 0,
|
|
18475
|
+
overflowY: "auto",
|
|
18476
|
+
overflowX: "auto",
|
|
18477
|
+
overscrollBehaviorY: "contain",
|
|
18478
|
+
scrollbarGutter: "stable",
|
|
18479
|
+
padding: "12px"
|
|
18480
|
+
}
|
|
18026
18481
|
},
|
|
18027
18482
|
previewLoading && import_react17.default.createElement("div", {
|
|
18028
18483
|
style: { color: "var(--dsw-alias-label-tertiary)", padding: "16px 0" }
|
|
@@ -18109,6 +18564,16 @@ function formatSize(bytes) {
|
|
|
18109
18564
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
18110
18565
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
18111
18566
|
}
|
|
18567
|
+
function findEntryByPath(entries, targetPath) {
|
|
18568
|
+
for (const entry of entries) {
|
|
18569
|
+
if (entry.path === targetPath) return entry;
|
|
18570
|
+
if (entry.kind === "directory" && entry.children !== void 0) {
|
|
18571
|
+
const found = findEntryByPath(entry.children, targetPath);
|
|
18572
|
+
if (found !== void 0) return found;
|
|
18573
|
+
}
|
|
18574
|
+
}
|
|
18575
|
+
return void 0;
|
|
18576
|
+
}
|
|
18112
18577
|
|
|
18113
18578
|
// src/ui/client/pentester-view.tsx
|
|
18114
18579
|
var CORE_REFRESH_MS = 1e4;
|
|
@@ -18411,12 +18876,14 @@ Client: ${mismatch.client}`,
|
|
|
18411
18876
|
{
|
|
18412
18877
|
"data-testid": "pentester-view",
|
|
18413
18878
|
"data-pentester-view": "",
|
|
18879
|
+
"data-conversation-composer-overlay": "",
|
|
18414
18880
|
style: {
|
|
18415
18881
|
display: "flex",
|
|
18416
18882
|
flexDirection: "column",
|
|
18417
18883
|
width: "100%",
|
|
18418
|
-
|
|
18419
|
-
|
|
18884
|
+
height: "100%",
|
|
18885
|
+
minHeight: 0,
|
|
18886
|
+
overflow: "hidden"
|
|
18420
18887
|
}
|
|
18421
18888
|
},
|
|
18422
18889
|
// ── Layer 1: TabsBar (sticky) ────────────────────────────────────────
|
|
@@ -18426,8 +18893,6 @@ Client: ${mismatch.client}`,
|
|
|
18426
18893
|
"data-testid": "pentester-tabs-bar",
|
|
18427
18894
|
style: {
|
|
18428
18895
|
flex: "none",
|
|
18429
|
-
position: "sticky",
|
|
18430
|
-
top: 0,
|
|
18431
18896
|
zIndex: 29,
|
|
18432
18897
|
background: "var(--dsw-alias-bg-base)",
|
|
18433
18898
|
borderBottom: "1px solid var(--dsw-alias-border-l2)",
|
|
@@ -18482,15 +18947,18 @@ Client: ${mismatch.client}`,
|
|
|
18482
18947
|
}
|
|
18483
18948
|
}, isRetrying ? "Retrying\u2026" : "Retry")
|
|
18484
18949
|
),
|
|
18485
|
-
// ── Body: flex
|
|
18950
|
+
// ── Body: bounded flex viewport ────────────────────────────────────
|
|
18486
18951
|
import_react18.default.createElement(
|
|
18487
18952
|
"div",
|
|
18488
18953
|
{
|
|
18489
18954
|
style: {
|
|
18490
18955
|
flex: 1,
|
|
18491
18956
|
minHeight: 0,
|
|
18492
|
-
overflow: "
|
|
18493
|
-
|
|
18957
|
+
overflow: "hidden",
|
|
18958
|
+
display: "flex",
|
|
18959
|
+
flexDirection: "column",
|
|
18960
|
+
padding: "16px",
|
|
18961
|
+
boxSizing: "border-box"
|
|
18494
18962
|
}
|
|
18495
18963
|
},
|
|
18496
18964
|
// Initial loading: shell is already visible, show skeleton
|
|
@@ -18597,23 +19065,40 @@ Client: ${mismatch.client}`,
|
|
|
18597
19065
|
}
|
|
18598
19066
|
}, "Refresh")
|
|
18599
19067
|
),
|
|
18600
|
-
// Bound content
|
|
19068
|
+
// Bound content — wrapped in a bounded viewport
|
|
18601
19069
|
dataState.kind === "bound" && import_react18.default.createElement(
|
|
18602
|
-
|
|
18603
|
-
|
|
18604
|
-
|
|
18605
|
-
|
|
18606
|
-
|
|
18607
|
-
|
|
18608
|
-
|
|
18609
|
-
|
|
18610
|
-
|
|
18611
|
-
|
|
18612
|
-
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
19070
|
+
"div",
|
|
19071
|
+
{
|
|
19072
|
+
style: {
|
|
19073
|
+
flex: 1,
|
|
19074
|
+
minHeight: 0,
|
|
19075
|
+
minWidth: 0,
|
|
19076
|
+
overflow: "hidden",
|
|
19077
|
+
display: "flex",
|
|
19078
|
+
flexDirection: "column"
|
|
19079
|
+
}
|
|
19080
|
+
},
|
|
19081
|
+
tab === "overview" && import_react18.default.createElement(
|
|
19082
|
+
ScrollablePage,
|
|
19083
|
+
null,
|
|
19084
|
+
import_react18.default.createElement(OverviewView, {
|
|
19085
|
+
snapshot,
|
|
19086
|
+
liveActivity,
|
|
19087
|
+
onNavigate: navigate,
|
|
19088
|
+
onOpenSession: openSession
|
|
19089
|
+
})
|
|
19090
|
+
),
|
|
19091
|
+
tab === "stages" && import_react18.default.createElement(
|
|
19092
|
+
ScrollablePage,
|
|
19093
|
+
null,
|
|
19094
|
+
import_react18.default.createElement(StagesView, {
|
|
19095
|
+
snapshot,
|
|
19096
|
+
liveActivity,
|
|
19097
|
+
onNavigate: navigate,
|
|
19098
|
+
onOpenSession: openSession,
|
|
19099
|
+
focusStage: navFocus.stage
|
|
19100
|
+
})
|
|
19101
|
+
),
|
|
18617
19102
|
tab === "findings" && import_react18.default.createElement(FindingsView, {
|
|
18618
19103
|
snapshot,
|
|
18619
19104
|
command: pentesterCommand,
|
|
@@ -18621,13 +19106,17 @@ Client: ${mismatch.client}`,
|
|
|
18621
19106
|
onNavigate: navigate,
|
|
18622
19107
|
focusFinding: navFocus.finding
|
|
18623
19108
|
}),
|
|
18624
|
-
tab === "trace" && import_react18.default.createElement(
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
19109
|
+
tab === "trace" && import_react18.default.createElement(
|
|
19110
|
+
ScrollablePage,
|
|
19111
|
+
null,
|
|
19112
|
+
import_react18.default.createElement(TraceView, {
|
|
19113
|
+
snapshot,
|
|
19114
|
+
liveActivity,
|
|
19115
|
+
onNavigate: navigate,
|
|
19116
|
+
onOpenSession: openSession,
|
|
19117
|
+
activeTargetId
|
|
19118
|
+
})
|
|
19119
|
+
),
|
|
18631
19120
|
tab === "output" && import_react18.default.createElement(OutputView, {
|
|
18632
19121
|
snapshot,
|
|
18633
19122
|
command: pentesterCommand,
|
|
@@ -18638,6 +19127,17 @@ Client: ${mismatch.client}`,
|
|
|
18638
19127
|
)
|
|
18639
19128
|
);
|
|
18640
19129
|
}
|
|
19130
|
+
function ScrollablePage(props) {
|
|
19131
|
+
return import_react18.default.createElement("div", {
|
|
19132
|
+
style: {
|
|
19133
|
+
flex: 1,
|
|
19134
|
+
minHeight: 0,
|
|
19135
|
+
overflowY: "auto",
|
|
19136
|
+
overflowX: "hidden",
|
|
19137
|
+
overscrollBehavior: "contain"
|
|
19138
|
+
}
|
|
19139
|
+
}, props.children);
|
|
19140
|
+
}
|
|
18641
19141
|
|
|
18642
19142
|
// src/ui/client/pentester/locales.ts
|
|
18643
19143
|
var NS = "dsh-pentester-view";
|
|
@@ -18719,7 +19219,7 @@ var en = {
|
|
|
18719
19219
|
};
|
|
18720
19220
|
|
|
18721
19221
|
// src/build-id.ts
|
|
18722
|
-
var BUILD_ID = "2.
|
|
19222
|
+
var BUILD_ID = "2.3.0+2a31301";
|
|
18723
19223
|
|
|
18724
19224
|
// src/ui/client/plugin.tsx
|
|
18725
19225
|
var SESSION_SWITCH_PERF = "[SESSION_SWITCH_PERF]";
|
|
@@ -18747,7 +19247,7 @@ function getRemoteMountError() {
|
|
|
18747
19247
|
}
|
|
18748
19248
|
var inject = ["slots", "remote", "sessions", "locale"];
|
|
18749
19249
|
function apply(ctx) {
|
|
18750
|
-
console.log(`[dsh-pentester]
|
|
19250
|
+
console.log(`[dsh-pentester/client] build=${BUILD_ID}`);
|
|
18751
19251
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "pentester: locale");
|
|
18752
19252
|
ctx.effect(() => {
|
|
18753
19253
|
let disposeMount;
|
|
@@ -18780,17 +19280,20 @@ function apply(ctx) {
|
|
|
18780
19280
|
if (result.ok && result.value !== null && typeof result.value === "object" && "ok" in result.value) {
|
|
18781
19281
|
const inner = result.value.value;
|
|
18782
19282
|
if (inner?.ready === true && typeof inner.buildId === "string") {
|
|
19283
|
+
console.log(`[dsh-pentester/client] health host=${inner.buildId} client=${BUILD_ID}`);
|
|
18783
19284
|
if (inner.buildId === BUILD_ID) {
|
|
19285
|
+
if (buildMismatch !== null) {
|
|
19286
|
+
console.log(`[dsh-pentester/client] build mismatch cleared (was host=${buildMismatch.host} client=${buildMismatch.client})`);
|
|
19287
|
+
}
|
|
18784
19288
|
buildMismatch = null;
|
|
18785
|
-
console.log(`[dsh-pentester] health check passed host=${inner.buildId} client=${BUILD_ID}`);
|
|
18786
19289
|
} else {
|
|
18787
19290
|
buildMismatch = { host: inner.buildId, client: BUILD_ID };
|
|
18788
|
-
console.error(`[dsh-pentester]
|
|
19291
|
+
console.error(`[dsh-pentester/client] build mismatch set host=${inner.buildId} client=${BUILD_ID}`);
|
|
18789
19292
|
}
|
|
18790
19293
|
}
|
|
18791
19294
|
}
|
|
18792
19295
|
} catch (error51) {
|
|
18793
|
-
console.warn("[dsh-pentester] build health check unavailable", error51);
|
|
19296
|
+
console.warn("[dsh-pentester/client] build health check unavailable", error51);
|
|
18794
19297
|
}
|
|
18795
19298
|
})();
|
|
18796
19299
|
}).catch((error51) => {
|