dsh-pentester 2.3.0 → 2.4.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/lib/build-id.json +1 -1
- package/lib/client.js +399 -312
- package/lib/client.js.map +4 -4
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -40,7 +40,7 @@ __export(plugin_exports, {
|
|
|
40
40
|
setPentesterEndpointState: () => setPentesterEndpointState
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(plugin_exports);
|
|
43
|
-
var
|
|
43
|
+
var import_react20 = __toESM(require("react"), 1);
|
|
44
44
|
|
|
45
45
|
// node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
46
46
|
var external_exports = {};
|
|
@@ -15397,7 +15397,7 @@ function isPentesterRootSession(snapshot, id) {
|
|
|
15397
15397
|
}
|
|
15398
15398
|
|
|
15399
15399
|
// src/ui/client/pentester-view.tsx
|
|
15400
|
-
var
|
|
15400
|
+
var import_react19 = __toESM(require("react"), 1);
|
|
15401
15401
|
|
|
15402
15402
|
// src/ui/client/pentester/navigation.ts
|
|
15403
15403
|
var PENTESTER_TABS = [
|
|
@@ -16100,8 +16100,71 @@ function LegendItem(props) {
|
|
|
16100
16100
|
}
|
|
16101
16101
|
|
|
16102
16102
|
// src/ui/client/pentester/FindingsView.tsx
|
|
16103
|
+
var import_react11 = __toESM(require("react"), 1);
|
|
16104
|
+
var import_dsh_client_ui_primitives4 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
16105
|
+
|
|
16106
|
+
// src/ui/client/pentester/CopyAction.tsx
|
|
16103
16107
|
var import_react10 = __toESM(require("react"), 1);
|
|
16104
16108
|
var import_dsh_client_ui_primitives3 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
16109
|
+
function CopyAction(props) {
|
|
16110
|
+
const { text } = props;
|
|
16111
|
+
const [copied, setCopied] = (0, import_react10.useState)(false);
|
|
16112
|
+
const timerRef = (0, import_react10.useRef)(null);
|
|
16113
|
+
const pendingRef = (0, import_react10.useRef)(false);
|
|
16114
|
+
const handleCopy = (0, import_react10.useCallback)(() => {
|
|
16115
|
+
if (copied || pendingRef.current) return;
|
|
16116
|
+
pendingRef.current = true;
|
|
16117
|
+
void (0, import_dsh_client_ui_primitives3.writeClipboard)(text).then((ok) => {
|
|
16118
|
+
pendingRef.current = false;
|
|
16119
|
+
if (!ok) return;
|
|
16120
|
+
setCopied(true);
|
|
16121
|
+
timerRef.current = setTimeout(() => {
|
|
16122
|
+
setCopied(false);
|
|
16123
|
+
timerRef.current = null;
|
|
16124
|
+
}, 1e3);
|
|
16125
|
+
});
|
|
16126
|
+
}, [text, copied]);
|
|
16127
|
+
(0, import_react10.useEffect)(() => {
|
|
16128
|
+
return () => {
|
|
16129
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
16130
|
+
};
|
|
16131
|
+
}, []);
|
|
16132
|
+
return import_react10.default.createElement(
|
|
16133
|
+
"button",
|
|
16134
|
+
{
|
|
16135
|
+
type: "button",
|
|
16136
|
+
onClick: handleCopy,
|
|
16137
|
+
"aria-label": copied ? "Copied" : "Copy",
|
|
16138
|
+
style: {
|
|
16139
|
+
display: "inline-flex",
|
|
16140
|
+
alignItems: "center",
|
|
16141
|
+
gap: "6px",
|
|
16142
|
+
padding: "4px 8px",
|
|
16143
|
+
border: "none",
|
|
16144
|
+
borderRadius: "6px",
|
|
16145
|
+
background: "transparent",
|
|
16146
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
16147
|
+
cursor: "pointer",
|
|
16148
|
+
fontSize: "13px",
|
|
16149
|
+
lineHeight: "16px",
|
|
16150
|
+
whiteSpace: "nowrap",
|
|
16151
|
+
flexShrink: 0
|
|
16152
|
+
},
|
|
16153
|
+
onMouseEnter: (e) => {
|
|
16154
|
+
e.currentTarget.style.background = "var(--dsw-alias-interactive-bg-hover)";
|
|
16155
|
+
e.currentTarget.style.color = "var(--dsw-alias-label-primary)";
|
|
16156
|
+
},
|
|
16157
|
+
onMouseLeave: (e) => {
|
|
16158
|
+
e.currentTarget.style.background = "transparent";
|
|
16159
|
+
e.currentTarget.style.color = "var(--dsw-alias-label-secondary)";
|
|
16160
|
+
}
|
|
16161
|
+
},
|
|
16162
|
+
copied ? import_react10.default.createElement(import_dsh_client_ui_primitives3.IconCheckOutline16, { size: 16 }) : import_react10.default.createElement(import_dsh_client_ui_primitives3.IconCopyOutline16, { size: 16 }),
|
|
16163
|
+
copied ? "Copied" : "Copy"
|
|
16164
|
+
);
|
|
16165
|
+
}
|
|
16166
|
+
|
|
16167
|
+
// src/ui/client/pentester/FindingsView.tsx
|
|
16105
16168
|
var SEVERITY_ORDER = ["critical", "high", "medium", "low", "info"];
|
|
16106
16169
|
var SEVERITY_LABELS = {
|
|
16107
16170
|
critical: "Critical",
|
|
@@ -16124,20 +16187,20 @@ var FILTER_TABS = [
|
|
|
16124
16187
|
function FindingsView(props) {
|
|
16125
16188
|
const { snapshot, command, sessionId, onNavigate } = props;
|
|
16126
16189
|
const findings = snapshot?.findings ?? [];
|
|
16127
|
-
const [selectedId, setSelectedId] = (0,
|
|
16128
|
-
const [detailContent, setDetailContent] = (0,
|
|
16129
|
-
const [detailLoading, setDetailLoading] = (0,
|
|
16130
|
-
const [detailError, setDetailError] = (0,
|
|
16131
|
-
const [filter, setFilter] = (0,
|
|
16132
|
-
const [search, setSearch] = (0,
|
|
16133
|
-
const [focusDone, setFocusDone] = (0,
|
|
16134
|
-
const loadSeqRef = (0,
|
|
16135
|
-
const severityCounts = (0,
|
|
16190
|
+
const [selectedId, setSelectedId] = (0, import_react11.useState)(null);
|
|
16191
|
+
const [detailContent, setDetailContent] = (0, import_react11.useState)(null);
|
|
16192
|
+
const [detailLoading, setDetailLoading] = (0, import_react11.useState)(false);
|
|
16193
|
+
const [detailError, setDetailError] = (0, import_react11.useState)(false);
|
|
16194
|
+
const [filter, setFilter] = (0, import_react11.useState)("all");
|
|
16195
|
+
const [search, setSearch] = (0, import_react11.useState)("");
|
|
16196
|
+
const [focusDone, setFocusDone] = (0, import_react11.useState)(false);
|
|
16197
|
+
const loadSeqRef = (0, import_react11.useRef)(0);
|
|
16198
|
+
const severityCounts = (0, import_react11.useMemo)(() => {
|
|
16136
16199
|
const counts = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };
|
|
16137
16200
|
for (const f of findings) counts[f.severity]++;
|
|
16138
16201
|
return counts;
|
|
16139
16202
|
}, [findings]);
|
|
16140
|
-
const filtered = (0,
|
|
16203
|
+
const filtered = (0, import_react11.useMemo)(() => {
|
|
16141
16204
|
let list = [...findings];
|
|
16142
16205
|
if (filter !== "all") list = list.filter((f) => f.severity === filter);
|
|
16143
16206
|
if (search.trim() !== "") {
|
|
@@ -16155,11 +16218,11 @@ function FindingsView(props) {
|
|
|
16155
16218
|
});
|
|
16156
16219
|
return list;
|
|
16157
16220
|
}, [findings, filter, search]);
|
|
16158
|
-
const selectedFinding = (0,
|
|
16221
|
+
const selectedFinding = (0, import_react11.useMemo)(
|
|
16159
16222
|
() => selectedId !== null ? findings.find((f) => f.id === selectedId) ?? null : null,
|
|
16160
16223
|
[findings, selectedId]
|
|
16161
16224
|
);
|
|
16162
|
-
(0,
|
|
16225
|
+
(0, import_react11.useEffect)(() => {
|
|
16163
16226
|
if (props.focusFinding !== void 0 && !focusDone) {
|
|
16164
16227
|
const match = findings.find((f) => f.id === props.focusFinding);
|
|
16165
16228
|
if (match !== void 0) {
|
|
@@ -16170,10 +16233,10 @@ function FindingsView(props) {
|
|
|
16170
16233
|
}
|
|
16171
16234
|
}
|
|
16172
16235
|
}, [props.focusFinding, focusDone, findings]);
|
|
16173
|
-
(0,
|
|
16236
|
+
(0, import_react11.useEffect)(() => {
|
|
16174
16237
|
setFocusDone(false);
|
|
16175
16238
|
}, [props.focusFinding]);
|
|
16176
|
-
const loadDetail = (0,
|
|
16239
|
+
const loadDetail = (0, import_react11.useCallback)(async (finding) => {
|
|
16177
16240
|
setSelectedId(finding.id);
|
|
16178
16241
|
setDetailContent(null);
|
|
16179
16242
|
setDetailLoading(true);
|
|
@@ -16202,7 +16265,7 @@ function FindingsView(props) {
|
|
|
16202
16265
|
if (seq === loadSeqRef.current) setDetailLoading(false);
|
|
16203
16266
|
}
|
|
16204
16267
|
}, [command, sessionId]);
|
|
16205
|
-
return
|
|
16268
|
+
return import_react11.default.createElement(
|
|
16206
16269
|
"div",
|
|
16207
16270
|
{
|
|
16208
16271
|
style: {
|
|
@@ -16214,14 +16277,14 @@ function FindingsView(props) {
|
|
|
16214
16277
|
}
|
|
16215
16278
|
},
|
|
16216
16279
|
// ── Top: severity summary strip ──────────────────────────────────────
|
|
16217
|
-
|
|
16280
|
+
import_react11.default.createElement(SeveritySummary, {
|
|
16218
16281
|
total: findings.length,
|
|
16219
16282
|
counts: severityCounts,
|
|
16220
16283
|
activeFilter: filter,
|
|
16221
16284
|
onFilter: setFilter
|
|
16222
16285
|
}),
|
|
16223
16286
|
// ── Bottom: split view ───────────────────────────────────────────────
|
|
16224
|
-
|
|
16287
|
+
import_react11.default.createElement(
|
|
16225
16288
|
"div",
|
|
16226
16289
|
{
|
|
16227
16290
|
style: {
|
|
@@ -16232,7 +16295,7 @@ function FindingsView(props) {
|
|
|
16232
16295
|
}
|
|
16233
16296
|
},
|
|
16234
16297
|
// ── Left: Navigator ───────────────────────────────────────────────
|
|
16235
|
-
|
|
16298
|
+
import_react11.default.createElement(
|
|
16236
16299
|
"div",
|
|
16237
16300
|
{
|
|
16238
16301
|
style: {
|
|
@@ -16247,7 +16310,7 @@ function FindingsView(props) {
|
|
|
16247
16310
|
}
|
|
16248
16311
|
},
|
|
16249
16312
|
// Search + filter (fixed header)
|
|
16250
|
-
|
|
16313
|
+
import_react11.default.createElement(
|
|
16251
16314
|
"div",
|
|
16252
16315
|
{
|
|
16253
16316
|
style: {
|
|
@@ -16255,7 +16318,7 @@ function FindingsView(props) {
|
|
|
16255
16318
|
padding: "8px 12px 4px"
|
|
16256
16319
|
}
|
|
16257
16320
|
},
|
|
16258
|
-
|
|
16321
|
+
import_react11.default.createElement("input", {
|
|
16259
16322
|
type: "text",
|
|
16260
16323
|
placeholder: "Search findings...",
|
|
16261
16324
|
value: search,
|
|
@@ -16273,7 +16336,7 @@ function FindingsView(props) {
|
|
|
16273
16336
|
marginBottom: "4px"
|
|
16274
16337
|
}
|
|
16275
16338
|
}),
|
|
16276
|
-
|
|
16339
|
+
import_react11.default.createElement(PentesterTabBar, {
|
|
16277
16340
|
items: FILTER_TABS,
|
|
16278
16341
|
active: filter,
|
|
16279
16342
|
onSelect: (id) => setFilter(id),
|
|
@@ -16281,7 +16344,7 @@ function FindingsView(props) {
|
|
|
16281
16344
|
})
|
|
16282
16345
|
),
|
|
16283
16346
|
// FindingList (scrollable)
|
|
16284
|
-
|
|
16347
|
+
import_react11.default.createElement(
|
|
16285
16348
|
"div",
|
|
16286
16349
|
{
|
|
16287
16350
|
style: {
|
|
@@ -16293,7 +16356,7 @@ function FindingsView(props) {
|
|
|
16293
16356
|
scrollbarGutter: "stable"
|
|
16294
16357
|
}
|
|
16295
16358
|
},
|
|
16296
|
-
filtered.length === 0 ?
|
|
16359
|
+
filtered.length === 0 ? import_react11.default.createElement("div", {
|
|
16297
16360
|
style: {
|
|
16298
16361
|
padding: "24px 12px",
|
|
16299
16362
|
color: "var(--dsw-alias-label-tertiary)",
|
|
@@ -16301,7 +16364,7 @@ function FindingsView(props) {
|
|
|
16301
16364
|
textAlign: "center"
|
|
16302
16365
|
}
|
|
16303
16366
|
}, findings.length === 0 ? "No findings yet" : "No matching findings") : filtered.map(
|
|
16304
|
-
(finding) =>
|
|
16367
|
+
(finding) => import_react11.default.createElement(FindingRow, {
|
|
16305
16368
|
key: finding.id,
|
|
16306
16369
|
finding,
|
|
16307
16370
|
isSelected: finding.id === selectedId,
|
|
@@ -16311,7 +16374,7 @@ function FindingsView(props) {
|
|
|
16311
16374
|
)
|
|
16312
16375
|
),
|
|
16313
16376
|
// ── Right: Detail ──────────────────────────────────────────────────
|
|
16314
|
-
|
|
16377
|
+
import_react11.default.createElement(
|
|
16315
16378
|
"div",
|
|
16316
16379
|
{
|
|
16317
16380
|
style: {
|
|
@@ -16323,7 +16386,7 @@ function FindingsView(props) {
|
|
|
16323
16386
|
overflow: "hidden"
|
|
16324
16387
|
}
|
|
16325
16388
|
},
|
|
16326
|
-
selectedFinding === null ?
|
|
16389
|
+
selectedFinding === null ? import_react11.default.createElement(
|
|
16327
16390
|
"div",
|
|
16328
16391
|
{
|
|
16329
16392
|
style: {
|
|
@@ -16337,13 +16400,13 @@ function FindingsView(props) {
|
|
|
16337
16400
|
fontSize: "13px"
|
|
16338
16401
|
}
|
|
16339
16402
|
},
|
|
16340
|
-
findings.length === 0 ?
|
|
16341
|
-
|
|
16403
|
+
findings.length === 0 ? import_react11.default.createElement(
|
|
16404
|
+
import_react11.default.Fragment,
|
|
16342
16405
|
null,
|
|
16343
|
-
|
|
16344
|
-
|
|
16406
|
+
import_react11.default.createElement("div", { style: { fontWeight: 500, color: "var(--dsw-alias-label-primary)" } }, "No findings yet"),
|
|
16407
|
+
import_react11.default.createElement("div", null, "Validated findings will appear here as the assessment progresses.")
|
|
16345
16408
|
) : "Select a finding to inspect"
|
|
16346
|
-
) :
|
|
16409
|
+
) : import_react11.default.createElement(FindingDetail, {
|
|
16347
16410
|
finding: selectedFinding,
|
|
16348
16411
|
content: detailContent,
|
|
16349
16412
|
loading: detailLoading,
|
|
@@ -16365,7 +16428,7 @@ function SeveritySummary(props) {
|
|
|
16365
16428
|
color: SEVERITY_COLORS[s]
|
|
16366
16429
|
}))
|
|
16367
16430
|
];
|
|
16368
|
-
return
|
|
16431
|
+
return import_react11.default.createElement(
|
|
16369
16432
|
"div",
|
|
16370
16433
|
{
|
|
16371
16434
|
style: {
|
|
@@ -16382,7 +16445,7 @@ function SeveritySummary(props) {
|
|
|
16382
16445
|
},
|
|
16383
16446
|
...items.map((item) => {
|
|
16384
16447
|
const isActive = activeFilter === item.key;
|
|
16385
|
-
return
|
|
16448
|
+
return import_react11.default.createElement(
|
|
16386
16449
|
"button",
|
|
16387
16450
|
{
|
|
16388
16451
|
key: item.key,
|
|
@@ -16403,7 +16466,7 @@ function SeveritySummary(props) {
|
|
|
16403
16466
|
whiteSpace: "nowrap"
|
|
16404
16467
|
}
|
|
16405
16468
|
},
|
|
16406
|
-
item.color !== void 0 &&
|
|
16469
|
+
item.color !== void 0 && import_react11.default.createElement("span", {
|
|
16407
16470
|
style: {
|
|
16408
16471
|
width: "8px",
|
|
16409
16472
|
height: "8px",
|
|
@@ -16412,8 +16475,8 @@ function SeveritySummary(props) {
|
|
|
16412
16475
|
flexShrink: 0
|
|
16413
16476
|
}
|
|
16414
16477
|
}),
|
|
16415
|
-
|
|
16416
|
-
|
|
16478
|
+
import_react11.default.createElement("span", null, item.label),
|
|
16479
|
+
import_react11.default.createElement("span", {
|
|
16417
16480
|
style: { fontWeight: 600, color: isActive ? "var(--dsw-alias-label-primary)" : "var(--dsw-alias-label-tertiary)" }
|
|
16418
16481
|
}, String(item.count))
|
|
16419
16482
|
);
|
|
@@ -16423,7 +16486,7 @@ function SeveritySummary(props) {
|
|
|
16423
16486
|
function FindingRow(props) {
|
|
16424
16487
|
const { finding, isSelected, onClick } = props;
|
|
16425
16488
|
const color = SEVERITY_COLORS[finding.severity];
|
|
16426
|
-
return
|
|
16489
|
+
return import_react11.default.createElement(
|
|
16427
16490
|
"div",
|
|
16428
16491
|
{
|
|
16429
16492
|
role: "button",
|
|
@@ -16457,7 +16520,7 @@ function FindingRow(props) {
|
|
|
16457
16520
|
}
|
|
16458
16521
|
},
|
|
16459
16522
|
// Row 1: title + severity
|
|
16460
|
-
|
|
16523
|
+
import_react11.default.createElement(
|
|
16461
16524
|
"div",
|
|
16462
16525
|
{
|
|
16463
16526
|
style: {
|
|
@@ -16467,7 +16530,7 @@ function FindingRow(props) {
|
|
|
16467
16530
|
minWidth: 0
|
|
16468
16531
|
}
|
|
16469
16532
|
},
|
|
16470
|
-
|
|
16533
|
+
import_react11.default.createElement("span", {
|
|
16471
16534
|
style: {
|
|
16472
16535
|
width: "7px",
|
|
16473
16536
|
height: "7px",
|
|
@@ -16476,7 +16539,7 @@ function FindingRow(props) {
|
|
|
16476
16539
|
flexShrink: 0
|
|
16477
16540
|
}
|
|
16478
16541
|
}),
|
|
16479
|
-
|
|
16542
|
+
import_react11.default.createElement("span", {
|
|
16480
16543
|
style: {
|
|
16481
16544
|
overflow: "hidden",
|
|
16482
16545
|
textOverflow: "ellipsis",
|
|
@@ -16486,7 +16549,7 @@ function FindingRow(props) {
|
|
|
16486
16549
|
minWidth: 0
|
|
16487
16550
|
}
|
|
16488
16551
|
}, finding.title),
|
|
16489
|
-
|
|
16552
|
+
import_react11.default.createElement("span", {
|
|
16490
16553
|
style: {
|
|
16491
16554
|
fontSize: "11px",
|
|
16492
16555
|
fontWeight: 600,
|
|
@@ -16496,7 +16559,7 @@ function FindingRow(props) {
|
|
|
16496
16559
|
}, SEVERITY_LABELS[finding.severity].toUpperCase())
|
|
16497
16560
|
),
|
|
16498
16561
|
// Row 2: affected asset (if exists)
|
|
16499
|
-
finding.affectedAsset !== void 0 &&
|
|
16562
|
+
finding.affectedAsset !== void 0 && import_react11.default.createElement("div", {
|
|
16500
16563
|
style: {
|
|
16501
16564
|
fontSize: "12px",
|
|
16502
16565
|
color: isSelected ? "rgba(255,255,255,0.6)" : "var(--dsw-alias-label-tertiary)",
|
|
@@ -16507,7 +16570,7 @@ function FindingRow(props) {
|
|
|
16507
16570
|
}
|
|
16508
16571
|
}, finding.affectedAsset),
|
|
16509
16572
|
// Row 3: source stage + delegation
|
|
16510
|
-
|
|
16573
|
+
import_react11.default.createElement("div", {
|
|
16511
16574
|
style: {
|
|
16512
16575
|
fontSize: "11px",
|
|
16513
16576
|
color: isSelected ? "rgba(255,255,255,0.5)" : "var(--dsw-alias-label-tertiary)",
|
|
@@ -16522,7 +16585,7 @@ function FindingRow(props) {
|
|
|
16522
16585
|
function FindingDetail(props) {
|
|
16523
16586
|
const { finding, content, loading, error: error51, onNavigate } = props;
|
|
16524
16587
|
const color = SEVERITY_COLORS[finding.severity];
|
|
16525
|
-
return
|
|
16588
|
+
return import_react11.default.createElement(
|
|
16526
16589
|
"div",
|
|
16527
16590
|
{
|
|
16528
16591
|
style: {
|
|
@@ -16534,7 +16597,7 @@ function FindingDetail(props) {
|
|
|
16534
16597
|
}
|
|
16535
16598
|
},
|
|
16536
16599
|
// ── Metadata header (fixed) ─────────────────────────────────────────
|
|
16537
|
-
|
|
16600
|
+
import_react11.default.createElement(
|
|
16538
16601
|
"div",
|
|
16539
16602
|
{
|
|
16540
16603
|
style: {
|
|
@@ -16543,8 +16606,8 @@ function FindingDetail(props) {
|
|
|
16543
16606
|
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
16544
16607
|
}
|
|
16545
16608
|
},
|
|
16546
|
-
// Title + severity
|
|
16547
|
-
|
|
16609
|
+
// Title + severity + copy
|
|
16610
|
+
import_react11.default.createElement(
|
|
16548
16611
|
"div",
|
|
16549
16612
|
{
|
|
16550
16613
|
style: {
|
|
@@ -16554,7 +16617,7 @@ function FindingDetail(props) {
|
|
|
16554
16617
|
marginBottom: "8px"
|
|
16555
16618
|
}
|
|
16556
16619
|
},
|
|
16557
|
-
|
|
16620
|
+
import_react11.default.createElement("span", {
|
|
16558
16621
|
style: {
|
|
16559
16622
|
fontSize: "15px",
|
|
16560
16623
|
fontWeight: 600,
|
|
@@ -16566,7 +16629,8 @@ function FindingDetail(props) {
|
|
|
16566
16629
|
minWidth: 0
|
|
16567
16630
|
}
|
|
16568
16631
|
}, finding.title),
|
|
16569
|
-
|
|
16632
|
+
content !== null && import_react11.default.createElement(CopyAction, { text: content }),
|
|
16633
|
+
import_react11.default.createElement("span", {
|
|
16570
16634
|
style: {
|
|
16571
16635
|
display: "inline-block",
|
|
16572
16636
|
padding: "2px 8px",
|
|
@@ -16580,7 +16644,7 @@ function FindingDetail(props) {
|
|
|
16580
16644
|
}, SEVERITY_LABELS[finding.severity].toUpperCase())
|
|
16581
16645
|
),
|
|
16582
16646
|
// Affected asset
|
|
16583
|
-
finding.affectedAsset !== void 0 &&
|
|
16647
|
+
finding.affectedAsset !== void 0 && import_react11.default.createElement(
|
|
16584
16648
|
"div",
|
|
16585
16649
|
{
|
|
16586
16650
|
style: {
|
|
@@ -16591,8 +16655,8 @@ function FindingDetail(props) {
|
|
|
16591
16655
|
gap: "6px"
|
|
16592
16656
|
}
|
|
16593
16657
|
},
|
|
16594
|
-
|
|
16595
|
-
|
|
16658
|
+
import_react11.default.createElement("span", { style: { color: "var(--dsw-alias-label-tertiary)", flexShrink: 0 } }, "Affected asset"),
|
|
16659
|
+
import_react11.default.createElement("code", {
|
|
16596
16660
|
style: {
|
|
16597
16661
|
fontSize: "12px",
|
|
16598
16662
|
background: "var(--dsw-alias-bg-subtle)",
|
|
@@ -16602,7 +16666,7 @@ function FindingDetail(props) {
|
|
|
16602
16666
|
}, finding.affectedAsset)
|
|
16603
16667
|
),
|
|
16604
16668
|
// Stage + Delegation metadata
|
|
16605
|
-
|
|
16669
|
+
import_react11.default.createElement(
|
|
16606
16670
|
"div",
|
|
16607
16671
|
{
|
|
16608
16672
|
style: {
|
|
@@ -16612,24 +16676,24 @@ function FindingDetail(props) {
|
|
|
16612
16676
|
color: "var(--dsw-alias-label-tertiary)"
|
|
16613
16677
|
}
|
|
16614
16678
|
},
|
|
16615
|
-
|
|
16679
|
+
import_react11.default.createElement(
|
|
16616
16680
|
"div",
|
|
16617
16681
|
null,
|
|
16618
|
-
|
|
16682
|
+
import_react11.default.createElement("span", { style: { fontWeight: 500, color: "var(--dsw-alias-label-secondary)" } }, "Stage"),
|
|
16619
16683
|
" ",
|
|
16620
|
-
|
|
16684
|
+
import_react11.default.createElement("span", null, finding.sourceStage)
|
|
16621
16685
|
),
|
|
16622
|
-
|
|
16686
|
+
import_react11.default.createElement(
|
|
16623
16687
|
"div",
|
|
16624
16688
|
null,
|
|
16625
|
-
|
|
16689
|
+
import_react11.default.createElement("span", { style: { fontWeight: 500, color: "var(--dsw-alias-label-secondary)" } }, "Delegation"),
|
|
16626
16690
|
" ",
|
|
16627
|
-
|
|
16691
|
+
import_react11.default.createElement("span", null, finding.sourceDelegationId)
|
|
16628
16692
|
)
|
|
16629
16693
|
)
|
|
16630
16694
|
),
|
|
16631
16695
|
// ── DetailBody (scrollable) ────────────────────────────────────────
|
|
16632
|
-
|
|
16696
|
+
import_react11.default.createElement(
|
|
16633
16697
|
"div",
|
|
16634
16698
|
{
|
|
16635
16699
|
style: {
|
|
@@ -16645,16 +16709,16 @@ function FindingDetail(props) {
|
|
|
16645
16709
|
color: "var(--dsw-alias-label-primary)"
|
|
16646
16710
|
}
|
|
16647
16711
|
},
|
|
16648
|
-
loading &&
|
|
16712
|
+
loading && import_react11.default.createElement("div", {
|
|
16649
16713
|
style: { color: "var(--dsw-alias-label-tertiary)", padding: "16px 0" }
|
|
16650
16714
|
}, "Loading finding..."),
|
|
16651
|
-
error51 &&
|
|
16715
|
+
error51 && import_react11.default.createElement("div", {
|
|
16652
16716
|
style: { color: "var(--dsw-status-error)", padding: "16px 0" }
|
|
16653
16717
|
}, "Unable to load finding detail"),
|
|
16654
|
-
content !== null &&
|
|
16718
|
+
content !== null && import_react11.default.createElement(import_dsh_client_ui_primitives4.MarkdownText, { text: content })
|
|
16655
16719
|
),
|
|
16656
16720
|
// ── Footer actions (fixed) ──────────────────────────────────────────
|
|
16657
|
-
|
|
16721
|
+
import_react11.default.createElement(
|
|
16658
16722
|
"div",
|
|
16659
16723
|
{
|
|
16660
16724
|
style: {
|
|
@@ -16665,11 +16729,11 @@ function FindingDetail(props) {
|
|
|
16665
16729
|
gap: "8px"
|
|
16666
16730
|
}
|
|
16667
16731
|
},
|
|
16668
|
-
|
|
16732
|
+
import_react11.default.createElement(ActionButton, {
|
|
16669
16733
|
label: "View Stage",
|
|
16670
16734
|
onClick: () => onNavigate("stages", { stage: finding.sourceStage })
|
|
16671
16735
|
}),
|
|
16672
|
-
|
|
16736
|
+
import_react11.default.createElement(ActionButton, {
|
|
16673
16737
|
label: "View in Output",
|
|
16674
16738
|
onClick: () => onNavigate("output", { output: `findings/${finding.detailFile}` })
|
|
16675
16739
|
})
|
|
@@ -16677,7 +16741,7 @@ function FindingDetail(props) {
|
|
|
16677
16741
|
);
|
|
16678
16742
|
}
|
|
16679
16743
|
function ActionButton(props) {
|
|
16680
|
-
return
|
|
16744
|
+
return import_react11.default.createElement("button", {
|
|
16681
16745
|
type: "button",
|
|
16682
16746
|
onClick: props.onClick,
|
|
16683
16747
|
style: {
|
|
@@ -16700,10 +16764,10 @@ function ActionButton(props) {
|
|
|
16700
16764
|
}
|
|
16701
16765
|
|
|
16702
16766
|
// src/ui/client/pentester/TraceView.tsx
|
|
16703
|
-
var
|
|
16767
|
+
var import_react16 = __toESM(require("react"), 1);
|
|
16704
16768
|
|
|
16705
16769
|
// src/ui/client/pentester/trace/TraceTimeline.tsx
|
|
16706
|
-
var
|
|
16770
|
+
var import_react15 = __toESM(require("react"), 1);
|
|
16707
16771
|
|
|
16708
16772
|
// src/ui/client/pentester/trace/types.ts
|
|
16709
16773
|
var STAGE_NODE_H = 72;
|
|
@@ -17107,8 +17171,8 @@ function buildScaledTraceLayout(baseLayout, scale) {
|
|
|
17107
17171
|
}
|
|
17108
17172
|
|
|
17109
17173
|
// src/ui/client/pentester/trace/TraceNode.tsx
|
|
17110
|
-
var
|
|
17111
|
-
var
|
|
17174
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
17175
|
+
var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
17112
17176
|
var CARD = {
|
|
17113
17177
|
position: "absolute",
|
|
17114
17178
|
borderRadius: "7px",
|
|
@@ -17121,10 +17185,10 @@ var CARD = {
|
|
|
17121
17185
|
cursor: "pointer",
|
|
17122
17186
|
pointerEvents: "auto"
|
|
17123
17187
|
};
|
|
17124
|
-
var StartNode = (0,
|
|
17188
|
+
var StartNode = (0, import_react12.forwardRef)(
|
|
17125
17189
|
function StartNode2(props, ref) {
|
|
17126
17190
|
const { section, x } = props;
|
|
17127
|
-
return
|
|
17191
|
+
return import_react12.default.createElement(
|
|
17128
17192
|
"div",
|
|
17129
17193
|
{
|
|
17130
17194
|
ref,
|
|
@@ -17152,7 +17216,7 @@ var StartNode = (0, import_react11.forwardRef)(
|
|
|
17152
17216
|
pointerEvents: "auto"
|
|
17153
17217
|
}
|
|
17154
17218
|
},
|
|
17155
|
-
|
|
17219
|
+
import_react12.default.createElement("div", {
|
|
17156
17220
|
style: {
|
|
17157
17221
|
width: "6px",
|
|
17158
17222
|
height: "6px",
|
|
@@ -17165,13 +17229,13 @@ var StartNode = (0, import_react11.forwardRef)(
|
|
|
17165
17229
|
);
|
|
17166
17230
|
}
|
|
17167
17231
|
);
|
|
17168
|
-
var StageNode = (0,
|
|
17232
|
+
var StageNode = (0, import_react12.forwardRef)(
|
|
17169
17233
|
function StageNode2(props, ref) {
|
|
17170
17234
|
const { section, x, onClick } = props;
|
|
17171
17235
|
const status = section.status;
|
|
17172
17236
|
const borderColor = status === "completed" ? "var(--dsw-status-done, #22c55e)" : status === "active" ? "var(--dsw-alias-state-business-primary)" : "var(--dsw-alias-border-l2)";
|
|
17173
17237
|
const dotState = status === "completed" ? "done" : status === "active" ? "ongoing" : "ongoing";
|
|
17174
|
-
return
|
|
17238
|
+
return import_react12.default.createElement(
|
|
17175
17239
|
"div",
|
|
17176
17240
|
{
|
|
17177
17241
|
ref,
|
|
@@ -17199,26 +17263,26 @@ var StageNode = (0, import_react11.forwardRef)(
|
|
|
17199
17263
|
gap: "10px"
|
|
17200
17264
|
}
|
|
17201
17265
|
},
|
|
17202
|
-
|
|
17203
|
-
|
|
17266
|
+
import_react12.default.createElement(import_dsh_client_ui_primitives5.StateDot, { state: dotState, size: 8 }),
|
|
17267
|
+
import_react12.default.createElement(
|
|
17204
17268
|
"div",
|
|
17205
17269
|
{ style: { minWidth: 0 } },
|
|
17206
|
-
|
|
17270
|
+
import_react12.default.createElement("div", {
|
|
17207
17271
|
style: { fontWeight: 600, color: "var(--dsw-alias-label-primary)", fontSize: "14px", lineHeight: "20px" }
|
|
17208
17272
|
}, section.label),
|
|
17209
|
-
|
|
17273
|
+
import_react12.default.createElement("div", {
|
|
17210
17274
|
style: { fontSize: "12px", color: "var(--dsw-alias-label-secondary)", marginTop: "2px" }
|
|
17211
17275
|
}, section.sublabel)
|
|
17212
17276
|
)
|
|
17213
17277
|
);
|
|
17214
17278
|
}
|
|
17215
17279
|
);
|
|
17216
|
-
var AgentNode = (0,
|
|
17280
|
+
var AgentNode = (0, import_react12.forwardRef)(
|
|
17217
17281
|
function AgentNode2(props, ref) {
|
|
17218
17282
|
const { branch, x, liveActivity, onClick } = props;
|
|
17219
17283
|
const dotState = branch.status === "failed" ? "error" : branch.status === "closed" ? "done" : liveActivity === "running" ? "ongoing" : liveActivity === "inactive" ? "done" : branch.status === "starting" ? "ongoing" : "done";
|
|
17220
17284
|
const borderColor = dotState === "error" ? "var(--dsw-status-error, #ef4444)" : dotState === "ongoing" ? "var(--dsw-alias-state-business-primary)" : "var(--dsw-alias-border-l2)";
|
|
17221
|
-
return
|
|
17285
|
+
return import_react12.default.createElement(
|
|
17222
17286
|
"div",
|
|
17223
17287
|
{
|
|
17224
17288
|
ref,
|
|
@@ -17246,14 +17310,14 @@ var AgentNode = (0, import_react11.forwardRef)(
|
|
|
17246
17310
|
gap: "8px"
|
|
17247
17311
|
}
|
|
17248
17312
|
},
|
|
17249
|
-
|
|
17250
|
-
|
|
17313
|
+
import_react12.default.createElement(import_dsh_client_ui_primitives5.StateDot, { state: dotState, size: 8 }),
|
|
17314
|
+
import_react12.default.createElement(
|
|
17251
17315
|
"div",
|
|
17252
17316
|
{ style: { minWidth: 0 } },
|
|
17253
|
-
|
|
17317
|
+
import_react12.default.createElement("div", {
|
|
17254
17318
|
style: { fontWeight: 600, color: "var(--dsw-alias-label-primary)", fontSize: "13px", lineHeight: "18px" }
|
|
17255
17319
|
}, branch.label),
|
|
17256
|
-
|
|
17320
|
+
import_react12.default.createElement("div", {
|
|
17257
17321
|
style: { fontSize: "11px", color: "var(--dsw-alias-label-tertiary)", marginTop: "2px" }
|
|
17258
17322
|
}, branch.status === "starting" ? "Agent starting" : branch.status === "active" ? "Agent active" : "Agent completed")
|
|
17259
17323
|
)
|
|
@@ -17268,11 +17332,11 @@ var DELIVERY_ICON_COLORS = {
|
|
|
17268
17332
|
finding: "var(--dsw-status-error, #ef4444)",
|
|
17269
17333
|
asset: "#3b82f6"
|
|
17270
17334
|
};
|
|
17271
|
-
var DeliveryNode = (0,
|
|
17335
|
+
var DeliveryNode = (0, import_react12.forwardRef)(
|
|
17272
17336
|
function DeliveryNode2(props, ref) {
|
|
17273
17337
|
const { group, x, y, onClick } = props;
|
|
17274
17338
|
const iconColor = DELIVERY_ICON_COLORS[group.kind] ?? "var(--dsw-alias-label-tertiary)";
|
|
17275
|
-
return
|
|
17339
|
+
return import_react12.default.createElement(
|
|
17276
17340
|
"div",
|
|
17277
17341
|
{
|
|
17278
17342
|
ref,
|
|
@@ -17304,7 +17368,7 @@ var DeliveryNode = (0, import_react11.forwardRef)(
|
|
|
17304
17368
|
textAlign: "center"
|
|
17305
17369
|
}
|
|
17306
17370
|
},
|
|
17307
|
-
|
|
17371
|
+
import_react12.default.createElement("div", {
|
|
17308
17372
|
style: {
|
|
17309
17373
|
width: "8px",
|
|
17310
17374
|
height: "8px",
|
|
@@ -17313,10 +17377,10 @@ var DeliveryNode = (0, import_react11.forwardRef)(
|
|
|
17313
17377
|
flexShrink: 0
|
|
17314
17378
|
}
|
|
17315
17379
|
}),
|
|
17316
|
-
|
|
17380
|
+
import_react12.default.createElement("div", {
|
|
17317
17381
|
style: { fontWeight: 600, color: "var(--dsw-alias-label-primary)", fontSize: "12px", lineHeight: "16px" }
|
|
17318
17382
|
}, group.label),
|
|
17319
|
-
|
|
17383
|
+
import_react12.default.createElement("div", {
|
|
17320
17384
|
style: { fontSize: "10px", color: "var(--dsw-alias-label-tertiary)" }
|
|
17321
17385
|
}, `${group.count} ${group.count === 1 ? "file" : "files"}`)
|
|
17322
17386
|
);
|
|
@@ -17324,7 +17388,7 @@ var DeliveryNode = (0, import_react11.forwardRef)(
|
|
|
17324
17388
|
);
|
|
17325
17389
|
|
|
17326
17390
|
// src/ui/client/pentester/trace/TraceConnectors.tsx
|
|
17327
|
-
var
|
|
17391
|
+
var import_react13 = __toESM(require("react"), 1);
|
|
17328
17392
|
function roundedOrthogonal(sx, sy, tx, ty, r = 6) {
|
|
17329
17393
|
if (Math.abs(sx - tx) < 2) {
|
|
17330
17394
|
return `M ${sx} ${sy} L ${tx} ${ty}`;
|
|
@@ -17349,7 +17413,7 @@ function branchJunction(cx, sy, targets) {
|
|
|
17349
17413
|
}
|
|
17350
17414
|
function TraceConnectors(props) {
|
|
17351
17415
|
const { layout } = props;
|
|
17352
|
-
const paths = (0,
|
|
17416
|
+
const paths = (0, import_react13.useMemo)(() => {
|
|
17353
17417
|
const result = [];
|
|
17354
17418
|
const cx = layout.spineX;
|
|
17355
17419
|
const solid = { stroke: "var(--dsw-alias-border-l2)", strokeWidth: 1.25 };
|
|
@@ -17430,7 +17494,7 @@ function TraceConnectors(props) {
|
|
|
17430
17494
|
}
|
|
17431
17495
|
return result;
|
|
17432
17496
|
}, [layout]);
|
|
17433
|
-
return
|
|
17497
|
+
return import_react13.default.createElement(
|
|
17434
17498
|
"svg",
|
|
17435
17499
|
{
|
|
17436
17500
|
width: layout.worldHalfWidth * 2,
|
|
@@ -17443,7 +17507,7 @@ function TraceConnectors(props) {
|
|
|
17443
17507
|
}
|
|
17444
17508
|
},
|
|
17445
17509
|
...paths.map(
|
|
17446
|
-
(p, i) =>
|
|
17510
|
+
(p, i) => import_react13.default.createElement("path", {
|
|
17447
17511
|
key: i,
|
|
17448
17512
|
d: p.d,
|
|
17449
17513
|
fill: "none",
|
|
@@ -17458,7 +17522,7 @@ function TraceConnectors(props) {
|
|
|
17458
17522
|
}
|
|
17459
17523
|
|
|
17460
17524
|
// src/ui/client/pentester/trace/TraceControls.tsx
|
|
17461
|
-
var
|
|
17525
|
+
var import_react14 = __toESM(require("react"), 1);
|
|
17462
17526
|
var BTN = {
|
|
17463
17527
|
height: "32px",
|
|
17464
17528
|
display: "flex",
|
|
@@ -17477,33 +17541,33 @@ var BTN = {
|
|
|
17477
17541
|
function TraceControls(props) {
|
|
17478
17542
|
const { scale, onZoomIn, onZoomOut, onReset, onFit } = props;
|
|
17479
17543
|
const pct = Math.round(scale * 100);
|
|
17480
|
-
return
|
|
17544
|
+
return import_react14.default.createElement(
|
|
17481
17545
|
"div",
|
|
17482
17546
|
{
|
|
17483
17547
|
style: { display: "flex", alignItems: "center", gap: "4px" }
|
|
17484
17548
|
},
|
|
17485
|
-
|
|
17549
|
+
import_react14.default.createElement("button", {
|
|
17486
17550
|
type: "button",
|
|
17487
17551
|
"aria-label": "Zoom out",
|
|
17488
17552
|
title: "Zoom out",
|
|
17489
17553
|
onClick: onZoomOut,
|
|
17490
17554
|
style: { ...BTN, width: "32px", padding: 0 }
|
|
17491
17555
|
}, "\u2212"),
|
|
17492
|
-
|
|
17556
|
+
import_react14.default.createElement("button", {
|
|
17493
17557
|
type: "button",
|
|
17494
17558
|
"aria-label": "Reset zoom",
|
|
17495
17559
|
title: "Reset to 100%",
|
|
17496
17560
|
onClick: onReset,
|
|
17497
17561
|
style: { ...BTN, fontWeight: 500, fontSize: "11px", color: "var(--dsw-alias-label-primary)" }
|
|
17498
17562
|
}, `${pct}%`),
|
|
17499
|
-
|
|
17563
|
+
import_react14.default.createElement("button", {
|
|
17500
17564
|
type: "button",
|
|
17501
17565
|
"aria-label": "Zoom in",
|
|
17502
17566
|
title: "Zoom in",
|
|
17503
17567
|
onClick: onZoomIn,
|
|
17504
17568
|
style: { ...BTN, width: "32px", padding: 0 }
|
|
17505
17569
|
}, "+"),
|
|
17506
|
-
|
|
17570
|
+
import_react14.default.createElement("button", {
|
|
17507
17571
|
type: "button",
|
|
17508
17572
|
"aria-label": "Fit to width",
|
|
17509
17573
|
title: "Fit topology width",
|
|
@@ -17532,12 +17596,12 @@ function checkSpineInvariant(graphEl, scale) {
|
|
|
17532
17596
|
}
|
|
17533
17597
|
function TraceTimeline(props) {
|
|
17534
17598
|
const { snapshot, liveActivity, onNavigate, onOpenSession } = props;
|
|
17535
|
-
const baseLayout = (0,
|
|
17536
|
-
const [scale, setScale] = (0,
|
|
17537
|
-
const graphRef = (0,
|
|
17538
|
-
const graphVpRef = (0,
|
|
17539
|
-
const autoFitDoneRef = (0,
|
|
17540
|
-
const scaledLayout = (0,
|
|
17599
|
+
const baseLayout = (0, import_react15.useMemo)(() => buildTraceLayout(snapshot), [snapshot]);
|
|
17600
|
+
const [scale, setScale] = (0, import_react15.useState)(DEFAULT_SCALE);
|
|
17601
|
+
const graphRef = (0, import_react15.useRef)(null);
|
|
17602
|
+
const graphVpRef = (0, import_react15.useRef)(null);
|
|
17603
|
+
const autoFitDoneRef = (0, import_react15.useRef)(false);
|
|
17604
|
+
const scaledLayout = (0, import_react15.useMemo)(
|
|
17541
17605
|
() => buildScaledTraceLayout(baseLayout, scale),
|
|
17542
17606
|
[baseLayout, scale]
|
|
17543
17607
|
);
|
|
@@ -17547,7 +17611,7 @@ function TraceTimeline(props) {
|
|
|
17547
17611
|
const spineX = scaledLayout.spineX;
|
|
17548
17612
|
const worldW = worldHalfWidth * 2;
|
|
17549
17613
|
const worldH = scaledLayout.totalHeight;
|
|
17550
|
-
const doAutoFit = (0,
|
|
17614
|
+
const doAutoFit = (0, import_react15.useCallback)(() => {
|
|
17551
17615
|
const vp = graphVpRef.current;
|
|
17552
17616
|
if (vp === null) return DEFAULT_SCALE;
|
|
17553
17617
|
const availableHalf = vp.clientWidth / 2 - GRAPH_PADDING;
|
|
@@ -17555,13 +17619,13 @@ function TraceTimeline(props) {
|
|
|
17555
17619
|
const fitScale = availableHalf / requiredHalf;
|
|
17556
17620
|
return Math.min(DEFAULT_SCALE, Math.max(MIN_SCALE, fitScale));
|
|
17557
17621
|
}, [baseLayout.worldHalfWidth]);
|
|
17558
|
-
(0,
|
|
17622
|
+
(0, import_react15.useEffect)(() => {
|
|
17559
17623
|
if (autoFitDoneRef.current) return;
|
|
17560
17624
|
const fitScale = doAutoFit();
|
|
17561
17625
|
if (fitScale !== DEFAULT_SCALE) setScale(fitScale);
|
|
17562
17626
|
autoFitDoneRef.current = true;
|
|
17563
17627
|
}, [doAutoFit]);
|
|
17564
|
-
const zoomTo = (0,
|
|
17628
|
+
const zoomTo = (0, import_react15.useCallback)((newScale) => {
|
|
17565
17629
|
const clamped = Math.min(MAX_SCALE, Math.max(MIN_SCALE, newScale));
|
|
17566
17630
|
const owner = getScrollOwner();
|
|
17567
17631
|
const oldScale = scale;
|
|
@@ -17574,26 +17638,26 @@ function TraceTimeline(props) {
|
|
|
17574
17638
|
owner.scrollTop = Math.max(0, nextScrollTop);
|
|
17575
17639
|
});
|
|
17576
17640
|
}, [scale]);
|
|
17577
|
-
const zoomIn = (0,
|
|
17578
|
-
const zoomOut = (0,
|
|
17579
|
-
const resetZoom = (0,
|
|
17580
|
-
const fitWidth = (0,
|
|
17581
|
-
const handleWheel = (0,
|
|
17641
|
+
const zoomIn = (0, import_react15.useCallback)(() => zoomTo(scale * 1.15), [zoomTo, scale]);
|
|
17642
|
+
const zoomOut = (0, import_react15.useCallback)(() => zoomTo(scale / 1.15), [zoomTo, scale]);
|
|
17643
|
+
const resetZoom = (0, import_react15.useCallback)(() => zoomTo(DEFAULT_SCALE), [zoomTo]);
|
|
17644
|
+
const fitWidth = (0, import_react15.useCallback)(() => zoomTo(doAutoFit()), [zoomTo, doAutoFit]);
|
|
17645
|
+
const handleWheel = (0, import_react15.useCallback)((e) => {
|
|
17582
17646
|
if (!e.ctrlKey && !e.metaKey) return;
|
|
17583
17647
|
e.preventDefault();
|
|
17584
17648
|
const factor = e.deltaY < 0 ? 1.12 : 1 / 1.12;
|
|
17585
17649
|
zoomTo(scale * factor);
|
|
17586
17650
|
}, [zoomTo, scale]);
|
|
17587
|
-
(0,
|
|
17651
|
+
(0, import_react15.useEffect)(() => {
|
|
17588
17652
|
checkSpineInvariant(graphRef.current, scale);
|
|
17589
17653
|
}, [scale, adjustedSections]);
|
|
17590
|
-
const handleStageClick = (0,
|
|
17654
|
+
const handleStageClick = (0, import_react15.useCallback)((stageId) => {
|
|
17591
17655
|
onNavigate("stages", { stage: stageId });
|
|
17592
17656
|
}, [onNavigate]);
|
|
17593
|
-
const handleAgentClick = (0,
|
|
17657
|
+
const handleAgentClick = (0, import_react15.useCallback)((sessionId) => {
|
|
17594
17658
|
if (sessionId !== void 0) onOpenSession(sessionId);
|
|
17595
17659
|
}, [onOpenSession]);
|
|
17596
|
-
const handleDeliveryClick = (0,
|
|
17660
|
+
const handleDeliveryClick = (0, import_react15.useCallback)((group) => {
|
|
17597
17661
|
if (group.navTab === "findings") {
|
|
17598
17662
|
onNavigate("findings", { finding: group.navPath });
|
|
17599
17663
|
} else {
|
|
@@ -17602,7 +17666,7 @@ function TraceTimeline(props) {
|
|
|
17602
17666
|
}, [onNavigate]);
|
|
17603
17667
|
const gridCols = `${TIME_PANEL_W}px minmax(0, 1fr)`;
|
|
17604
17668
|
const timelineEventGrid = `${TIMELINE_DOT_W}px ${TIMELINE_TIME_W}px minmax(0, 1fr)`;
|
|
17605
|
-
return
|
|
17669
|
+
return import_react15.default.createElement(
|
|
17606
17670
|
"div",
|
|
17607
17671
|
{
|
|
17608
17672
|
style: {
|
|
@@ -17615,7 +17679,7 @@ function TraceTimeline(props) {
|
|
|
17615
17679
|
}
|
|
17616
17680
|
},
|
|
17617
17681
|
// ── TraceHeader ─────────────────────────────────────────────────────────
|
|
17618
|
-
|
|
17682
|
+
import_react15.default.createElement(
|
|
17619
17683
|
"div",
|
|
17620
17684
|
{
|
|
17621
17685
|
"data-testid": "trace-header",
|
|
@@ -17627,16 +17691,16 @@ function TraceTimeline(props) {
|
|
|
17627
17691
|
background: "var(--dsw-alias-bg-base)"
|
|
17628
17692
|
}
|
|
17629
17693
|
},
|
|
17630
|
-
|
|
17694
|
+
import_react15.default.createElement(
|
|
17631
17695
|
"div",
|
|
17632
17696
|
{
|
|
17633
17697
|
style: { padding: "12px 18px", borderRight: "1px solid var(--dsw-alias-border-l1)" }
|
|
17634
17698
|
},
|
|
17635
|
-
|
|
17699
|
+
import_react15.default.createElement("div", {
|
|
17636
17700
|
style: { fontSize: "13px", fontWeight: 600, color: "var(--dsw-alias-label-primary)" }
|
|
17637
17701
|
}, "Timeline")
|
|
17638
17702
|
),
|
|
17639
|
-
|
|
17703
|
+
import_react15.default.createElement(
|
|
17640
17704
|
"div",
|
|
17641
17705
|
{
|
|
17642
17706
|
style: {
|
|
@@ -17646,10 +17710,10 @@ function TraceTimeline(props) {
|
|
|
17646
17710
|
justifyContent: "space-between"
|
|
17647
17711
|
}
|
|
17648
17712
|
},
|
|
17649
|
-
|
|
17713
|
+
import_react15.default.createElement("div", {
|
|
17650
17714
|
style: { fontSize: "13px", fontWeight: 600, color: "var(--dsw-alias-label-primary)" }
|
|
17651
17715
|
}, "Topology"),
|
|
17652
|
-
|
|
17716
|
+
import_react15.default.createElement(TraceControls, {
|
|
17653
17717
|
scale,
|
|
17654
17718
|
onZoomIn: zoomIn,
|
|
17655
17719
|
onZoomOut: zoomOut,
|
|
@@ -17659,7 +17723,7 @@ function TraceTimeline(props) {
|
|
|
17659
17723
|
)
|
|
17660
17724
|
),
|
|
17661
17725
|
// ── Content (no scroll — flows into Harness scroll owner) ───────────────
|
|
17662
|
-
|
|
17726
|
+
import_react15.default.createElement(
|
|
17663
17727
|
"div",
|
|
17664
17728
|
{
|
|
17665
17729
|
onWheel: handleWheel,
|
|
@@ -17669,7 +17733,7 @@ function TraceTimeline(props) {
|
|
|
17669
17733
|
}
|
|
17670
17734
|
},
|
|
17671
17735
|
// ── Timeline rail ────────────────────────────────────────────────────
|
|
17672
|
-
|
|
17736
|
+
import_react15.default.createElement(
|
|
17673
17737
|
"div",
|
|
17674
17738
|
{
|
|
17675
17739
|
style: {
|
|
@@ -17680,7 +17744,7 @@ function TraceTimeline(props) {
|
|
|
17680
17744
|
}
|
|
17681
17745
|
},
|
|
17682
17746
|
// Vertical timeline spine line
|
|
17683
|
-
|
|
17747
|
+
import_react15.default.createElement("div", {
|
|
17684
17748
|
"aria-hidden": true,
|
|
17685
17749
|
style: {
|
|
17686
17750
|
position: "absolute",
|
|
@@ -17695,7 +17759,7 @@ function TraceTimeline(props) {
|
|
|
17695
17759
|
...scaledBands.map((band) => {
|
|
17696
17760
|
const isStart = band.bandId === "band:start";
|
|
17697
17761
|
if (band.timelineItems.length === 0) return null;
|
|
17698
|
-
return
|
|
17762
|
+
return import_react15.default.createElement(
|
|
17699
17763
|
"div",
|
|
17700
17764
|
{
|
|
17701
17765
|
key: band.bandId,
|
|
@@ -17712,7 +17776,7 @@ function TraceTimeline(props) {
|
|
|
17712
17776
|
},
|
|
17713
17777
|
// Start band
|
|
17714
17778
|
isStart && band.timelineItems.map(
|
|
17715
|
-
(item, ii) =>
|
|
17779
|
+
(item, ii) => import_react15.default.createElement(
|
|
17716
17780
|
"div",
|
|
17717
17781
|
{
|
|
17718
17782
|
key: ii,
|
|
@@ -17724,12 +17788,12 @@ function TraceTimeline(props) {
|
|
|
17724
17788
|
minHeight: `${TIMELINE_ROW_H}px`
|
|
17725
17789
|
}
|
|
17726
17790
|
},
|
|
17727
|
-
|
|
17791
|
+
import_react15.default.createElement(
|
|
17728
17792
|
"div",
|
|
17729
17793
|
{
|
|
17730
17794
|
style: { display: "flex", justifyContent: "center", paddingTop: "4px" }
|
|
17731
17795
|
},
|
|
17732
|
-
|
|
17796
|
+
import_react15.default.createElement("div", {
|
|
17733
17797
|
style: {
|
|
17734
17798
|
width: "6px",
|
|
17735
17799
|
height: "6px",
|
|
@@ -17738,7 +17802,7 @@ function TraceTimeline(props) {
|
|
|
17738
17802
|
}
|
|
17739
17803
|
})
|
|
17740
17804
|
),
|
|
17741
|
-
|
|
17805
|
+
import_react15.default.createElement("span", {
|
|
17742
17806
|
style: {
|
|
17743
17807
|
fontSize: "11px",
|
|
17744
17808
|
fontFamily: "monospace",
|
|
@@ -17747,13 +17811,13 @@ function TraceTimeline(props) {
|
|
|
17747
17811
|
paddingTop: "2px"
|
|
17748
17812
|
}
|
|
17749
17813
|
}, item.timeLabel),
|
|
17750
|
-
|
|
17814
|
+
import_react15.default.createElement(
|
|
17751
17815
|
"div",
|
|
17752
17816
|
{ style: { minWidth: 0, paddingTop: "2px" } },
|
|
17753
|
-
|
|
17817
|
+
import_react15.default.createElement("div", {
|
|
17754
17818
|
style: { fontSize: "13px", fontWeight: 500, color: "var(--dsw-alias-label-primary)", lineHeight: "18px" }
|
|
17755
17819
|
}, item.title),
|
|
17756
|
-
item.subtitle !== "" &&
|
|
17820
|
+
item.subtitle !== "" && import_react15.default.createElement("div", {
|
|
17757
17821
|
style: { fontSize: "11px", color: "var(--dsw-alias-label-tertiary)", lineHeight: "16px" }
|
|
17758
17822
|
}, item.subtitle)
|
|
17759
17823
|
)
|
|
@@ -17761,7 +17825,7 @@ function TraceTimeline(props) {
|
|
|
17761
17825
|
),
|
|
17762
17826
|
// Regular stage/agent items
|
|
17763
17827
|
!isStart && band.timelineItems.map(
|
|
17764
|
-
(item, ii) =>
|
|
17828
|
+
(item, ii) => import_react15.default.createElement(
|
|
17765
17829
|
"div",
|
|
17766
17830
|
{
|
|
17767
17831
|
key: ii,
|
|
@@ -17773,12 +17837,12 @@ function TraceTimeline(props) {
|
|
|
17773
17837
|
minHeight: `${TIMELINE_ROW_H}px`
|
|
17774
17838
|
}
|
|
17775
17839
|
},
|
|
17776
|
-
|
|
17840
|
+
import_react15.default.createElement(
|
|
17777
17841
|
"div",
|
|
17778
17842
|
{
|
|
17779
17843
|
style: { display: "flex", justifyContent: "center", paddingTop: "4px" }
|
|
17780
17844
|
},
|
|
17781
|
-
|
|
17845
|
+
import_react15.default.createElement("div", {
|
|
17782
17846
|
style: {
|
|
17783
17847
|
width: "8px",
|
|
17784
17848
|
height: "8px",
|
|
@@ -17787,7 +17851,7 @@ function TraceTimeline(props) {
|
|
|
17787
17851
|
}
|
|
17788
17852
|
})
|
|
17789
17853
|
),
|
|
17790
|
-
|
|
17854
|
+
import_react15.default.createElement("span", {
|
|
17791
17855
|
style: {
|
|
17792
17856
|
fontSize: "11px",
|
|
17793
17857
|
fontFamily: "monospace",
|
|
@@ -17796,13 +17860,13 @@ function TraceTimeline(props) {
|
|
|
17796
17860
|
paddingTop: "2px"
|
|
17797
17861
|
}
|
|
17798
17862
|
}, item.timeLabel),
|
|
17799
|
-
|
|
17863
|
+
import_react15.default.createElement(
|
|
17800
17864
|
"div",
|
|
17801
17865
|
{ style: { minWidth: 0, paddingTop: "2px" } },
|
|
17802
|
-
|
|
17866
|
+
import_react15.default.createElement("div", {
|
|
17803
17867
|
style: { fontSize: "13px", fontWeight: 500, color: "var(--dsw-alias-label-primary)", lineHeight: "18px" }
|
|
17804
17868
|
}, item.title),
|
|
17805
|
-
item.subtitle !== "" &&
|
|
17869
|
+
item.subtitle !== "" && import_react15.default.createElement("div", {
|
|
17806
17870
|
style: { fontSize: "11px", color: "var(--dsw-alias-label-tertiary)", lineHeight: "16px" }
|
|
17807
17871
|
}, item.subtitle)
|
|
17808
17872
|
)
|
|
@@ -17812,7 +17876,7 @@ function TraceTimeline(props) {
|
|
|
17812
17876
|
})
|
|
17813
17877
|
),
|
|
17814
17878
|
// ── Graph viewport ────────────────────────────────────────────────────
|
|
17815
|
-
|
|
17879
|
+
import_react15.default.createElement(
|
|
17816
17880
|
"div",
|
|
17817
17881
|
{
|
|
17818
17882
|
ref: graphVpRef,
|
|
@@ -17824,7 +17888,7 @@ function TraceTimeline(props) {
|
|
|
17824
17888
|
}
|
|
17825
17889
|
},
|
|
17826
17890
|
// SpineAnchor: CSS left:50%, always at viewport center
|
|
17827
|
-
|
|
17891
|
+
import_react15.default.createElement(
|
|
17828
17892
|
"div",
|
|
17829
17893
|
{
|
|
17830
17894
|
style: {
|
|
@@ -17837,7 +17901,7 @@ function TraceTimeline(props) {
|
|
|
17837
17901
|
}
|
|
17838
17902
|
},
|
|
17839
17903
|
// TopologyWorld: symmetric around spine
|
|
17840
|
-
|
|
17904
|
+
import_react15.default.createElement(
|
|
17841
17905
|
"div",
|
|
17842
17906
|
{
|
|
17843
17907
|
ref: graphRef,
|
|
@@ -17851,24 +17915,24 @@ function TraceTimeline(props) {
|
|
|
17851
17915
|
transformOrigin: `${spineX}px 0px`
|
|
17852
17916
|
}
|
|
17853
17917
|
},
|
|
17854
|
-
|
|
17918
|
+
import_react15.default.createElement(TraceConnectors, {
|
|
17855
17919
|
layout: { ...baseLayout, sections: adjustedSections, worldHeight: worldH, spineX },
|
|
17856
17920
|
rects: /* @__PURE__ */ new Map()
|
|
17857
17921
|
}),
|
|
17858
|
-
|
|
17922
|
+
import_react15.default.createElement(
|
|
17859
17923
|
"div",
|
|
17860
17924
|
{
|
|
17861
17925
|
style: { position: "absolute", inset: 0, zIndex: 1 }
|
|
17862
17926
|
},
|
|
17863
17927
|
...adjustedSections.filter((s) => s.stageId === "start").map(
|
|
17864
|
-
(section) =>
|
|
17928
|
+
(section) => import_react15.default.createElement(StartNode, {
|
|
17865
17929
|
key: "stage:start",
|
|
17866
17930
|
section,
|
|
17867
17931
|
x: spineX
|
|
17868
17932
|
})
|
|
17869
17933
|
),
|
|
17870
17934
|
...adjustedSections.filter((s) => s.stageId !== "start").map(
|
|
17871
|
-
(section) =>
|
|
17935
|
+
(section) => import_react15.default.createElement(StageNode, {
|
|
17872
17936
|
key: `stage:${section.stageId}`,
|
|
17873
17937
|
section,
|
|
17874
17938
|
x: spineX,
|
|
@@ -17877,7 +17941,7 @@ function TraceTimeline(props) {
|
|
|
17877
17941
|
),
|
|
17878
17942
|
...adjustedSections.flatMap(
|
|
17879
17943
|
(section) => section.agentBranches.map(
|
|
17880
|
-
(branch) =>
|
|
17944
|
+
(branch) => import_react15.default.createElement(AgentNode, {
|
|
17881
17945
|
key: `agent:${branch.delegationId}`,
|
|
17882
17946
|
branch,
|
|
17883
17947
|
x: spineX + branch.x,
|
|
@@ -17892,7 +17956,7 @@ function TraceTimeline(props) {
|
|
|
17892
17956
|
(row3, ri) => row3.map((dx, gi) => {
|
|
17893
17957
|
const group = branch.deliveryGroups[ri * 3 + gi];
|
|
17894
17958
|
if (group === void 0) return null;
|
|
17895
|
-
return
|
|
17959
|
+
return import_react15.default.createElement(DeliveryNode, {
|
|
17896
17960
|
key: `delivery:${branch.delegationId}:${group.kind}`,
|
|
17897
17961
|
group,
|
|
17898
17962
|
x: spineX + dx,
|
|
@@ -17915,11 +17979,11 @@ function TraceTimeline(props) {
|
|
|
17915
17979
|
function TraceView(props) {
|
|
17916
17980
|
const { snapshot, liveActivity, onNavigate, onOpenSession, activeTargetId } = props;
|
|
17917
17981
|
if (snapshot === null || snapshot.run === null) {
|
|
17918
|
-
return
|
|
17982
|
+
return import_react16.default.createElement("div", {
|
|
17919
17983
|
style: { padding: "24px", color: "var(--dsw-alias-label-tertiary)", fontSize: "14px" }
|
|
17920
17984
|
}, "No execution trace yet");
|
|
17921
17985
|
}
|
|
17922
|
-
return
|
|
17986
|
+
return import_react16.default.createElement(TraceTimeline, {
|
|
17923
17987
|
snapshot,
|
|
17924
17988
|
liveActivity,
|
|
17925
17989
|
onNavigate,
|
|
@@ -17929,21 +17993,21 @@ function TraceView(props) {
|
|
|
17929
17993
|
}
|
|
17930
17994
|
|
|
17931
17995
|
// src/ui/client/pentester/OutputView.tsx
|
|
17932
|
-
var
|
|
17933
|
-
var
|
|
17996
|
+
var import_react18 = __toESM(require("react"), 1);
|
|
17997
|
+
var import_dsh_client_ui_primitives7 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
17934
17998
|
|
|
17935
17999
|
// src/ui/client/pentester/FolderTreeRow.tsx
|
|
17936
|
-
var
|
|
17937
|
-
var
|
|
18000
|
+
var import_react17 = __toESM(require("react"), 1);
|
|
18001
|
+
var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
17938
18002
|
function FolderTreeRow(props) {
|
|
17939
18003
|
const { name, depth, defaultOpen = true, children, containsSelected = false } = props;
|
|
17940
|
-
const [open, setOpen] = (0,
|
|
17941
|
-
const hasChildren = children !== void 0 &&
|
|
18004
|
+
const [open, setOpen] = (0, import_react17.useState)(defaultOpen);
|
|
18005
|
+
const hasChildren = children !== void 0 && import_react17.default.Children.count(children) > 0;
|
|
17942
18006
|
const folderColor = containsSelected ? "var(--dsw-alias-state-business-primary)" : "var(--dsw-alias-label-secondary)";
|
|
17943
|
-
return
|
|
18007
|
+
return import_react17.default.createElement(
|
|
17944
18008
|
"div",
|
|
17945
18009
|
null,
|
|
17946
|
-
|
|
18010
|
+
import_react17.default.createElement(
|
|
17947
18011
|
"div",
|
|
17948
18012
|
{
|
|
17949
18013
|
role: "button",
|
|
@@ -17979,19 +18043,19 @@ function FolderTreeRow(props) {
|
|
|
17979
18043
|
}
|
|
17980
18044
|
},
|
|
17981
18045
|
// Chevron
|
|
17982
|
-
hasChildren ?
|
|
18046
|
+
hasChildren ? import_react17.default.createElement(
|
|
17983
18047
|
"span",
|
|
17984
18048
|
{ style: { flexShrink: 0, color: "var(--dsw-alias-label-tertiary)" } },
|
|
17985
|
-
|
|
17986
|
-
) :
|
|
18049
|
+
import_react17.default.createElement(open ? import_dsh_client_ui_primitives6.IconChevronDownOutline14 : import_dsh_client_ui_primitives6.IconChevronRightOutline14, { size: 14 })
|
|
18050
|
+
) : import_react17.default.createElement("span", { style: { width: "14px", flexShrink: 0 } }),
|
|
17987
18051
|
// Folder icon — color reflects selected ancestry
|
|
17988
|
-
|
|
18052
|
+
import_react17.default.createElement(
|
|
17989
18053
|
"span",
|
|
17990
18054
|
{ style: { flexShrink: 0, color: folderColor } },
|
|
17991
|
-
|
|
18055
|
+
import_react17.default.createElement(open ? import_dsh_client_ui_primitives6.IconFolderOpen16 : import_dsh_client_ui_primitives6.IconFolderClose16, { size: 16 })
|
|
17992
18056
|
),
|
|
17993
18057
|
// Name
|
|
17994
|
-
|
|
18058
|
+
import_react17.default.createElement("span", {
|
|
17995
18059
|
style: {
|
|
17996
18060
|
overflow: "hidden",
|
|
17997
18061
|
textOverflow: "ellipsis",
|
|
@@ -17999,12 +18063,12 @@ function FolderTreeRow(props) {
|
|
|
17999
18063
|
}
|
|
18000
18064
|
}, name)
|
|
18001
18065
|
),
|
|
18002
|
-
open && hasChildren &&
|
|
18066
|
+
open && hasChildren && import_react17.default.createElement("div", null, children)
|
|
18003
18067
|
);
|
|
18004
18068
|
}
|
|
18005
18069
|
function FileRow(props) {
|
|
18006
18070
|
const { name, depth, size, isSelected = false, onClick } = props;
|
|
18007
|
-
return
|
|
18071
|
+
return import_react17.default.createElement(
|
|
18008
18072
|
"div",
|
|
18009
18073
|
{
|
|
18010
18074
|
role: "button",
|
|
@@ -18039,10 +18103,10 @@ function FileRow(props) {
|
|
|
18039
18103
|
}
|
|
18040
18104
|
},
|
|
18041
18105
|
// File icon placeholder (Harness doesn't have a specific file icon; use chevron space)
|
|
18042
|
-
|
|
18106
|
+
import_react17.default.createElement("span", {
|
|
18043
18107
|
style: { width: "14px", flexShrink: 0 }
|
|
18044
18108
|
}),
|
|
18045
|
-
|
|
18109
|
+
import_react17.default.createElement("span", {
|
|
18046
18110
|
style: {
|
|
18047
18111
|
overflow: "hidden",
|
|
18048
18112
|
textOverflow: "ellipsis",
|
|
@@ -18051,7 +18115,7 @@ function FileRow(props) {
|
|
|
18051
18115
|
minWidth: 0
|
|
18052
18116
|
}
|
|
18053
18117
|
}, name),
|
|
18054
|
-
size !== void 0 &&
|
|
18118
|
+
size !== void 0 && import_react17.default.createElement("span", {
|
|
18055
18119
|
style: {
|
|
18056
18120
|
fontSize: "11px",
|
|
18057
18121
|
color: "var(--dsw-alias-label-tertiary)",
|
|
@@ -18070,7 +18134,7 @@ var OUTPUT_FILTER_TABS = [
|
|
|
18070
18134
|
];
|
|
18071
18135
|
function TargetIcon(props) {
|
|
18072
18136
|
const s = props.size ?? 16;
|
|
18073
|
-
return
|
|
18137
|
+
return import_react18.default.createElement(
|
|
18074
18138
|
"svg",
|
|
18075
18139
|
{
|
|
18076
18140
|
width: s,
|
|
@@ -18084,13 +18148,13 @@ function TargetIcon(props) {
|
|
|
18084
18148
|
"aria-hidden": true,
|
|
18085
18149
|
style: { flexShrink: 0 }
|
|
18086
18150
|
},
|
|
18087
|
-
|
|
18088
|
-
|
|
18089
|
-
|
|
18090
|
-
|
|
18091
|
-
|
|
18092
|
-
|
|
18093
|
-
|
|
18151
|
+
import_react18.default.createElement("circle", { cx: "8", cy: "8", r: "6.5" }),
|
|
18152
|
+
import_react18.default.createElement("circle", { cx: "8", cy: "8", r: "3.5" }),
|
|
18153
|
+
import_react18.default.createElement("circle", { cx: "8", cy: "8", r: "1", fill: "currentColor", stroke: "none" }),
|
|
18154
|
+
import_react18.default.createElement("line", { x1: "8", y1: "1", x2: "8", y2: "3" }),
|
|
18155
|
+
import_react18.default.createElement("line", { x1: "8", y1: "13", x2: "8", y2: "15" }),
|
|
18156
|
+
import_react18.default.createElement("line", { x1: "1", y1: "8", x2: "3", y2: "8" }),
|
|
18157
|
+
import_react18.default.createElement("line", { x1: "13", y1: "8", x2: "15", y2: "8" })
|
|
18094
18158
|
);
|
|
18095
18159
|
}
|
|
18096
18160
|
function entryContainsSelected(entry, selectedPath) {
|
|
@@ -18101,12 +18165,12 @@ function entryContainsSelected(entry, selectedPath) {
|
|
|
18101
18165
|
}
|
|
18102
18166
|
function TargetRow(props) {
|
|
18103
18167
|
const { targetId, target, current, defaultOpen, containsSelected, children } = props;
|
|
18104
|
-
const [open, setOpen] = (0,
|
|
18168
|
+
const [open, setOpen] = (0, import_react18.useState)(defaultOpen);
|
|
18105
18169
|
const iconColor = containsSelected ? "var(--dsw-alias-state-business-primary)" : current ? "var(--dsw-alias-state-business-primary)" : "var(--dsw-alias-label-secondary)";
|
|
18106
|
-
return
|
|
18170
|
+
return import_react18.default.createElement(
|
|
18107
18171
|
"div",
|
|
18108
18172
|
null,
|
|
18109
|
-
|
|
18173
|
+
import_react18.default.createElement(
|
|
18110
18174
|
"div",
|
|
18111
18175
|
{
|
|
18112
18176
|
role: "button",
|
|
@@ -18142,7 +18206,7 @@ function TargetRow(props) {
|
|
|
18142
18206
|
e.currentTarget.style.background = "transparent";
|
|
18143
18207
|
}
|
|
18144
18208
|
},
|
|
18145
|
-
|
|
18209
|
+
import_react18.default.createElement("span", {
|
|
18146
18210
|
style: {
|
|
18147
18211
|
color: "var(--dsw-alias-label-tertiary)",
|
|
18148
18212
|
flexShrink: 0,
|
|
@@ -18152,22 +18216,22 @@ function TargetRow(props) {
|
|
|
18152
18216
|
width: "12px"
|
|
18153
18217
|
}
|
|
18154
18218
|
}, open ? "\u25BE" : "\u25B8"),
|
|
18155
|
-
|
|
18219
|
+
import_react18.default.createElement("span", {
|
|
18156
18220
|
style: {
|
|
18157
18221
|
color: iconColor,
|
|
18158
18222
|
flexShrink: 0,
|
|
18159
18223
|
display: "flex",
|
|
18160
18224
|
alignItems: "center"
|
|
18161
18225
|
}
|
|
18162
|
-
},
|
|
18163
|
-
|
|
18226
|
+
}, import_react18.default.createElement(TargetIcon, { size: 16 })),
|
|
18227
|
+
import_react18.default.createElement("span", {
|
|
18164
18228
|
style: {
|
|
18165
18229
|
overflow: "hidden",
|
|
18166
18230
|
textOverflow: "ellipsis",
|
|
18167
18231
|
whiteSpace: "nowrap"
|
|
18168
18232
|
}
|
|
18169
18233
|
}, target),
|
|
18170
|
-
current &&
|
|
18234
|
+
current && import_react18.default.createElement("span", {
|
|
18171
18235
|
style: {
|
|
18172
18236
|
fontSize: "10px",
|
|
18173
18237
|
color: "var(--dsw-alias-state-business-primary)",
|
|
@@ -18180,19 +18244,19 @@ function TargetRow(props) {
|
|
|
18180
18244
|
}
|
|
18181
18245
|
}, "active")
|
|
18182
18246
|
),
|
|
18183
|
-
open &&
|
|
18247
|
+
open && import_react18.default.createElement("div", { style: { marginLeft: "20px" } }, children)
|
|
18184
18248
|
);
|
|
18185
18249
|
}
|
|
18186
18250
|
function OutputView(props) {
|
|
18187
18251
|
const { snapshot, command, sessionId, focusOutput } = props;
|
|
18188
|
-
const [filter, setFilter] = (0,
|
|
18189
|
-
const [preview, setPreview] = (0,
|
|
18190
|
-
const [previewContent, setPreviewContent] = (0,
|
|
18191
|
-
const [previewLoading, setPreviewLoading] = (0,
|
|
18192
|
-
const [outputTree, setOutputTree] = (0,
|
|
18193
|
-
const [outputLoading, setOutputLoading] = (0,
|
|
18194
|
-
const [outputError, setOutputError] = (0,
|
|
18195
|
-
(0,
|
|
18252
|
+
const [filter, setFilter] = (0, import_react18.useState)("all");
|
|
18253
|
+
const [preview, setPreview] = (0, import_react18.useState)(null);
|
|
18254
|
+
const [previewContent, setPreviewContent] = (0, import_react18.useState)(null);
|
|
18255
|
+
const [previewLoading, setPreviewLoading] = (0, import_react18.useState)(false);
|
|
18256
|
+
const [outputTree, setOutputTree] = (0, import_react18.useState)(null);
|
|
18257
|
+
const [outputLoading, setOutputLoading] = (0, import_react18.useState)(false);
|
|
18258
|
+
const [outputError, setOutputError] = (0, import_react18.useState)(null);
|
|
18259
|
+
(0, import_react18.useEffect)(() => {
|
|
18196
18260
|
if (snapshot === null) return;
|
|
18197
18261
|
let cancelled = false;
|
|
18198
18262
|
setOutputLoading(true);
|
|
@@ -18218,7 +18282,7 @@ function OutputView(props) {
|
|
|
18218
18282
|
const targetTrees = outputTree !== null ? [outputTree] : [];
|
|
18219
18283
|
const selectedPath = preview?.entry.path ?? null;
|
|
18220
18284
|
const selectedTargetId = preview?.targetId ?? null;
|
|
18221
|
-
const filteredTargets = (0,
|
|
18285
|
+
const filteredTargets = (0, import_react18.useMemo)(() => {
|
|
18222
18286
|
const base = filter === "all" ? targetTrees : (() => {
|
|
18223
18287
|
const categoryMap = {
|
|
18224
18288
|
all: [],
|
|
@@ -18239,7 +18303,7 @@ function OutputView(props) {
|
|
|
18239
18303
|
)
|
|
18240
18304
|
}));
|
|
18241
18305
|
}, [targetTrees, filter, selectedPath, selectedTargetId]);
|
|
18242
|
-
const openPreview = (0,
|
|
18306
|
+
const openPreview = (0, import_react18.useCallback)(async (entry, targetId) => {
|
|
18243
18307
|
if (entry.kind === "directory") return;
|
|
18244
18308
|
setPreview({ entry, targetId });
|
|
18245
18309
|
setPreviewContent(null);
|
|
@@ -18262,12 +18326,12 @@ function OutputView(props) {
|
|
|
18262
18326
|
setPreviewLoading(false);
|
|
18263
18327
|
}
|
|
18264
18328
|
}, [command, sessionId]);
|
|
18265
|
-
const closePreview = (0,
|
|
18329
|
+
const closePreview = (0, import_react18.useCallback)(() => {
|
|
18266
18330
|
setPreview(null);
|
|
18267
18331
|
setPreviewContent(null);
|
|
18268
18332
|
}, []);
|
|
18269
|
-
const focusAppliedRef = (0,
|
|
18270
|
-
(0,
|
|
18333
|
+
const focusAppliedRef = (0, import_react18.useRef)(void 0);
|
|
18334
|
+
(0, import_react18.useEffect)(() => {
|
|
18271
18335
|
if (focusOutput === void 0 || focusOutput === focusAppliedRef.current) return;
|
|
18272
18336
|
if (outputTree === null) return;
|
|
18273
18337
|
focusAppliedRef.current = focusOutput;
|
|
@@ -18278,21 +18342,21 @@ function OutputView(props) {
|
|
|
18278
18342
|
}, [focusOutput, outputTree, openPreview]);
|
|
18279
18343
|
const initialLoading = outputTree === null && outputLoading;
|
|
18280
18344
|
if (initialLoading) {
|
|
18281
|
-
return
|
|
18345
|
+
return import_react18.default.createElement("div", {
|
|
18282
18346
|
style: { padding: "24px", color: "var(--dsw-alias-label-tertiary)", fontSize: "14px" }
|
|
18283
18347
|
}, "Loading output tree...");
|
|
18284
18348
|
}
|
|
18285
18349
|
if (outputError !== null) {
|
|
18286
|
-
return
|
|
18350
|
+
return import_react18.default.createElement(
|
|
18287
18351
|
"div",
|
|
18288
18352
|
{ style: { padding: "24px" } },
|
|
18289
|
-
|
|
18353
|
+
import_react18.default.createElement("div", {
|
|
18290
18354
|
style: { color: "var(--dsw-status-error)", marginBottom: "12px", fontSize: "14px" }
|
|
18291
18355
|
}, "Unable to load output tree"),
|
|
18292
|
-
|
|
18356
|
+
import_react18.default.createElement("div", {
|
|
18293
18357
|
style: { color: "var(--dsw-alias-label-tertiary)", fontSize: "12px", marginBottom: "12px" }
|
|
18294
18358
|
}, outputError),
|
|
18295
|
-
|
|
18359
|
+
import_react18.default.createElement("button", {
|
|
18296
18360
|
onClick: () => {
|
|
18297
18361
|
setOutputError(null);
|
|
18298
18362
|
setOutputTree(null);
|
|
@@ -18322,22 +18386,22 @@ function OutputView(props) {
|
|
|
18322
18386
|
);
|
|
18323
18387
|
}
|
|
18324
18388
|
if (snapshot === null) {
|
|
18325
|
-
return
|
|
18389
|
+
return import_react18.default.createElement("div", {
|
|
18326
18390
|
style: { padding: "24px", color: "var(--dsw-alias-label-tertiary)", fontSize: "14px" }
|
|
18327
18391
|
}, "No output data");
|
|
18328
18392
|
}
|
|
18329
18393
|
if (targetTrees.length === 0) {
|
|
18330
|
-
return
|
|
18394
|
+
return import_react18.default.createElement("div", {
|
|
18331
18395
|
style: { padding: "24px", color: "var(--dsw-alias-label-tertiary)", fontSize: "14px" }
|
|
18332
18396
|
}, "No output files");
|
|
18333
18397
|
}
|
|
18334
|
-
return
|
|
18398
|
+
return import_react18.default.createElement(
|
|
18335
18399
|
"div",
|
|
18336
18400
|
{
|
|
18337
18401
|
style: { display: "flex", gap: "16px", flex: 1, height: "100%", minHeight: 0, minWidth: 0, overflow: "hidden" }
|
|
18338
18402
|
},
|
|
18339
18403
|
// Left: file tree
|
|
18340
|
-
|
|
18404
|
+
import_react18.default.createElement(
|
|
18341
18405
|
"div",
|
|
18342
18406
|
{
|
|
18343
18407
|
style: {
|
|
@@ -18351,7 +18415,7 @@ function OutputView(props) {
|
|
|
18351
18415
|
}
|
|
18352
18416
|
},
|
|
18353
18417
|
// Filter tabs (fixed)
|
|
18354
|
-
|
|
18418
|
+
import_react18.default.createElement(
|
|
18355
18419
|
"div",
|
|
18356
18420
|
{
|
|
18357
18421
|
style: {
|
|
@@ -18360,7 +18424,7 @@ function OutputView(props) {
|
|
|
18360
18424
|
paddingTop: "2px"
|
|
18361
18425
|
}
|
|
18362
18426
|
},
|
|
18363
|
-
|
|
18427
|
+
import_react18.default.createElement(PentesterTabBar, {
|
|
18364
18428
|
items: OUTPUT_FILTER_TABS,
|
|
18365
18429
|
active: filter,
|
|
18366
18430
|
onSelect: (id) => setFilter(id),
|
|
@@ -18368,7 +18432,7 @@ function OutputView(props) {
|
|
|
18368
18432
|
})
|
|
18369
18433
|
),
|
|
18370
18434
|
// ── TreeViewport (scrollable) ──────────────────────────────────
|
|
18371
|
-
|
|
18435
|
+
import_react18.default.createElement(
|
|
18372
18436
|
"div",
|
|
18373
18437
|
{
|
|
18374
18438
|
style: {
|
|
@@ -18381,7 +18445,7 @@ function OutputView(props) {
|
|
|
18381
18445
|
scrollbarGutter: "stable"
|
|
18382
18446
|
}
|
|
18383
18447
|
},
|
|
18384
|
-
|
|
18448
|
+
import_react18.default.createElement("div", {
|
|
18385
18449
|
style: {
|
|
18386
18450
|
fontSize: "11px",
|
|
18387
18451
|
fontWeight: 600,
|
|
@@ -18393,7 +18457,7 @@ function OutputView(props) {
|
|
|
18393
18457
|
}
|
|
18394
18458
|
}, "Targets"),
|
|
18395
18459
|
...filteredTargets.map(
|
|
18396
|
-
(t) =>
|
|
18460
|
+
(t) => import_react18.default.createElement(TargetRow, {
|
|
18397
18461
|
key: t.targetId,
|
|
18398
18462
|
targetId: t.targetId,
|
|
18399
18463
|
target: t.target,
|
|
@@ -18408,7 +18472,7 @@ function OutputView(props) {
|
|
|
18408
18472
|
)
|
|
18409
18473
|
),
|
|
18410
18474
|
// Right: preview frame
|
|
18411
|
-
|
|
18475
|
+
import_react18.default.createElement(
|
|
18412
18476
|
"div",
|
|
18413
18477
|
{
|
|
18414
18478
|
style: {
|
|
@@ -18423,7 +18487,7 @@ function OutputView(props) {
|
|
|
18423
18487
|
background: "var(--dsw-alias-bg-base)"
|
|
18424
18488
|
}
|
|
18425
18489
|
},
|
|
18426
|
-
preview === null ?
|
|
18490
|
+
preview === null ? import_react18.default.createElement("div", {
|
|
18427
18491
|
style: {
|
|
18428
18492
|
flex: 1,
|
|
18429
18493
|
display: "flex",
|
|
@@ -18432,40 +18496,63 @@ function OutputView(props) {
|
|
|
18432
18496
|
color: "var(--dsw-alias-label-tertiary)",
|
|
18433
18497
|
fontSize: "13px"
|
|
18434
18498
|
}
|
|
18435
|
-
}, "Select a file to preview") :
|
|
18436
|
-
|
|
18499
|
+
}, "Select a file to preview") : import_react18.default.createElement(
|
|
18500
|
+
import_react18.default.Fragment,
|
|
18437
18501
|
null,
|
|
18438
18502
|
// PreviewHeader (fixed)
|
|
18439
|
-
|
|
18503
|
+
import_react18.default.createElement(
|
|
18440
18504
|
"div",
|
|
18441
18505
|
{
|
|
18442
18506
|
style: {
|
|
18443
18507
|
flex: "none",
|
|
18444
18508
|
display: "flex",
|
|
18445
18509
|
alignItems: "center",
|
|
18446
|
-
justifyContent: "space-between",
|
|
18447
18510
|
padding: "8px 12px",
|
|
18448
18511
|
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
18449
18512
|
}
|
|
18450
18513
|
},
|
|
18451
|
-
|
|
18452
|
-
|
|
18453
|
-
}, preview.entry.name),
|
|
18454
|
-
import_react17.default.createElement("button", {
|
|
18455
|
-
onClick: closePreview,
|
|
18514
|
+
// Filename
|
|
18515
|
+
import_react18.default.createElement("div", {
|
|
18456
18516
|
style: {
|
|
18457
|
-
|
|
18458
|
-
|
|
18459
|
-
|
|
18460
|
-
|
|
18461
|
-
|
|
18462
|
-
|
|
18517
|
+
flex: 1,
|
|
18518
|
+
minWidth: 0,
|
|
18519
|
+
fontSize: "13px",
|
|
18520
|
+
fontWeight: 600,
|
|
18521
|
+
color: "var(--dsw-alias-label-primary)",
|
|
18522
|
+
overflow: "hidden",
|
|
18523
|
+
textOverflow: "ellipsis",
|
|
18524
|
+
whiteSpace: "nowrap"
|
|
18525
|
+
}
|
|
18526
|
+
}, preview.entry.name),
|
|
18527
|
+
// Actions
|
|
18528
|
+
import_react18.default.createElement(
|
|
18529
|
+
"div",
|
|
18530
|
+
{
|
|
18531
|
+
style: {
|
|
18532
|
+
flex: "none",
|
|
18533
|
+
display: "flex",
|
|
18534
|
+
alignItems: "center",
|
|
18535
|
+
gap: "4px",
|
|
18536
|
+
marginLeft: "8px"
|
|
18537
|
+
}
|
|
18463
18538
|
},
|
|
18464
|
-
"
|
|
18465
|
-
|
|
18539
|
+
previewContent !== null && previewContent.content !== void 0 && previewContent.mime !== "binary" && import_react18.default.createElement(CopyAction, { text: previewContent.content }),
|
|
18540
|
+
import_react18.default.createElement("button", {
|
|
18541
|
+
onClick: closePreview,
|
|
18542
|
+
style: {
|
|
18543
|
+
background: "none",
|
|
18544
|
+
border: "none",
|
|
18545
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
18546
|
+
cursor: "pointer",
|
|
18547
|
+
fontSize: "18px",
|
|
18548
|
+
padding: "0 4px"
|
|
18549
|
+
},
|
|
18550
|
+
"aria-label": "Close preview"
|
|
18551
|
+
}, "\xD7")
|
|
18552
|
+
)
|
|
18466
18553
|
),
|
|
18467
18554
|
// PreviewBody (scrollable)
|
|
18468
|
-
|
|
18555
|
+
import_react18.default.createElement(
|
|
18469
18556
|
"div",
|
|
18470
18557
|
{
|
|
18471
18558
|
style: {
|
|
@@ -18479,7 +18566,7 @@ function OutputView(props) {
|
|
|
18479
18566
|
padding: "12px"
|
|
18480
18567
|
}
|
|
18481
18568
|
},
|
|
18482
|
-
previewLoading &&
|
|
18569
|
+
previewLoading && import_react18.default.createElement("div", {
|
|
18483
18570
|
style: { color: "var(--dsw-alias-label-tertiary)", padding: "16px 0" }
|
|
18484
18571
|
}, "Loading..."),
|
|
18485
18572
|
previewContent !== null && renderPreview(previewContent)
|
|
@@ -18492,7 +18579,7 @@ function renderOutputTree(entry, depth, targetId, onSelect, selected, selectedPa
|
|
|
18492
18579
|
if (entry.kind === "directory" && entry.children !== void 0 && entry.children.length > 0) {
|
|
18493
18580
|
const isSelectedTarget = selectedTargetId === targetId;
|
|
18494
18581
|
const containsSelected = isSelectedTarget && entryContainsSelected(entry, selectedPath);
|
|
18495
|
-
return
|
|
18582
|
+
return import_react18.default.createElement(FolderTreeRow, {
|
|
18496
18583
|
key: `${targetId}:${entry.path}`,
|
|
18497
18584
|
name: entry.name,
|
|
18498
18585
|
depth,
|
|
@@ -18504,7 +18591,7 @@ function renderOutputTree(entry, depth, targetId, onSelect, selected, selectedPa
|
|
|
18504
18591
|
});
|
|
18505
18592
|
}
|
|
18506
18593
|
const isSelected = selected?.entry.path === entry.path && selected?.targetId === targetId;
|
|
18507
|
-
return
|
|
18594
|
+
return import_react18.default.createElement(FileRow, {
|
|
18508
18595
|
key: `${targetId}:${entry.path}`,
|
|
18509
18596
|
name: entry.name,
|
|
18510
18597
|
depth,
|
|
@@ -18515,33 +18602,33 @@ function renderOutputTree(entry, depth, targetId, onSelect, selected, selectedPa
|
|
|
18515
18602
|
}
|
|
18516
18603
|
function renderPreview(result) {
|
|
18517
18604
|
if (result.mime === "binary") {
|
|
18518
|
-
return
|
|
18605
|
+
return import_react18.default.createElement(
|
|
18519
18606
|
"div",
|
|
18520
18607
|
{
|
|
18521
18608
|
style: { color: "var(--dsw-alias-label-tertiary)", fontSize: "13px", padding: "16px" }
|
|
18522
18609
|
},
|
|
18523
|
-
|
|
18524
|
-
|
|
18525
|
-
|
|
18610
|
+
import_react18.default.createElement("div", { style: { marginBottom: "8px" } }, "Preview unavailable"),
|
|
18611
|
+
import_react18.default.createElement("div", { style: { fontSize: "12px" } }, `Binary file \xB7 ${formatSize(result.size)}`),
|
|
18612
|
+
import_react18.default.createElement("div", { style: { fontSize: "12px" } }, result.path)
|
|
18526
18613
|
);
|
|
18527
18614
|
}
|
|
18528
18615
|
if (result.content === void 0) {
|
|
18529
|
-
return
|
|
18616
|
+
return import_react18.default.createElement("div", {
|
|
18530
18617
|
style: { color: "var(--dsw-alias-label-tertiary)", fontSize: "13px" }
|
|
18531
18618
|
}, "No content available");
|
|
18532
18619
|
}
|
|
18533
18620
|
if (result.mime === "markdown") {
|
|
18534
|
-
return
|
|
18621
|
+
return import_react18.default.createElement(import_dsh_client_ui_primitives7.MarkdownText, { text: result.content });
|
|
18535
18622
|
}
|
|
18536
18623
|
if (result.mime === "json") {
|
|
18537
18624
|
try {
|
|
18538
18625
|
const parsed = JSON.parse(result.content);
|
|
18539
|
-
return
|
|
18626
|
+
return import_react18.default.createElement(import_dsh_client_ui_primitives7.JsonTree, { data: parsed, label: result.name });
|
|
18540
18627
|
} catch {
|
|
18541
18628
|
}
|
|
18542
18629
|
}
|
|
18543
18630
|
const lines = result.content.split("\n");
|
|
18544
|
-
return
|
|
18631
|
+
return import_react18.default.createElement(import_dsh_client_ui_primitives7.ReadBlock, {
|
|
18545
18632
|
lines: lines.map((text, i) => ({ number: i + 1, text })),
|
|
18546
18633
|
totalLines: lines.length,
|
|
18547
18634
|
maxLines: 500
|
|
@@ -18616,13 +18703,13 @@ function resolveDelegationPresentationState(delegation, sessionList, rootSession
|
|
|
18616
18703
|
return "unknown";
|
|
18617
18704
|
}
|
|
18618
18705
|
function useDelegationActivity(sessions, rootSessionId, delegations) {
|
|
18619
|
-
const delegationSessionIds = (0,
|
|
18706
|
+
const delegationSessionIds = (0, import_react19.useMemo)(
|
|
18620
18707
|
() => new Set(delegations.filter((d) => d.sessionId !== void 0).map((d) => d.sessionId)),
|
|
18621
18708
|
[delegations]
|
|
18622
18709
|
);
|
|
18623
|
-
const prevSigRef = (0,
|
|
18624
|
-
const cachedMapRef = (0,
|
|
18625
|
-
const getSnapshot = (0,
|
|
18710
|
+
const prevSigRef = (0, import_react19.useRef)("");
|
|
18711
|
+
const cachedMapRef = (0, import_react19.useRef)(/* @__PURE__ */ new Map());
|
|
18712
|
+
const getSnapshot = (0, import_react19.useCallback)(() => {
|
|
18626
18713
|
const raw = sessions?.list.getSnapshot();
|
|
18627
18714
|
if (raw === void 0) return cachedMapRef.current;
|
|
18628
18715
|
const sig = computeActivitySignature(raw, rootSessionId, delegationSessionIds);
|
|
@@ -18636,7 +18723,7 @@ function useDelegationActivity(sessions, rootSessionId, delegations) {
|
|
|
18636
18723
|
cachedMapRef.current = map2;
|
|
18637
18724
|
return map2;
|
|
18638
18725
|
}, [sessions, rootSessionId, delegationSessionIds, delegations]);
|
|
18639
|
-
return (0,
|
|
18726
|
+
return (0, import_react19.useSyncExternalStore)(
|
|
18640
18727
|
sessions?.list.subscribe ?? (() => () => {
|
|
18641
18728
|
}),
|
|
18642
18729
|
getSnapshot
|
|
@@ -18648,7 +18735,7 @@ var RPC_PREFIX = "[PENTESTER_RPC]";
|
|
|
18648
18735
|
var isPerf = typeof window !== "undefined" && window.__DSH_PENTESTER_PERF === true;
|
|
18649
18736
|
function PentesterView(props) {
|
|
18650
18737
|
const { sessionId, reflect, sessions, useSession, sessionSwitchTimes: sessionSwitchTimes2, sessionPerf } = props;
|
|
18651
|
-
const mountTime = (0,
|
|
18738
|
+
const mountTime = (0, import_react19.useRef)(performance.now());
|
|
18652
18739
|
const switchTime = sessionSwitchTimes2?.get(sessionId);
|
|
18653
18740
|
if (isPerf) {
|
|
18654
18741
|
console.log(`${PERF_PREFIX} mount=0ms`);
|
|
@@ -18657,8 +18744,8 @@ function PentesterView(props) {
|
|
|
18657
18744
|
}
|
|
18658
18745
|
}
|
|
18659
18746
|
const openState = useSession?.((s) => s.openState);
|
|
18660
|
-
const prevOpenState = (0,
|
|
18661
|
-
(0,
|
|
18747
|
+
const prevOpenState = (0, import_react19.useRef)(void 0);
|
|
18748
|
+
(0, import_react19.useEffect)(() => {
|
|
18662
18749
|
if (!sessionPerf || openState === void 0) return;
|
|
18663
18750
|
if (openState !== prevOpenState.current) {
|
|
18664
18751
|
const elapsed = (performance.now() - mountTime.current).toFixed(0);
|
|
@@ -18684,27 +18771,27 @@ function PentesterView(props) {
|
|
|
18684
18771
|
prevOpenState.current = openState;
|
|
18685
18772
|
}
|
|
18686
18773
|
}, [openState, sessionPerf, switchTime]);
|
|
18687
|
-
const [tab, setTab] = (0,
|
|
18688
|
-
const [dataState, setDataState] = (0,
|
|
18689
|
-
const [requestState, setRequestState] = (0,
|
|
18690
|
-
const [navFocus, setNavFocus] = (0,
|
|
18691
|
-
const [activeTargetId, setActiveTargetId] = (0,
|
|
18692
|
-
const requestSeqRef = (0,
|
|
18693
|
-
const pendingRef = (0,
|
|
18694
|
-
const mountedRef = (0,
|
|
18695
|
-
const firstLoadDone = (0,
|
|
18696
|
-
const pollingPausedRef = (0,
|
|
18697
|
-
const backoffRef = (0,
|
|
18698
|
-
const timerRef = (0,
|
|
18699
|
-
const snapshotRef = (0,
|
|
18700
|
-
const pentesterCommand = (0,
|
|
18774
|
+
const [tab, setTab] = (0, import_react19.useState)("overview");
|
|
18775
|
+
const [dataState, setDataState] = (0, import_react19.useState)({ kind: "initial" });
|
|
18776
|
+
const [requestState, setRequestState] = (0, import_react19.useState)("idle");
|
|
18777
|
+
const [navFocus, setNavFocus] = (0, import_react19.useState)({});
|
|
18778
|
+
const [activeTargetId, setActiveTargetId] = (0, import_react19.useState)(null);
|
|
18779
|
+
const requestSeqRef = (0, import_react19.useRef)(0);
|
|
18780
|
+
const pendingRef = (0, import_react19.useRef)(null);
|
|
18781
|
+
const mountedRef = (0, import_react19.useRef)(true);
|
|
18782
|
+
const firstLoadDone = (0, import_react19.useRef)(false);
|
|
18783
|
+
const pollingPausedRef = (0, import_react19.useRef)(false);
|
|
18784
|
+
const backoffRef = (0, import_react19.useRef)(0);
|
|
18785
|
+
const timerRef = (0, import_react19.useRef)(null);
|
|
18786
|
+
const snapshotRef = (0, import_react19.useRef)(null);
|
|
18787
|
+
const pentesterCommand = (0, import_react19.useCallback)((input2, timeoutMs) => {
|
|
18701
18788
|
const currentFace = reflect?.get("remote.pentesterView");
|
|
18702
18789
|
return pentesterViewCommand(currentFace, input2, timeoutMs);
|
|
18703
18790
|
}, [reflect]);
|
|
18704
18791
|
const snapshot = dataState.kind === "bound" ? dataState.snapshot : null;
|
|
18705
18792
|
const delegations = snapshot?.delegations ?? [];
|
|
18706
18793
|
const liveActivity = useDelegationActivity(sessions, sessionId, delegations);
|
|
18707
|
-
const loadSnapshot = (0,
|
|
18794
|
+
const loadSnapshot = (0, import_react19.useCallback)(async (reason) => {
|
|
18708
18795
|
if (reason !== "retry" && reason !== "refresh" && getPentesterEndpointState() === "missing") {
|
|
18709
18796
|
if (isPerf) console.log(`${RPC_PREFIX} circuit-open endpoint=missing reason=${reason}`);
|
|
18710
18797
|
return;
|
|
@@ -18822,7 +18909,7 @@ Client: ${mismatch.client}`,
|
|
|
18822
18909
|
}
|
|
18823
18910
|
}
|
|
18824
18911
|
}, [pentesterCommand, sessionId, switchTime]);
|
|
18825
|
-
(0,
|
|
18912
|
+
(0, import_react19.useEffect)(() => {
|
|
18826
18913
|
mountedRef.current = true;
|
|
18827
18914
|
pollingPausedRef.current = false;
|
|
18828
18915
|
backoffRef.current = 0;
|
|
@@ -18850,7 +18937,7 @@ Client: ${mismatch.client}`,
|
|
|
18850
18937
|
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
18851
18938
|
};
|
|
18852
18939
|
}, [loadSnapshot]);
|
|
18853
|
-
(0,
|
|
18940
|
+
(0, import_react19.useEffect)(() => {
|
|
18854
18941
|
const onVisible = () => {
|
|
18855
18942
|
if (document.visibilityState === "visible" && mountedRef.current && firstLoadDone.current && !pollingPausedRef.current) {
|
|
18856
18943
|
loadSnapshot("visible");
|
|
@@ -18859,11 +18946,11 @@ Client: ${mismatch.client}`,
|
|
|
18859
18946
|
document.addEventListener("visibilitychange", onVisible);
|
|
18860
18947
|
return () => document.removeEventListener("visibilitychange", onVisible);
|
|
18861
18948
|
}, [loadSnapshot]);
|
|
18862
|
-
const navigate = (0,
|
|
18949
|
+
const navigate = (0, import_react19.useCallback)((targetTab, focus) => {
|
|
18863
18950
|
setTab(targetTab);
|
|
18864
18951
|
if (focus !== void 0) setNavFocus(focus);
|
|
18865
18952
|
}, []);
|
|
18866
|
-
const openSession = (0,
|
|
18953
|
+
const openSession = (0, import_react19.useCallback)((id) => {
|
|
18867
18954
|
sessions?.open(id);
|
|
18868
18955
|
}, [sessions]);
|
|
18869
18956
|
const isInitialLoading = dataState.kind === "initial" && requestState === "pending";
|
|
@@ -18871,7 +18958,7 @@ Client: ${mismatch.client}`,
|
|
|
18871
18958
|
const errorMsg = dataState.kind === "error" ? dataState.error : null;
|
|
18872
18959
|
const errorCode = dataState.kind === "error" ? dataState.code : null;
|
|
18873
18960
|
const hasSnapshot = snapshot !== null;
|
|
18874
|
-
return
|
|
18961
|
+
return import_react19.default.createElement(
|
|
18875
18962
|
"div",
|
|
18876
18963
|
{
|
|
18877
18964
|
"data-testid": "pentester-view",
|
|
@@ -18887,7 +18974,7 @@ Client: ${mismatch.client}`,
|
|
|
18887
18974
|
}
|
|
18888
18975
|
},
|
|
18889
18976
|
// ── Layer 1: TabsBar (sticky) ────────────────────────────────────────
|
|
18890
|
-
|
|
18977
|
+
import_react19.default.createElement(
|
|
18891
18978
|
"div",
|
|
18892
18979
|
{
|
|
18893
18980
|
"data-testid": "pentester-tabs-bar",
|
|
@@ -18901,7 +18988,7 @@ Client: ${mismatch.client}`,
|
|
|
18901
18988
|
boxSizing: "border-box"
|
|
18902
18989
|
}
|
|
18903
18990
|
},
|
|
18904
|
-
|
|
18991
|
+
import_react19.default.createElement(PentesterTabBar, {
|
|
18905
18992
|
items: PENTESTER_TABS.map((t) => ({
|
|
18906
18993
|
id: t.id,
|
|
18907
18994
|
label: t.id.charAt(0).toUpperCase() + t.id.slice(1)
|
|
@@ -18912,7 +18999,7 @@ Client: ${mismatch.client}`,
|
|
|
18912
18999
|
),
|
|
18913
19000
|
// ── Refresh error banner ──────────────────────────────────────────────
|
|
18914
19001
|
// Stale-while-revalidate: error + last good snapshot → show banner
|
|
18915
|
-
errorMsg !== null && hasSnapshot &&
|
|
19002
|
+
errorMsg !== null && hasSnapshot && import_react19.default.createElement(
|
|
18916
19003
|
"div",
|
|
18917
19004
|
{
|
|
18918
19005
|
style: {
|
|
@@ -18926,8 +19013,8 @@ Client: ${mismatch.client}`,
|
|
|
18926
19013
|
alignItems: "center"
|
|
18927
19014
|
}
|
|
18928
19015
|
},
|
|
18929
|
-
|
|
18930
|
-
|
|
19016
|
+
import_react19.default.createElement("span", null, errorMsg),
|
|
19017
|
+
import_react19.default.createElement("button", {
|
|
18931
19018
|
onClick: () => {
|
|
18932
19019
|
if (pendingRef.current === null) {
|
|
18933
19020
|
void loadSnapshot("retry");
|
|
@@ -18948,7 +19035,7 @@ Client: ${mismatch.client}`,
|
|
|
18948
19035
|
}, isRetrying ? "Retrying\u2026" : "Retry")
|
|
18949
19036
|
),
|
|
18950
19037
|
// ── Body: bounded flex viewport ────────────────────────────────────
|
|
18951
|
-
|
|
19038
|
+
import_react19.default.createElement(
|
|
18952
19039
|
"div",
|
|
18953
19040
|
{
|
|
18954
19041
|
style: {
|
|
@@ -18962,17 +19049,17 @@ Client: ${mismatch.client}`,
|
|
|
18962
19049
|
}
|
|
18963
19050
|
},
|
|
18964
19051
|
// Initial loading: shell is already visible, show skeleton
|
|
18965
|
-
isInitialLoading &&
|
|
19052
|
+
isInitialLoading && import_react19.default.createElement("div", {
|
|
18966
19053
|
style: { padding: "24px", color: "var(--dsw-alias-label-tertiary)", fontSize: "14px" }
|
|
18967
19054
|
}, "Loading..."),
|
|
18968
19055
|
// Error state (no last good snapshot)
|
|
18969
|
-
dataState.kind === "error" && !hasSnapshot &&
|
|
19056
|
+
dataState.kind === "error" && !hasSnapshot && import_react19.default.createElement(
|
|
18970
19057
|
"div",
|
|
18971
19058
|
{ style: { padding: "24px" } },
|
|
18972
|
-
|
|
19059
|
+
import_react19.default.createElement("div", {
|
|
18973
19060
|
style: { color: "var(--dsw-status-error)", marginBottom: "12px", fontSize: "14px" }
|
|
18974
19061
|
}, errorMsg ?? "Unknown error"),
|
|
18975
|
-
|
|
19062
|
+
import_react19.default.createElement("button", {
|
|
18976
19063
|
onClick: () => {
|
|
18977
19064
|
if (pendingRef.current === null) {
|
|
18978
19065
|
void loadSnapshot("retry");
|
|
@@ -18992,20 +19079,20 @@ Client: ${mismatch.client}`,
|
|
|
18992
19079
|
}, isRetrying ? "Retrying\u2026" : "Retry")
|
|
18993
19080
|
),
|
|
18994
19081
|
// Unbound state
|
|
18995
|
-
dataState.kind === "unbound" &&
|
|
19082
|
+
dataState.kind === "unbound" && import_react19.default.createElement(
|
|
18996
19083
|
"div",
|
|
18997
19084
|
{ style: { padding: "24px" } },
|
|
18998
|
-
|
|
19085
|
+
import_react19.default.createElement("div", {
|
|
18999
19086
|
style: { fontSize: "14px", color: "var(--dsw-alias-label-tertiary)", marginBottom: "16px" }
|
|
19000
19087
|
}, "This session is not bound to a pentest target."),
|
|
19001
|
-
dataState.targets.length > 0 &&
|
|
19088
|
+
dataState.targets.length > 0 && import_react19.default.createElement(
|
|
19002
19089
|
"div",
|
|
19003
19090
|
{ style: { marginBottom: "12px" } },
|
|
19004
|
-
|
|
19091
|
+
import_react19.default.createElement("div", {
|
|
19005
19092
|
style: { fontSize: "13px", fontWeight: 600, marginBottom: "8px", color: "var(--dsw-alias-label-primary)" }
|
|
19006
19093
|
}, "Existing targets"),
|
|
19007
19094
|
...dataState.targets.map(
|
|
19008
|
-
(t) =>
|
|
19095
|
+
(t) => import_react19.default.createElement(
|
|
19009
19096
|
"div",
|
|
19010
19097
|
{
|
|
19011
19098
|
key: t.id,
|
|
@@ -19020,17 +19107,17 @@ Client: ${mismatch.client}`,
|
|
|
19020
19107
|
fontSize: "13px"
|
|
19021
19108
|
}
|
|
19022
19109
|
},
|
|
19023
|
-
|
|
19110
|
+
import_react19.default.createElement(
|
|
19024
19111
|
"div",
|
|
19025
19112
|
null,
|
|
19026
|
-
|
|
19027
|
-
|
|
19113
|
+
import_react19.default.createElement("div", { style: { fontWeight: 500 } }, t.target),
|
|
19114
|
+
import_react19.default.createElement(
|
|
19028
19115
|
"div",
|
|
19029
19116
|
{ style: { color: "var(--dsw-alias-label-tertiary)", fontSize: "12px" } },
|
|
19030
19117
|
`${t.currentStage ?? "unknown"} \xB7 ${t.status}`
|
|
19031
19118
|
)
|
|
19032
19119
|
),
|
|
19033
|
-
t.rootSessionId !== null &&
|
|
19120
|
+
t.rootSessionId !== null && import_react19.default.createElement("button", {
|
|
19034
19121
|
onClick: () => sessions?.open(t.rootSessionId),
|
|
19035
19122
|
style: {
|
|
19036
19123
|
padding: "4px 12px",
|
|
@@ -19045,7 +19132,7 @@ Client: ${mismatch.client}`,
|
|
|
19045
19132
|
)
|
|
19046
19133
|
)
|
|
19047
19134
|
),
|
|
19048
|
-
|
|
19135
|
+
import_react19.default.createElement("button", {
|
|
19049
19136
|
onClick: () => {
|
|
19050
19137
|
if (pendingRef.current === null) {
|
|
19051
19138
|
void loadSnapshot("refresh");
|
|
@@ -19066,7 +19153,7 @@ Client: ${mismatch.client}`,
|
|
|
19066
19153
|
}, "Refresh")
|
|
19067
19154
|
),
|
|
19068
19155
|
// Bound content — wrapped in a bounded viewport
|
|
19069
|
-
dataState.kind === "bound" &&
|
|
19156
|
+
dataState.kind === "bound" && import_react19.default.createElement(
|
|
19070
19157
|
"div",
|
|
19071
19158
|
{
|
|
19072
19159
|
style: {
|
|
@@ -19078,20 +19165,20 @@ Client: ${mismatch.client}`,
|
|
|
19078
19165
|
flexDirection: "column"
|
|
19079
19166
|
}
|
|
19080
19167
|
},
|
|
19081
|
-
tab === "overview" &&
|
|
19168
|
+
tab === "overview" && import_react19.default.createElement(
|
|
19082
19169
|
ScrollablePage,
|
|
19083
19170
|
null,
|
|
19084
|
-
|
|
19171
|
+
import_react19.default.createElement(OverviewView, {
|
|
19085
19172
|
snapshot,
|
|
19086
19173
|
liveActivity,
|
|
19087
19174
|
onNavigate: navigate,
|
|
19088
19175
|
onOpenSession: openSession
|
|
19089
19176
|
})
|
|
19090
19177
|
),
|
|
19091
|
-
tab === "stages" &&
|
|
19178
|
+
tab === "stages" && import_react19.default.createElement(
|
|
19092
19179
|
ScrollablePage,
|
|
19093
19180
|
null,
|
|
19094
|
-
|
|
19181
|
+
import_react19.default.createElement(StagesView, {
|
|
19095
19182
|
snapshot,
|
|
19096
19183
|
liveActivity,
|
|
19097
19184
|
onNavigate: navigate,
|
|
@@ -19099,17 +19186,17 @@ Client: ${mismatch.client}`,
|
|
|
19099
19186
|
focusStage: navFocus.stage
|
|
19100
19187
|
})
|
|
19101
19188
|
),
|
|
19102
|
-
tab === "findings" &&
|
|
19189
|
+
tab === "findings" && import_react19.default.createElement(FindingsView, {
|
|
19103
19190
|
snapshot,
|
|
19104
19191
|
command: pentesterCommand,
|
|
19105
19192
|
sessionId,
|
|
19106
19193
|
onNavigate: navigate,
|
|
19107
19194
|
focusFinding: navFocus.finding
|
|
19108
19195
|
}),
|
|
19109
|
-
tab === "trace" &&
|
|
19196
|
+
tab === "trace" && import_react19.default.createElement(
|
|
19110
19197
|
ScrollablePage,
|
|
19111
19198
|
null,
|
|
19112
|
-
|
|
19199
|
+
import_react19.default.createElement(TraceView, {
|
|
19113
19200
|
snapshot,
|
|
19114
19201
|
liveActivity,
|
|
19115
19202
|
onNavigate: navigate,
|
|
@@ -19117,7 +19204,7 @@ Client: ${mismatch.client}`,
|
|
|
19117
19204
|
activeTargetId
|
|
19118
19205
|
})
|
|
19119
19206
|
),
|
|
19120
|
-
tab === "output" &&
|
|
19207
|
+
tab === "output" && import_react19.default.createElement(OutputView, {
|
|
19121
19208
|
snapshot,
|
|
19122
19209
|
command: pentesterCommand,
|
|
19123
19210
|
sessionId,
|
|
@@ -19128,7 +19215,7 @@ Client: ${mismatch.client}`,
|
|
|
19128
19215
|
);
|
|
19129
19216
|
}
|
|
19130
19217
|
function ScrollablePage(props) {
|
|
19131
|
-
return
|
|
19218
|
+
return import_react19.default.createElement("div", {
|
|
19132
19219
|
style: {
|
|
19133
19220
|
flex: 1,
|
|
19134
19221
|
minHeight: 0,
|
|
@@ -19219,7 +19306,7 @@ var en = {
|
|
|
19219
19306
|
};
|
|
19220
19307
|
|
|
19221
19308
|
// src/build-id.ts
|
|
19222
|
-
var BUILD_ID = "2.
|
|
19309
|
+
var BUILD_ID = "2.4.0+3a85fc6";
|
|
19223
19310
|
|
|
19224
19311
|
// src/ui/client/plugin.tsx
|
|
19225
19312
|
var SESSION_SWITCH_PERF = "[SESSION_SWITCH_PERF]";
|
|
@@ -19319,7 +19406,7 @@ function apply(ctx) {
|
|
|
19319
19406
|
return { command: (input2) => dockerCommand(face, input2) };
|
|
19320
19407
|
}
|
|
19321
19408
|
},
|
|
19322
|
-
(props) =>
|
|
19409
|
+
(props) => import_react20.default.createElement(PentesterConfigSection, { ...props })
|
|
19323
19410
|
)
|
|
19324
19411
|
);
|
|
19325
19412
|
ctx.slots.inject("conversation.view", () => {
|
|
@@ -19366,7 +19453,7 @@ function apply(ctx) {
|
|
|
19366
19453
|
}
|
|
19367
19454
|
},
|
|
19368
19455
|
(props) => {
|
|
19369
|
-
return
|
|
19456
|
+
return import_react20.default.createElement(PentesterView, {
|
|
19370
19457
|
sessionId: props.sessionId,
|
|
19371
19458
|
reflect: props.reflect,
|
|
19372
19459
|
sessions: props.sessions,
|