pentesting 0.73.13 → 0.73.14
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 +5 -0
- package/dist/{agent-tool-KHXXTHGS.js → agent-tool-MMDCBQ74.js} +3 -3
- package/dist/{chunk-GILD75OT.js → chunk-4KLVUP3C.js} +118 -67
- package/dist/{chunk-4UNNRHYY.js → chunk-AEQNELCQ.js} +172 -39
- package/dist/{chunk-S5ZMXFHR.js → chunk-YZNPWDNS.js} +12 -8
- package/dist/main.js +14 -54
- package/dist/{persistence-U2N3KWFH.js → persistence-IGAKJZJ3.js} +2 -2
- package/dist/{process-registry-4Y3HB4YQ.js → process-registry-DNEZX4S5.js} +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,9 +44,14 @@ docker run -it --rm \
|
|
|
44
44
|
-e PENTEST_API_KEY="your_key" \
|
|
45
45
|
-e PENTEST_BASE_URL="https://api.z.ai/api/anthropic" \
|
|
46
46
|
-e PENTEST_MODEL="glm-4.7" \
|
|
47
|
+
-v pentesting-data:/tmp/.pentesting \
|
|
47
48
|
agnusdei1207/pentesting
|
|
48
49
|
```
|
|
49
50
|
|
|
51
|
+
Docker stores workspace state under `/tmp/.pentesting` inside the container.
|
|
52
|
+
The entrypoint resets that directory on each fresh container start to avoid mixing stale state into a new run.
|
|
53
|
+
Mount that path if you want access to `.pentesting/turns`, `.pentesting/sessions`, `.pentesting/memory`, and workspace artifacts after an OOM or while the same container is still alive.
|
|
54
|
+
|
|
50
55
|
### 🐉 Kali Linux (Native)
|
|
51
56
|
|
|
52
57
|
```bash
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
createContextExtractor,
|
|
6
6
|
getLLMClient,
|
|
7
7
|
getShellSupervisorLifecycleSnapshot
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4KLVUP3C.js";
|
|
9
9
|
import {
|
|
10
10
|
AGENT_ROLES,
|
|
11
11
|
EVENT_TYPES,
|
|
@@ -13,14 +13,14 @@ import {
|
|
|
13
13
|
TOOL_NAMES,
|
|
14
14
|
getProcessOutput,
|
|
15
15
|
listBackgroundProcesses
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-AEQNELCQ.js";
|
|
17
17
|
import {
|
|
18
18
|
DETECTION_PATTERNS,
|
|
19
19
|
PROCESS_EVENTS,
|
|
20
20
|
PROCESS_ROLES,
|
|
21
21
|
getActiveProcessSummary,
|
|
22
22
|
getProcessEventLog
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-YZNPWDNS.js";
|
|
24
24
|
|
|
25
25
|
// src/engine/agent-tool/completion-box.ts
|
|
26
26
|
function createCompletionBox() {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
DANGER_LEVELS,
|
|
11
11
|
DANGER_LEVEL_MAP,
|
|
12
12
|
DEFAULTS,
|
|
13
|
+
DEFAULT_MODEL,
|
|
13
14
|
DISPLAY_LIMITS,
|
|
14
15
|
DynamicTechniqueLibrary,
|
|
15
16
|
EVENT_TYPES,
|
|
@@ -52,11 +53,19 @@ import {
|
|
|
52
53
|
generateId,
|
|
53
54
|
generatePrefixedId,
|
|
54
55
|
getActiveSessionRuntime,
|
|
56
|
+
getApiKey,
|
|
57
|
+
getBaseUrl,
|
|
55
58
|
getErrorMessage,
|
|
59
|
+
getModel,
|
|
56
60
|
getProcessOutput,
|
|
61
|
+
getSearchApiKey,
|
|
62
|
+
getSearchApiUrl,
|
|
63
|
+
getThinkingBudget,
|
|
57
64
|
getTorBrowserArgs,
|
|
58
65
|
getUsedPorts,
|
|
59
66
|
isBranchMemoryEnabled,
|
|
67
|
+
isThinkingEnabled,
|
|
68
|
+
isZaiProvider,
|
|
60
69
|
listBackgroundProcesses,
|
|
61
70
|
llmNodeCooldownPolicy,
|
|
62
71
|
llmNodeOutputParsing,
|
|
@@ -69,7 +78,7 @@ import {
|
|
|
69
78
|
startBackgroundProcess,
|
|
70
79
|
stopBackgroundProcess,
|
|
71
80
|
writeFileContent
|
|
72
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-AEQNELCQ.js";
|
|
73
82
|
import {
|
|
74
83
|
DETECTION_PATTERNS,
|
|
75
84
|
HEALTH_CONFIG,
|
|
@@ -83,59 +92,7 @@ import {
|
|
|
83
92
|
__require,
|
|
84
93
|
getProcessEventLog,
|
|
85
94
|
logEvent
|
|
86
|
-
} from "./chunk-
|
|
87
|
-
|
|
88
|
-
// src/shared/utils/config/env.ts
|
|
89
|
-
var ENV_KEYS = {
|
|
90
|
-
API_KEY: "PENTEST_API_KEY",
|
|
91
|
-
BASE_URL: "PENTEST_BASE_URL",
|
|
92
|
-
MODEL: "PENTEST_MODEL",
|
|
93
|
-
SEARCH_API_KEY: "SEARCH_API_KEY",
|
|
94
|
-
SEARCH_API_URL: "SEARCH_API_URL",
|
|
95
|
-
THINKING: "PENTEST_THINKING",
|
|
96
|
-
THINKING_BUDGET: "PENTEST_THINKING_BUDGET",
|
|
97
|
-
SCOPE_MODE: "PENTEST_SCOPE_MODE",
|
|
98
|
-
APPROVAL_MODE: "PENTEST_APPROVAL_MODE",
|
|
99
|
-
CONTAINERIZED: "PENTEST_CONTAINERIZED",
|
|
100
|
-
APP_VERSION: "PENTESTING_VERSION"
|
|
101
|
-
};
|
|
102
|
-
var DEFAULT_THINKING_BUDGET = 8e3;
|
|
103
|
-
var DEFAULT_SEARCH_API_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
104
|
-
var DEFAULT_MODEL = "glm-4.7";
|
|
105
|
-
function getApiKey() {
|
|
106
|
-
return process.env[ENV_KEYS.API_KEY] || "";
|
|
107
|
-
}
|
|
108
|
-
function getOptionalEnv(key) {
|
|
109
|
-
const value = process.env[key];
|
|
110
|
-
return value && value !== "" ? value : void 0;
|
|
111
|
-
}
|
|
112
|
-
function getBaseUrl() {
|
|
113
|
-
return getOptionalEnv(ENV_KEYS.BASE_URL);
|
|
114
|
-
}
|
|
115
|
-
function getModel() {
|
|
116
|
-
return process.env[ENV_KEYS.MODEL] || "";
|
|
117
|
-
}
|
|
118
|
-
function getSearchApiKey() {
|
|
119
|
-
const explicitKey = getOptionalEnv(ENV_KEYS.SEARCH_API_KEY);
|
|
120
|
-
if (explicitKey) {
|
|
121
|
-
return explicitKey;
|
|
122
|
-
}
|
|
123
|
-
return getOptionalEnv(ENV_KEYS.API_KEY);
|
|
124
|
-
}
|
|
125
|
-
function getSearchApiUrl() {
|
|
126
|
-
return process.env[ENV_KEYS.SEARCH_API_URL] || DEFAULT_SEARCH_API_URL;
|
|
127
|
-
}
|
|
128
|
-
function isZaiProvider() {
|
|
129
|
-
const baseUrl = getBaseUrl() || "";
|
|
130
|
-
return baseUrl.includes("z.ai");
|
|
131
|
-
}
|
|
132
|
-
function isThinkingEnabled() {
|
|
133
|
-
return process.env[ENV_KEYS.THINKING] !== "false";
|
|
134
|
-
}
|
|
135
|
-
function getThinkingBudget() {
|
|
136
|
-
const val = parseInt(process.env[ENV_KEYS.THINKING_BUDGET] || "", 10);
|
|
137
|
-
return isNaN(val) ? DEFAULT_THINKING_BUDGET : Math.max(1024, val);
|
|
138
|
-
}
|
|
95
|
+
} from "./chunk-YZNPWDNS.js";
|
|
139
96
|
|
|
140
97
|
// src/shared/constants/llm/api.ts
|
|
141
98
|
var LLM_API = {
|
|
@@ -558,14 +515,42 @@ var LLMClient = class {
|
|
|
558
515
|
const currentBlockRef = { value: null };
|
|
559
516
|
const toolCallsMap = /* @__PURE__ */ new Map();
|
|
560
517
|
let totalChars = 0;
|
|
518
|
+
let storedContentChars = 0;
|
|
519
|
+
let storedReasoningChars = 0;
|
|
520
|
+
let contentWasTruncated = false;
|
|
521
|
+
let reasoningWasTruncated = false;
|
|
561
522
|
let wasAborted = false;
|
|
562
523
|
context.onContent = (text) => {
|
|
563
|
-
contentChunks.push(text);
|
|
564
524
|
totalChars += text.length;
|
|
525
|
+
const remaining = LLM_LIMITS.streamStoredContentChars - storedContentChars;
|
|
526
|
+
if (remaining <= 0) {
|
|
527
|
+
contentWasTruncated = true;
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const slice = text.slice(0, remaining);
|
|
531
|
+
if (slice) {
|
|
532
|
+
contentChunks.push(slice);
|
|
533
|
+
storedContentChars += slice.length;
|
|
534
|
+
}
|
|
535
|
+
if (slice.length < text.length) {
|
|
536
|
+
contentWasTruncated = true;
|
|
537
|
+
}
|
|
565
538
|
};
|
|
566
539
|
context.onReasoning = (text) => {
|
|
567
|
-
reasoningChunks.push(text);
|
|
568
540
|
totalChars += text.length;
|
|
541
|
+
const remaining = LLM_LIMITS.streamStoredReasoningChars - storedReasoningChars;
|
|
542
|
+
if (remaining <= 0) {
|
|
543
|
+
reasoningWasTruncated = true;
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
const slice = text.slice(0, remaining);
|
|
547
|
+
if (slice) {
|
|
548
|
+
reasoningChunks.push(slice);
|
|
549
|
+
storedReasoningChars += slice.length;
|
|
550
|
+
}
|
|
551
|
+
if (slice.length < text.length) {
|
|
552
|
+
reasoningWasTruncated = true;
|
|
553
|
+
}
|
|
569
554
|
};
|
|
570
555
|
context.onUsage = (u) => {
|
|
571
556
|
usage = u;
|
|
@@ -578,7 +563,13 @@ var LLMClient = class {
|
|
|
578
563
|
throw new DOMException("Aborted string generation", "AbortError");
|
|
579
564
|
}
|
|
580
565
|
const toolCalls = resolveToolCalls(toolCallsMap);
|
|
581
|
-
const
|
|
566
|
+
const truncatedContent = contentWasTruncated ? `${contentChunks.join("")}
|
|
567
|
+
|
|
568
|
+
...[assistant output truncated for memory safety]` : contentChunks.join("");
|
|
569
|
+
const truncatedReasoning = reasoningWasTruncated ? `${reasoningChunks.join("")}
|
|
570
|
+
|
|
571
|
+
...[reasoning truncated for memory safety]` : reasoningChunks.join("");
|
|
572
|
+
const stripped = stripThinkTags(truncatedContent, truncatedReasoning);
|
|
582
573
|
if (usage.input_tokens > 0 || usage.output_tokens > 0) {
|
|
583
574
|
addGlobalTokenUsage(usage);
|
|
584
575
|
}
|
|
@@ -2015,8 +2006,8 @@ var PASSTHROUGH_THRESHOLD = 2e3;
|
|
|
2015
2006
|
var PREPROCESS_THRESHOLD = 3e3;
|
|
2016
2007
|
var MAX_PREPROCESSED_LINES = 800;
|
|
2017
2008
|
var MAX_DUPLICATE_DISPLAY = 3;
|
|
2018
|
-
var ANALYST_MAX_INPUT_CHARS =
|
|
2019
|
-
var FALLBACK_MAX_CHARS =
|
|
2009
|
+
var ANALYST_MAX_INPUT_CHARS = 4e4;
|
|
2010
|
+
var FALLBACK_MAX_CHARS = 15e3;
|
|
2020
2011
|
var NOISE_PATTERNS = [
|
|
2021
2012
|
/^\s*$/,
|
|
2022
2013
|
// blank lines
|
|
@@ -2345,6 +2336,8 @@ function getAnalystSystemPrompt() {
|
|
|
2345
2336
|
}
|
|
2346
2337
|
function createLLMDigestFn(llmClient) {
|
|
2347
2338
|
return async (text, context) => {
|
|
2339
|
+
const cappedText = text.length > ANALYST_MAX_INPUT_CHARS ? `${text.slice(0, ANALYST_MAX_INPUT_CHARS)}
|
|
2340
|
+
... [truncated at ${ANALYST_MAX_INPUT_CHARS} chars before Analyst request]` : text;
|
|
2348
2341
|
const messages = [{
|
|
2349
2342
|
role: LLM_ROLES.USER,
|
|
2350
2343
|
content: `Analyze this pentesting tool output and extract actionable intelligence.
|
|
@@ -2352,7 +2345,7 @@ function createLLMDigestFn(llmClient) {
|
|
|
2352
2345
|
Context: ${context}
|
|
2353
2346
|
|
|
2354
2347
|
--- OUTPUT START ---
|
|
2355
|
-
${
|
|
2348
|
+
${cappedText}
|
|
2356
2349
|
--- OUTPUT END ---`
|
|
2357
2350
|
}];
|
|
2358
2351
|
const response = await llmClient.generateResponse(
|
|
@@ -3751,15 +3744,18 @@ var HealthMonitor = class {
|
|
|
3751
3744
|
check() {
|
|
3752
3745
|
const processes = this.checkProcesses();
|
|
3753
3746
|
const ports = this.checkPorts();
|
|
3754
|
-
const
|
|
3747
|
+
const memory = this.checkMemory();
|
|
3748
|
+
const recommendations = this.generateRecommendations(memory);
|
|
3755
3749
|
const overall = this.calculateOverall({
|
|
3756
3750
|
zombies: processes.zombies,
|
|
3751
|
+
memoryStatus: memory.status,
|
|
3757
3752
|
recommendations
|
|
3758
3753
|
});
|
|
3759
3754
|
return {
|
|
3760
3755
|
overall,
|
|
3761
3756
|
processes,
|
|
3762
3757
|
ports,
|
|
3758
|
+
memory,
|
|
3763
3759
|
recommendations
|
|
3764
3760
|
};
|
|
3765
3761
|
}
|
|
@@ -3795,10 +3791,42 @@ var HealthMonitor = class {
|
|
|
3795
3791
|
}
|
|
3796
3792
|
return { inUse, conflicts };
|
|
3797
3793
|
}
|
|
3794
|
+
/**
|
|
3795
|
+
* Check Node.js process memory health.
|
|
3796
|
+
*/
|
|
3797
|
+
checkMemory() {
|
|
3798
|
+
const usage = process.memoryUsage();
|
|
3799
|
+
const heapUsedRatio = usage.heapTotal > 0 ? usage.heapUsed / usage.heapTotal : 0;
|
|
3800
|
+
if (heapUsedRatio >= HEALTH_CONFIG.MEMORY_CRITICAL_HEAP_RATIO || usage.rss >= HEALTH_CONFIG.MEMORY_CRITICAL_RSS_BYTES) {
|
|
3801
|
+
return {
|
|
3802
|
+
rssBytes: usage.rss,
|
|
3803
|
+
heapUsedBytes: usage.heapUsed,
|
|
3804
|
+
heapTotalBytes: usage.heapTotal,
|
|
3805
|
+
heapUsedRatio,
|
|
3806
|
+
status: HEALTH_STATUS.CRITICAL
|
|
3807
|
+
};
|
|
3808
|
+
}
|
|
3809
|
+
if (heapUsedRatio >= HEALTH_CONFIG.MEMORY_WARNING_HEAP_RATIO || usage.rss >= HEALTH_CONFIG.MEMORY_WARNING_RSS_BYTES) {
|
|
3810
|
+
return {
|
|
3811
|
+
rssBytes: usage.rss,
|
|
3812
|
+
heapUsedBytes: usage.heapUsed,
|
|
3813
|
+
heapTotalBytes: usage.heapTotal,
|
|
3814
|
+
heapUsedRatio,
|
|
3815
|
+
status: HEALTH_STATUS.WARNING
|
|
3816
|
+
};
|
|
3817
|
+
}
|
|
3818
|
+
return {
|
|
3819
|
+
rssBytes: usage.rss,
|
|
3820
|
+
heapUsedBytes: usage.heapUsed,
|
|
3821
|
+
heapTotalBytes: usage.heapTotal,
|
|
3822
|
+
heapUsedRatio,
|
|
3823
|
+
status: HEALTH_STATUS.HEALTHY
|
|
3824
|
+
};
|
|
3825
|
+
}
|
|
3798
3826
|
/**
|
|
3799
3827
|
* Generate recommendations based on current state
|
|
3800
3828
|
*/
|
|
3801
|
-
generateRecommendations() {
|
|
3829
|
+
generateRecommendations(memory) {
|
|
3802
3830
|
const recs = [];
|
|
3803
3831
|
const procs = listBackgroundProcesses();
|
|
3804
3832
|
for (const proc of procs) {
|
|
@@ -3810,6 +3838,15 @@ var HealthMonitor = class {
|
|
|
3810
3838
|
recs.push(`[${proc.id}] ${proc.role} running for ${durMin}min`);
|
|
3811
3839
|
}
|
|
3812
3840
|
}
|
|
3841
|
+
if (memory.status === HEALTH_STATUS.CRITICAL) {
|
|
3842
|
+
recs.push(
|
|
3843
|
+
`Memory critical: heap ${(memory.heapUsedRatio * 100).toFixed(0)}% (${this.formatBytes(memory.heapUsedBytes)}/${this.formatBytes(memory.heapTotalBytes)}), rss ${this.formatBytes(memory.rssBytes)} - reduce prompt/output volume immediately`
|
|
3844
|
+
);
|
|
3845
|
+
} else if (memory.status === HEALTH_STATUS.WARNING) {
|
|
3846
|
+
recs.push(
|
|
3847
|
+
`Memory warning: heap ${(memory.heapUsedRatio * 100).toFixed(0)}% (${this.formatBytes(memory.heapUsedBytes)}/${this.formatBytes(memory.heapTotalBytes)}), rss ${this.formatBytes(memory.rssBytes)}`
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3813
3850
|
return recs;
|
|
3814
3851
|
}
|
|
3815
3852
|
/**
|
|
@@ -3817,9 +3854,21 @@ var HealthMonitor = class {
|
|
|
3817
3854
|
*/
|
|
3818
3855
|
calculateOverall(data) {
|
|
3819
3856
|
if (data.zombies > 0) return HEALTH_STATUS.CRITICAL;
|
|
3857
|
+
if (data.memoryStatus === HEALTH_STATUS.CRITICAL) return HEALTH_STATUS.CRITICAL;
|
|
3858
|
+
if (data.memoryStatus === HEALTH_STATUS.WARNING) return HEALTH_STATUS.WARNING;
|
|
3820
3859
|
if (data.recommendations.length > HEALTH_CONFIG.MAX_RECOMMENDATIONS_FOR_HEALTHY) return HEALTH_STATUS.WARNING;
|
|
3821
3860
|
return HEALTH_STATUS.HEALTHY;
|
|
3822
3861
|
}
|
|
3862
|
+
formatBytes(bytes) {
|
|
3863
|
+
const units = ["B", "KB", "MB", "GB"];
|
|
3864
|
+
let value = bytes;
|
|
3865
|
+
let unitIndex = 0;
|
|
3866
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
3867
|
+
value /= 1024;
|
|
3868
|
+
unitIndex++;
|
|
3869
|
+
}
|
|
3870
|
+
return `${value.toFixed(unitIndex === 0 ? 0 : 1)}${units[unitIndex]}`;
|
|
3871
|
+
}
|
|
3823
3872
|
};
|
|
3824
3873
|
|
|
3825
3874
|
// src/engine/resource/zombie-hunter.ts
|
|
@@ -3905,6 +3954,9 @@ async function executeBgStatus() {
|
|
|
3905
3954
|
}
|
|
3906
3955
|
lines.push(`
|
|
3907
3956
|
## Health: ${health.overall.toUpperCase()}`);
|
|
3957
|
+
lines.push(
|
|
3958
|
+
`Memory: ${health.memory.status.toUpperCase()} heap=${(health.memory.heapUsedRatio * 100).toFixed(0)}% (${Math.round(health.memory.heapUsedBytes / 1024 / 1024)}MB/${Math.round(health.memory.heapTotalBytes / 1024 / 1024)}MB) rss=${Math.round(health.memory.rssBytes / 1024 / 1024)}MB`
|
|
3959
|
+
);
|
|
3908
3960
|
if (health.recommendations.length > 0) {
|
|
3909
3961
|
lines.push("Recommendations:");
|
|
3910
3962
|
for (const r of health.recommendations) {
|
|
@@ -3976,6 +4028,9 @@ async function executeHealthCheck() {
|
|
|
3976
4028
|
const lines = [];
|
|
3977
4029
|
lines.push(`Health: ${status.overall.toUpperCase()}`);
|
|
3978
4030
|
lines.push(`Processes: ${status.processes.running}/${status.processes.total} running`);
|
|
4031
|
+
lines.push(
|
|
4032
|
+
`Memory: ${status.memory.status.toUpperCase()} heap=${(status.memory.heapUsedRatio * 100).toFixed(0)}% (${Math.round(status.memory.heapUsedBytes / 1024 / 1024)}MB/${Math.round(status.memory.heapTotalBytes / 1024 / 1024)}MB) rss=${Math.round(status.memory.rssBytes / 1024 / 1024)}MB`
|
|
4033
|
+
);
|
|
3979
4034
|
if (status.ports.inUse.length > 0) {
|
|
3980
4035
|
lines.push(`Ports in use: ${status.ports.inUse.join(", ")}`);
|
|
3981
4036
|
}
|
|
@@ -11084,7 +11139,7 @@ After completion: record key loot/findings from the sub-agent output to canonica
|
|
|
11084
11139
|
rootTaskId: activeExecution.rootTaskId
|
|
11085
11140
|
}
|
|
11086
11141
|
});
|
|
11087
|
-
const { AgentTool } = await import("./agent-tool-
|
|
11142
|
+
const { AgentTool } = await import("./agent-tool-MMDCBQ74.js");
|
|
11088
11143
|
const executor = new AgentTool(state, events, scopeGuard, approvalGate);
|
|
11089
11144
|
try {
|
|
11090
11145
|
const result = await executor.execute(input);
|
|
@@ -11363,10 +11418,6 @@ function buildShellSupervisorLifecycleSection() {
|
|
|
11363
11418
|
}
|
|
11364
11419
|
|
|
11365
11420
|
export {
|
|
11366
|
-
ENV_KEYS,
|
|
11367
|
-
DEFAULT_MODEL,
|
|
11368
|
-
getApiKey,
|
|
11369
|
-
getModel,
|
|
11370
11421
|
getTimeAdaptiveStrategy,
|
|
11371
11422
|
SharedState,
|
|
11372
11423
|
HealthMonitor,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
getRuntimeSectionOr,
|
|
21
21
|
logEvent,
|
|
22
22
|
setProcess
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-YZNPWDNS.js";
|
|
24
24
|
|
|
25
25
|
// src/shared/constants/time/conversions.ts
|
|
26
26
|
var MS_PER_MINUTE = 6e4;
|
|
@@ -273,6 +273,10 @@ var LLM_LIMITS = {
|
|
|
273
273
|
nonStreamMaxTokens: 65536,
|
|
274
274
|
/** WHY dynamic: streaming calls are the main agent loop. Override via config. */
|
|
275
275
|
streamMaxTokens: mainLlmTokens,
|
|
276
|
+
/** WHY: cap stored assistant content even when provider streams far more text. */
|
|
277
|
+
streamStoredContentChars: 6e4,
|
|
278
|
+
/** WHY: reasoning is only used for UI/think-tag extraction, not canonical memory. */
|
|
279
|
+
streamStoredReasoningChars: 24e3,
|
|
276
280
|
/** WHY: ~3.5 chars/token is a reasonable average for mixed English/CJK content */
|
|
277
281
|
charsPerTokenEstimate: 3.5,
|
|
278
282
|
/** WHY: 5 minutes max timeout for streaming and non-streaming responses */
|
|
@@ -348,7 +352,7 @@ var INPUT_PROMPT_PATTERNS = [
|
|
|
348
352
|
];
|
|
349
353
|
|
|
350
354
|
// src/shared/constants/agent.ts
|
|
351
|
-
var APP_VERSION = "0.73.
|
|
355
|
+
var APP_VERSION = "0.73.14";
|
|
352
356
|
var APP_DESCRIPTION = "Autonomous Penetration Testing AI Agent";
|
|
353
357
|
var LLM_ROLES = {
|
|
354
358
|
SYSTEM: "system",
|
|
@@ -1067,17 +1071,133 @@ function getInputHandler() {
|
|
|
1067
1071
|
// src/shared/constants/paths.ts
|
|
1068
1072
|
import path2 from "path";
|
|
1069
1073
|
|
|
1074
|
+
// src/shared/utils/config/runtime-safety.ts
|
|
1075
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
1076
|
+
|
|
1077
|
+
// src/shared/utils/config/env.ts
|
|
1078
|
+
var ENV_KEYS = {
|
|
1079
|
+
API_KEY: "PENTEST_API_KEY",
|
|
1080
|
+
BASE_URL: "PENTEST_BASE_URL",
|
|
1081
|
+
MODEL: "PENTEST_MODEL",
|
|
1082
|
+
SEARCH_API_KEY: "SEARCH_API_KEY",
|
|
1083
|
+
SEARCH_API_URL: "SEARCH_API_URL",
|
|
1084
|
+
THINKING: "PENTEST_THINKING",
|
|
1085
|
+
THINKING_BUDGET: "PENTEST_THINKING_BUDGET",
|
|
1086
|
+
SCOPE_MODE: "PENTEST_SCOPE_MODE",
|
|
1087
|
+
APPROVAL_MODE: "PENTEST_APPROVAL_MODE",
|
|
1088
|
+
CONTAINERIZED: "PENTEST_CONTAINERIZED",
|
|
1089
|
+
APP_VERSION: "PENTESTING_VERSION"
|
|
1090
|
+
};
|
|
1091
|
+
var DEFAULT_THINKING_BUDGET = 8e3;
|
|
1092
|
+
var DEFAULT_SEARCH_API_URL = "https://api.search.brave.com/res/v1/web/search";
|
|
1093
|
+
var DEFAULT_MODEL = "glm-4.7";
|
|
1094
|
+
function getApiKey() {
|
|
1095
|
+
return process.env[ENV_KEYS.API_KEY] || "";
|
|
1096
|
+
}
|
|
1097
|
+
function getOptionalEnv(key) {
|
|
1098
|
+
const value = process.env[key];
|
|
1099
|
+
return value && value !== "" ? value : void 0;
|
|
1100
|
+
}
|
|
1101
|
+
function getBaseUrl() {
|
|
1102
|
+
return getOptionalEnv(ENV_KEYS.BASE_URL);
|
|
1103
|
+
}
|
|
1104
|
+
function getModel() {
|
|
1105
|
+
return process.env[ENV_KEYS.MODEL] || "";
|
|
1106
|
+
}
|
|
1107
|
+
function getSearchApiKey() {
|
|
1108
|
+
const explicitKey = getOptionalEnv(ENV_KEYS.SEARCH_API_KEY);
|
|
1109
|
+
if (explicitKey) {
|
|
1110
|
+
return explicitKey;
|
|
1111
|
+
}
|
|
1112
|
+
return getOptionalEnv(ENV_KEYS.API_KEY);
|
|
1113
|
+
}
|
|
1114
|
+
function getSearchApiUrl() {
|
|
1115
|
+
return process.env[ENV_KEYS.SEARCH_API_URL] || DEFAULT_SEARCH_API_URL;
|
|
1116
|
+
}
|
|
1117
|
+
function isZaiProvider() {
|
|
1118
|
+
const baseUrl = getBaseUrl() || "";
|
|
1119
|
+
return baseUrl.includes("z.ai");
|
|
1120
|
+
}
|
|
1121
|
+
function isThinkingEnabled() {
|
|
1122
|
+
return process.env[ENV_KEYS.THINKING] !== "false";
|
|
1123
|
+
}
|
|
1124
|
+
function getThinkingBudget() {
|
|
1125
|
+
const val = parseInt(process.env[ENV_KEYS.THINKING_BUDGET] || "", 10);
|
|
1126
|
+
return isNaN(val) ? DEFAULT_THINKING_BUDGET : Math.max(1024, val);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/shared/utils/config/runtime-safety.ts
|
|
1130
|
+
var CONTAINER_MARKER_PATH = "/.dockerenv";
|
|
1131
|
+
var CGROUP_PATH = "/proc/1/cgroup";
|
|
1132
|
+
var CONTAINER_RUNTIME_PATTERN = /(docker|containerd|kubepods|podman)/i;
|
|
1133
|
+
var SCOPE_MODES = ["advisory", "enforce"];
|
|
1134
|
+
var APPROVAL_MODES = ["advisory", "require_auto_approve"];
|
|
1135
|
+
function getOptionalEnv2(key) {
|
|
1136
|
+
const value = process.env[key];
|
|
1137
|
+
return value && value !== "" ? value : void 0;
|
|
1138
|
+
}
|
|
1139
|
+
function getBooleanOverride(key) {
|
|
1140
|
+
const value = getOptionalEnv2(key);
|
|
1141
|
+
if (value === "true") return true;
|
|
1142
|
+
if (value === "false") return false;
|
|
1143
|
+
return void 0;
|
|
1144
|
+
}
|
|
1145
|
+
function getEnumEnv(key, allowed) {
|
|
1146
|
+
const value = getOptionalEnv2(key);
|
|
1147
|
+
return value && allowed.includes(value) ? value : void 0;
|
|
1148
|
+
}
|
|
1149
|
+
function isContainerizedRuntime() {
|
|
1150
|
+
const override = getBooleanOverride(ENV_KEYS.CONTAINERIZED);
|
|
1151
|
+
if (override !== void 0) return override;
|
|
1152
|
+
if (existsSync2(CONTAINER_MARKER_PATH)) return true;
|
|
1153
|
+
try {
|
|
1154
|
+
const cgroup = readFileSync2(CGROUP_PATH, "utf-8");
|
|
1155
|
+
return CONTAINER_RUNTIME_PATTERN.test(cgroup);
|
|
1156
|
+
} catch {
|
|
1157
|
+
return false;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
function getScopeMode() {
|
|
1161
|
+
const configured = getEnumEnv(ENV_KEYS.SCOPE_MODE, SCOPE_MODES);
|
|
1162
|
+
if (configured) return configured;
|
|
1163
|
+
return isContainerizedRuntime() ? "advisory" : "enforce";
|
|
1164
|
+
}
|
|
1165
|
+
function getApprovalMode() {
|
|
1166
|
+
const configured = getEnumEnv(ENV_KEYS.APPROVAL_MODE, APPROVAL_MODES);
|
|
1167
|
+
if (configured) return configured;
|
|
1168
|
+
return isContainerizedRuntime() ? "advisory" : "require_auto_approve";
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1070
1171
|
// src/agents/workspace-config.ts
|
|
1071
1172
|
var DEFAULT_WORKSPACE_ROOT = ".pentesting";
|
|
1072
1173
|
var DEFAULT_WORKSPACE_DIRECTORIES = {};
|
|
1174
|
+
var DOCKER_WORKSPACE_ROOT = "/tmp/.pentesting";
|
|
1073
1175
|
function getWorkspaceConfig() {
|
|
1074
1176
|
return getRuntimeSectionOr("workspace", {});
|
|
1075
1177
|
}
|
|
1076
1178
|
function getWorkspaceRoot() {
|
|
1077
|
-
|
|
1179
|
+
const configuredRoot = getWorkspaceConfig().root ?? DEFAULT_WORKSPACE_ROOT;
|
|
1180
|
+
return remapWorkspacePath(configuredRoot);
|
|
1078
1181
|
}
|
|
1079
1182
|
function getWorkspaceDirectories() {
|
|
1080
|
-
|
|
1183
|
+
const configured = getWorkspaceConfig().directories ?? DEFAULT_WORKSPACE_DIRECTORIES;
|
|
1184
|
+
return Object.fromEntries(
|
|
1185
|
+
Object.entries(configured).map(([key, value]) => [key, remapWorkspacePath(value)])
|
|
1186
|
+
);
|
|
1187
|
+
}
|
|
1188
|
+
function remapWorkspacePath(pathValue) {
|
|
1189
|
+
if (!isContainerizedRuntime()) {
|
|
1190
|
+
return pathValue;
|
|
1191
|
+
}
|
|
1192
|
+
const normalized = pathValue.replace(/\/+$/, "");
|
|
1193
|
+
const defaultRoot = DEFAULT_WORKSPACE_ROOT.replace(/\/+$/, "");
|
|
1194
|
+
if (normalized === defaultRoot) {
|
|
1195
|
+
return DOCKER_WORKSPACE_ROOT;
|
|
1196
|
+
}
|
|
1197
|
+
if (normalized.startsWith(`${defaultRoot}/`)) {
|
|
1198
|
+
return `${DOCKER_WORKSPACE_ROOT}${normalized.slice(defaultRoot.length)}`;
|
|
1199
|
+
}
|
|
1200
|
+
return pathValue;
|
|
1081
1201
|
}
|
|
1082
1202
|
|
|
1083
1203
|
// src/shared/constants/files/extensions.ts
|
|
@@ -1125,9 +1245,9 @@ var SPECIAL_FILES = {
|
|
|
1125
1245
|
};
|
|
1126
1246
|
|
|
1127
1247
|
// src/shared/utils/file-ops/file-utils.ts
|
|
1128
|
-
import { existsSync as
|
|
1248
|
+
import { existsSync as existsSync3, mkdirSync } from "fs";
|
|
1129
1249
|
function ensureDirExists(dirPath) {
|
|
1130
|
-
if (!
|
|
1250
|
+
if (!existsSync3(dirPath)) {
|
|
1131
1251
|
mkdirSync(dirPath, { recursive: true });
|
|
1132
1252
|
}
|
|
1133
1253
|
}
|
|
@@ -1438,7 +1558,7 @@ var BLOCKED_BINARIES = /* @__PURE__ */ new Set([
|
|
|
1438
1558
|
]);
|
|
1439
1559
|
|
|
1440
1560
|
// src/shared/utils/debug/debug-logger.ts
|
|
1441
|
-
import { appendFileSync, writeFileSync, statSync, readFileSync as
|
|
1561
|
+
import { appendFileSync, writeFileSync, statSync, readFileSync as readFileSync3 } from "fs";
|
|
1442
1562
|
import { join } from "path";
|
|
1443
1563
|
var ROTATE_BYTES = 5 * 1024 * 1024;
|
|
1444
1564
|
var WIPE_BYTES = 20 * 1024 * 1024;
|
|
@@ -1490,7 +1610,7 @@ var DebugLogger = class _DebugLogger {
|
|
|
1490
1610
|
writeFileSync(this.logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] [GENERAL] === LOG WIPED (exceeded ${Math.round(WIPE_BYTES / 1024 / 1024)}MB) ===
|
|
1491
1611
|
`);
|
|
1492
1612
|
} else if (size > ROTATE_BYTES) {
|
|
1493
|
-
const content =
|
|
1613
|
+
const content = readFileSync3(this.logPath, "utf-8");
|
|
1494
1614
|
const half = content.slice(Math.floor(content.length / 2));
|
|
1495
1615
|
const firstNewline = half.indexOf("\n");
|
|
1496
1616
|
const trimmed = firstNewline >= 0 ? half.slice(firstNewline + 1) : half;
|
|
@@ -2526,7 +2646,7 @@ Suggestion: ${torLeak.suggestion}`
|
|
|
2526
2646
|
}
|
|
2527
2647
|
|
|
2528
2648
|
// src/engine/tools-base/file-operations.ts
|
|
2529
|
-
import { readFileSync as
|
|
2649
|
+
import { readFileSync as readFileSync4, existsSync as existsSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
2530
2650
|
import { dirname } from "path";
|
|
2531
2651
|
import { join as join2 } from "path";
|
|
2532
2652
|
import { tmpdir } from "os";
|
|
@@ -2546,14 +2666,14 @@ function getErrorMessage(error) {
|
|
|
2546
2666
|
// src/engine/tools-base/file-operations.ts
|
|
2547
2667
|
async function readFileContent(filePath) {
|
|
2548
2668
|
try {
|
|
2549
|
-
if (!
|
|
2669
|
+
if (!existsSync4(filePath)) {
|
|
2550
2670
|
return {
|
|
2551
2671
|
success: false,
|
|
2552
2672
|
output: "",
|
|
2553
2673
|
error: `File not found: ${filePath}`
|
|
2554
2674
|
};
|
|
2555
2675
|
}
|
|
2556
|
-
const content =
|
|
2676
|
+
const content = readFileSync4(filePath, "utf-8");
|
|
2557
2677
|
return {
|
|
2558
2678
|
success: true,
|
|
2559
2679
|
output: content
|
|
@@ -2664,7 +2784,7 @@ function startBackgroundProcess(command, options = {}) {
|
|
|
2664
2784
|
}
|
|
2665
2785
|
|
|
2666
2786
|
// src/engine/process/process-interaction.ts
|
|
2667
|
-
import { existsSync as
|
|
2787
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, appendFileSync as appendFileSync2 } from "fs";
|
|
2668
2788
|
async function sendToProcess(processId, input, waitMs = SYSTEM_LIMITS.DEFAULT_WAIT_MS_INTERACT) {
|
|
2669
2789
|
const proc = getProcess(processId);
|
|
2670
2790
|
if (!proc) return { success: false, output: `Process ${processId} not found`, newOutput: "" };
|
|
@@ -2672,8 +2792,8 @@ async function sendToProcess(processId, input, waitMs = SYSTEM_LIMITS.DEFAULT_WA
|
|
|
2672
2792
|
if (proc.hasExited) return { success: false, output: `Process ${processId} has exited`, newOutput: "" };
|
|
2673
2793
|
let currentLen = 0;
|
|
2674
2794
|
try {
|
|
2675
|
-
if (
|
|
2676
|
-
currentLen =
|
|
2795
|
+
if (existsSync5(proc.stdoutFile)) {
|
|
2796
|
+
currentLen = readFileSync5(proc.stdoutFile, "utf-8").length;
|
|
2677
2797
|
}
|
|
2678
2798
|
} catch {
|
|
2679
2799
|
}
|
|
@@ -2686,8 +2806,8 @@ async function sendToProcess(processId, input, waitMs = SYSTEM_LIMITS.DEFAULT_WA
|
|
|
2686
2806
|
await new Promise((r) => setTimeout(r, waitMs));
|
|
2687
2807
|
let fullStdout = "";
|
|
2688
2808
|
try {
|
|
2689
|
-
if (
|
|
2690
|
-
fullStdout =
|
|
2809
|
+
if (existsSync5(proc.stdoutFile)) {
|
|
2810
|
+
fullStdout = readFileSync5(proc.stdoutFile, "utf-8");
|
|
2691
2811
|
}
|
|
2692
2812
|
} catch {
|
|
2693
2813
|
}
|
|
@@ -2709,7 +2829,7 @@ function promoteToShell(processId, description) {
|
|
|
2709
2829
|
}
|
|
2710
2830
|
|
|
2711
2831
|
// src/engine/process/process-monitor.ts
|
|
2712
|
-
import { existsSync as
|
|
2832
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
|
|
2713
2833
|
function isProcessRunning(processId) {
|
|
2714
2834
|
const proc = getProcess(processId);
|
|
2715
2835
|
if (!proc) return false;
|
|
@@ -2722,8 +2842,8 @@ function isProcessRunning(processId) {
|
|
|
2722
2842
|
proc.childPids = discoverAllDescendants(proc.pid);
|
|
2723
2843
|
if (proc.role === PROCESS_ROLES.LISTENER) {
|
|
2724
2844
|
try {
|
|
2725
|
-
if (
|
|
2726
|
-
const stdout =
|
|
2845
|
+
if (existsSync6(proc.stdoutFile)) {
|
|
2846
|
+
const stdout = readFileSync6(proc.stdoutFile, "utf-8");
|
|
2727
2847
|
if (detectConnection(stdout)) {
|
|
2728
2848
|
promoteToShell(processId, "Reverse shell connected (auto-detected)");
|
|
2729
2849
|
logEvent(processId, PROCESS_EVENTS.CONNECTION_DETECTED, `Connection detected on port ${proc.listeningPort}`);
|
|
@@ -2741,16 +2861,16 @@ function getProcessOutput(processId) {
|
|
|
2741
2861
|
let stdout = "";
|
|
2742
2862
|
let stderr = "";
|
|
2743
2863
|
try {
|
|
2744
|
-
if (
|
|
2745
|
-
const content =
|
|
2864
|
+
if (existsSync6(proc.stdoutFile)) {
|
|
2865
|
+
const content = readFileSync6(proc.stdoutFile, "utf-8");
|
|
2746
2866
|
stdout = content.length > SYSTEM_LIMITS.MAX_STDOUT_SLICE ? `... [truncated ${content.length - SYSTEM_LIMITS.MAX_STDOUT_SLICE} chars] ...
|
|
2747
2867
|
` + content.slice(-SYSTEM_LIMITS.MAX_STDOUT_SLICE) : content;
|
|
2748
2868
|
}
|
|
2749
2869
|
} catch {
|
|
2750
2870
|
}
|
|
2751
2871
|
try {
|
|
2752
|
-
if (
|
|
2753
|
-
const content =
|
|
2872
|
+
if (existsSync6(proc.stderrFile)) {
|
|
2873
|
+
const content = readFileSync6(proc.stderrFile, "utf-8");
|
|
2754
2874
|
stderr = content.length > SYSTEM_LIMITS.MAX_STDERR_SLICE ? `... [truncated ${content.length - SYSTEM_LIMITS.MAX_STDERR_SLICE} chars] ...
|
|
2755
2875
|
` + content.slice(-SYSTEM_LIMITS.MAX_STDERR_SLICE) : content;
|
|
2756
2876
|
}
|
|
@@ -2856,7 +2976,7 @@ async function cleanupAllProcesses() {
|
|
|
2856
2976
|
cleanupDone = false;
|
|
2857
2977
|
return;
|
|
2858
2978
|
}
|
|
2859
|
-
const { getBackgroundProcessesMap: getBackgroundProcessesMap2 } = await import("./process-registry-
|
|
2979
|
+
const { getBackgroundProcessesMap: getBackgroundProcessesMap2 } = await import("./process-registry-DNEZX4S5.js");
|
|
2860
2980
|
const backgroundProcesses = getBackgroundProcessesMap2();
|
|
2861
2981
|
terminateAllNatively(backgroundProcesses, "SIGTERM");
|
|
2862
2982
|
await new Promise((r) => setTimeout(r, SYSTEM_LIMITS.CLEANUP_BATCH_WAIT_MS));
|
|
@@ -2923,7 +3043,7 @@ function cleanupOrphanProcesses() {
|
|
|
2923
3043
|
}
|
|
2924
3044
|
|
|
2925
3045
|
// src/engine/process/resource-summary.ts
|
|
2926
|
-
import { existsSync as
|
|
3046
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
|
|
2927
3047
|
function formatActiveProcesses(running, lines) {
|
|
2928
3048
|
if (running.length === 0) return;
|
|
2929
3049
|
lines.push(`Active Assets (${running.length}):`);
|
|
@@ -2935,8 +3055,8 @@ function formatActiveProcesses(running, lines) {
|
|
|
2935
3055
|
const roleIcon = PROCESS_ICONS[p.role] || PROCESS_ICONS[PROCESS_ROLES.BACKGROUND];
|
|
2936
3056
|
let lastOutput = "";
|
|
2937
3057
|
try {
|
|
2938
|
-
if (p.stdoutFile &&
|
|
2939
|
-
const content =
|
|
3058
|
+
if (p.stdoutFile && existsSync7(p.stdoutFile)) {
|
|
3059
|
+
const content = readFileSync7(p.stdoutFile, "utf-8");
|
|
2940
3060
|
const outputLines = content.trim().split("\n");
|
|
2941
3061
|
lastOutput = outputLines.slice(-SYSTEM_LIMITS.RECENT_OUTPUT_LINES).join(" | ").replace(/\n/g, " ");
|
|
2942
3062
|
}
|
|
@@ -3410,7 +3530,7 @@ var EpisodicMemory = class {
|
|
|
3410
3530
|
};
|
|
3411
3531
|
|
|
3412
3532
|
// src/shared/utils/agent-memory/persistent-memory.ts
|
|
3413
|
-
import { existsSync as
|
|
3533
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
|
|
3414
3534
|
import { join as join4 } from "path";
|
|
3415
3535
|
|
|
3416
3536
|
// src/shared/utils/agent-memory/similarity.ts
|
|
@@ -3439,7 +3559,7 @@ function matchesServiceProfile(serviceProfile, services) {
|
|
|
3439
3559
|
}
|
|
3440
3560
|
|
|
3441
3561
|
// src/shared/utils/agent-memory/session-snapshot.ts
|
|
3442
|
-
import { existsSync as
|
|
3562
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync as writeFileSync4, unlinkSync as unlinkSync4 } from "fs";
|
|
3443
3563
|
import { join as join3 } from "path";
|
|
3444
3564
|
|
|
3445
3565
|
// src/agents/memory-rollout-config.ts
|
|
@@ -3473,8 +3593,8 @@ function saveSessionSnapshot(snapshot) {
|
|
|
3473
3593
|
}
|
|
3474
3594
|
function loadSessionSnapshot() {
|
|
3475
3595
|
try {
|
|
3476
|
-
if (
|
|
3477
|
-
return JSON.parse(
|
|
3596
|
+
if (existsSync8(SNAPSHOT_FILE)) {
|
|
3597
|
+
return JSON.parse(readFileSync8(SNAPSHOT_FILE, "utf-8"));
|
|
3478
3598
|
}
|
|
3479
3599
|
} catch {
|
|
3480
3600
|
}
|
|
@@ -3509,7 +3629,7 @@ function snapshotToPrompt() {
|
|
|
3509
3629
|
}
|
|
3510
3630
|
function clearSessionSnapshot() {
|
|
3511
3631
|
try {
|
|
3512
|
-
if (
|
|
3632
|
+
if (existsSync8(SNAPSHOT_FILE)) {
|
|
3513
3633
|
unlinkSync4(SNAPSHOT_FILE);
|
|
3514
3634
|
}
|
|
3515
3635
|
} catch {
|
|
@@ -3659,8 +3779,8 @@ var PersistentMemory = class {
|
|
|
3659
3779
|
}
|
|
3660
3780
|
load() {
|
|
3661
3781
|
try {
|
|
3662
|
-
if (
|
|
3663
|
-
const data = JSON.parse(
|
|
3782
|
+
if (existsSync9(MEMORY_FILE)) {
|
|
3783
|
+
const data = JSON.parse(readFileSync9(MEMORY_FILE, "utf-8"));
|
|
3664
3784
|
return {
|
|
3665
3785
|
...data,
|
|
3666
3786
|
exploitChains: data.exploitChains ?? []
|
|
@@ -5611,15 +5731,15 @@ function pruneOldSessions(sessionsDir) {
|
|
|
5611
5731
|
}
|
|
5612
5732
|
|
|
5613
5733
|
// src/engine/state/persistence/loader.ts
|
|
5614
|
-
import { readFileSync as
|
|
5734
|
+
import { readFileSync as readFileSync10, existsSync as existsSync10 } from "fs";
|
|
5615
5735
|
import { join as join6 } from "path";
|
|
5616
5736
|
function loadState(state3) {
|
|
5617
5737
|
const latestFile = join6(WORKSPACE.SESSIONS, "latest.json");
|
|
5618
|
-
if (!
|
|
5738
|
+
if (!existsSync10(latestFile)) {
|
|
5619
5739
|
return false;
|
|
5620
5740
|
}
|
|
5621
5741
|
try {
|
|
5622
|
-
const raw =
|
|
5742
|
+
const raw = readFileSync10(latestFile, "utf-8");
|
|
5623
5743
|
const snapshot = JSON.parse(raw);
|
|
5624
5744
|
if (snapshot.version !== 1) {
|
|
5625
5745
|
debugLog("general", `Unknown snapshot version: ${snapshot.version}`);
|
|
@@ -5669,7 +5789,7 @@ function loadState(state3) {
|
|
|
5669
5789
|
}
|
|
5670
5790
|
|
|
5671
5791
|
// src/engine/state/persistence/janitor.ts
|
|
5672
|
-
import { existsSync as
|
|
5792
|
+
import { existsSync as existsSync11, rmSync } from "fs";
|
|
5673
5793
|
import path3 from "path";
|
|
5674
5794
|
function clearWorkspace() {
|
|
5675
5795
|
const cleared = [];
|
|
@@ -5687,7 +5807,7 @@ function clearWorkspace() {
|
|
|
5687
5807
|
];
|
|
5688
5808
|
for (const dir2 of dirsToClean) {
|
|
5689
5809
|
try {
|
|
5690
|
-
if (
|
|
5810
|
+
if (existsSync11(dir2.path)) {
|
|
5691
5811
|
rmSync(dir2.path, { recursive: true, force: true });
|
|
5692
5812
|
ensureDirExists(dir2.path);
|
|
5693
5813
|
cleared.push(dir2.label);
|
|
@@ -5700,6 +5820,19 @@ function clearWorkspace() {
|
|
|
5700
5820
|
}
|
|
5701
5821
|
|
|
5702
5822
|
export {
|
|
5823
|
+
ENV_KEYS,
|
|
5824
|
+
DEFAULT_MODEL,
|
|
5825
|
+
getApiKey,
|
|
5826
|
+
getBaseUrl,
|
|
5827
|
+
getModel,
|
|
5828
|
+
getSearchApiKey,
|
|
5829
|
+
getSearchApiUrl,
|
|
5830
|
+
isZaiProvider,
|
|
5831
|
+
isThinkingEnabled,
|
|
5832
|
+
getThinkingBudget,
|
|
5833
|
+
isContainerizedRuntime,
|
|
5834
|
+
getScopeMode,
|
|
5835
|
+
getApprovalMode,
|
|
5703
5836
|
ensureDirExists,
|
|
5704
5837
|
getWorkspaceConfig,
|
|
5705
5838
|
FILE_EXTENSIONS,
|
|
@@ -136,8 +136,8 @@ var RUNTIME_CONFIG_LLM_NODES = {
|
|
|
136
136
|
".pentesting/workspace/tools/"
|
|
137
137
|
],
|
|
138
138
|
limits: {
|
|
139
|
-
max_tokens:
|
|
140
|
-
max_prompt_chars:
|
|
139
|
+
max_tokens: 49152,
|
|
140
|
+
max_prompt_chars: 18e4
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
143
|
analyst: {
|
|
@@ -480,7 +480,7 @@ function definePromptLayer(layer) {
|
|
|
480
480
|
return layer;
|
|
481
481
|
}
|
|
482
482
|
var RUNTIME_CONFIG_PROMPT_BUILDER = {
|
|
483
|
-
max_chars:
|
|
483
|
+
max_chars: 18e4,
|
|
484
484
|
truncation: "back",
|
|
485
485
|
preserved_last: "user_context",
|
|
486
486
|
layers: [
|
|
@@ -790,16 +790,16 @@ var RUNTIME_CONFIG_LIMITS = {
|
|
|
790
790
|
eviction: "delete_oldest_first"
|
|
791
791
|
},
|
|
792
792
|
messages: {
|
|
793
|
-
context_extractor_per_msg_limit:
|
|
793
|
+
context_extractor_per_msg_limit: 12e3,
|
|
794
794
|
truncation_direction: "back"
|
|
795
795
|
},
|
|
796
796
|
prompt: {
|
|
797
|
-
max_chars:
|
|
797
|
+
max_chars: 18e4,
|
|
798
798
|
truncation_direction: "back",
|
|
799
799
|
preserved_last: "user_context"
|
|
800
800
|
},
|
|
801
801
|
tool_output: {
|
|
802
|
-
max_chars:
|
|
802
|
+
max_chars: 6e4
|
|
803
803
|
},
|
|
804
804
|
agent_loop: {
|
|
805
805
|
max_iterations: 500,
|
|
@@ -829,7 +829,7 @@ var RUNTIME_CONFIG_COMPRESSION = {
|
|
|
829
829
|
strategy: "llm_compress",
|
|
830
830
|
trigger: "every_turn",
|
|
831
831
|
agent: "context_extractor",
|
|
832
|
-
per_msg_max_chars:
|
|
832
|
+
per_msg_max_chars: 12e3,
|
|
833
833
|
output_format: "<session-context>\n{value}\n</session-context>",
|
|
834
834
|
write_mode: "replace_all",
|
|
835
835
|
on_failure: "keep_existing"
|
|
@@ -1074,7 +1074,11 @@ var HEALTH_CONFIG = {
|
|
|
1074
1074
|
// 5 minutes
|
|
1075
1075
|
VERY_LONG_RUNNING_THRESHOLD_MS: 9e5,
|
|
1076
1076
|
// 15 minutes
|
|
1077
|
-
MAX_RECOMMENDATIONS_FOR_HEALTHY: 2
|
|
1077
|
+
MAX_RECOMMENDATIONS_FOR_HEALTHY: 2,
|
|
1078
|
+
MEMORY_WARNING_HEAP_RATIO: 0.7,
|
|
1079
|
+
MEMORY_CRITICAL_HEAP_RATIO: 0.85,
|
|
1080
|
+
MEMORY_WARNING_RSS_BYTES: 12e8,
|
|
1081
|
+
MEMORY_CRITICAL_RSS_BYTES: 18e8
|
|
1078
1082
|
};
|
|
1079
1083
|
|
|
1080
1084
|
// src/engine/process/process-registry.ts
|
package/dist/main.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
import {
|
|
3
3
|
CategorizedToolRegistry,
|
|
4
4
|
CoreAgent,
|
|
5
|
-
DEFAULT_MODEL,
|
|
6
|
-
ENV_KEYS,
|
|
7
5
|
HealthMonitor,
|
|
8
6
|
INITIAL_TASKS,
|
|
9
7
|
PROMPT_CONFIG,
|
|
@@ -23,11 +21,9 @@ import {
|
|
|
23
21
|
ensurePolicyDocument,
|
|
24
22
|
formatChallengeAnalysis,
|
|
25
23
|
formatTurnRecord,
|
|
26
|
-
getApiKey,
|
|
27
24
|
getDefaultPolicyDocument,
|
|
28
25
|
getGlobalRequestCount,
|
|
29
26
|
getGlobalTokenUsage,
|
|
30
|
-
getModel,
|
|
31
27
|
getNextTurnNumber,
|
|
32
28
|
getServiceContext,
|
|
33
29
|
getShellSupervisorLifecycleSnapshot,
|
|
@@ -39,7 +35,7 @@ import {
|
|
|
39
35
|
rotateTurnRecords,
|
|
40
36
|
setCurrentTurn,
|
|
41
37
|
writePolicyDocument
|
|
42
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-4KLVUP3C.js";
|
|
43
39
|
import {
|
|
44
40
|
AGENT_ROLES,
|
|
45
41
|
APP_DESCRIPTION,
|
|
@@ -48,8 +44,10 @@ import {
|
|
|
48
44
|
COMMAND_EVENT_TYPES,
|
|
49
45
|
CONFIDENCE_THRESHOLDS,
|
|
50
46
|
DEFAULTS,
|
|
47
|
+
DEFAULT_MODEL,
|
|
51
48
|
DISPLAY_LIMITS,
|
|
52
49
|
EDGE_STATUS,
|
|
50
|
+
ENV_KEYS,
|
|
53
51
|
EVENT_TYPES,
|
|
54
52
|
INPUT_TYPES,
|
|
55
53
|
LLM_LIMITS,
|
|
@@ -75,11 +73,16 @@ import {
|
|
|
75
73
|
extractSuccessfulChain,
|
|
76
74
|
flowLog,
|
|
77
75
|
generateId,
|
|
76
|
+
getApiKey,
|
|
77
|
+
getApprovalMode,
|
|
78
78
|
getErrorMessage,
|
|
79
|
+
getModel,
|
|
79
80
|
getProcessOutput,
|
|
81
|
+
getScopeMode,
|
|
80
82
|
getWorkspaceConfig,
|
|
81
83
|
initDebugLogger,
|
|
82
84
|
isBranchMemoryEnabled,
|
|
85
|
+
isContainerizedRuntime,
|
|
83
86
|
listBackgroundProcesses,
|
|
84
87
|
loadState,
|
|
85
88
|
readRuntimeAssetFile,
|
|
@@ -88,12 +91,12 @@ import {
|
|
|
88
91
|
setActiveSessionRuntime,
|
|
89
92
|
setTorEnabled,
|
|
90
93
|
snapshotToPrompt
|
|
91
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-AEQNELCQ.js";
|
|
92
95
|
import {
|
|
93
96
|
EXIT_CODES,
|
|
94
97
|
getOptionalRuntimeSection,
|
|
95
98
|
getRequiredRuntimeSection
|
|
96
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-YZNPWDNS.js";
|
|
97
100
|
|
|
98
101
|
// src/platform/tui/main.tsx
|
|
99
102
|
import chalk4 from "chalk";
|
|
@@ -211,49 +214,6 @@ var ICONS = {
|
|
|
211
214
|
pwned: "\u25C8"
|
|
212
215
|
};
|
|
213
216
|
|
|
214
|
-
// src/shared/utils/config/runtime-safety.ts
|
|
215
|
-
import { existsSync, readFileSync } from "fs";
|
|
216
|
-
var CONTAINER_MARKER_PATH = "/.dockerenv";
|
|
217
|
-
var CGROUP_PATH = "/proc/1/cgroup";
|
|
218
|
-
var CONTAINER_RUNTIME_PATTERN = /(docker|containerd|kubepods|podman)/i;
|
|
219
|
-
var SCOPE_MODES = ["advisory", "enforce"];
|
|
220
|
-
var APPROVAL_MODES = ["advisory", "require_auto_approve"];
|
|
221
|
-
function getOptionalEnv(key) {
|
|
222
|
-
const value = process.env[key];
|
|
223
|
-
return value && value !== "" ? value : void 0;
|
|
224
|
-
}
|
|
225
|
-
function getBooleanOverride(key) {
|
|
226
|
-
const value = getOptionalEnv(key);
|
|
227
|
-
if (value === "true") return true;
|
|
228
|
-
if (value === "false") return false;
|
|
229
|
-
return void 0;
|
|
230
|
-
}
|
|
231
|
-
function getEnumEnv(key, allowed) {
|
|
232
|
-
const value = getOptionalEnv(key);
|
|
233
|
-
return value && allowed.includes(value) ? value : void 0;
|
|
234
|
-
}
|
|
235
|
-
function isContainerizedRuntime() {
|
|
236
|
-
const override = getBooleanOverride(ENV_KEYS.CONTAINERIZED);
|
|
237
|
-
if (override !== void 0) return override;
|
|
238
|
-
if (existsSync(CONTAINER_MARKER_PATH)) return true;
|
|
239
|
-
try {
|
|
240
|
-
const cgroup = readFileSync(CGROUP_PATH, "utf-8");
|
|
241
|
-
return CONTAINER_RUNTIME_PATTERN.test(cgroup);
|
|
242
|
-
} catch {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
function getScopeMode() {
|
|
247
|
-
const configured = getEnumEnv(ENV_KEYS.SCOPE_MODE, SCOPE_MODES);
|
|
248
|
-
if (configured) return configured;
|
|
249
|
-
return isContainerizedRuntime() ? "advisory" : "enforce";
|
|
250
|
-
}
|
|
251
|
-
function getApprovalMode() {
|
|
252
|
-
const configured = getEnumEnv(ENV_KEYS.APPROVAL_MODE, APPROVAL_MODES);
|
|
253
|
-
if (configured) return configured;
|
|
254
|
-
return isContainerizedRuntime() ? "advisory" : "require_auto_approve";
|
|
255
|
-
}
|
|
256
|
-
|
|
257
217
|
// src/shared/utils/config/validation.ts
|
|
258
218
|
function validateRequiredConfig() {
|
|
259
219
|
const errors = [];
|
|
@@ -3285,7 +3245,7 @@ var makeRotateTurns = (_llm, _opts) => async (_ctx) => {
|
|
|
3285
3245
|
};
|
|
3286
3246
|
var makeSaveSession = (_llm, _opts) => async (ctx) => {
|
|
3287
3247
|
try {
|
|
3288
|
-
const { saveState: saveState2 } = await import("./persistence-
|
|
3248
|
+
const { saveState: saveState2 } = await import("./persistence-IGAKJZJ3.js");
|
|
3289
3249
|
saveState2(ctx.state);
|
|
3290
3250
|
} catch {
|
|
3291
3251
|
}
|
|
@@ -3492,7 +3452,7 @@ function getRuntimePipelineConfig() {
|
|
|
3492
3452
|
}
|
|
3493
3453
|
|
|
3494
3454
|
// src/agents/prompt-builder/prompt-loader.ts
|
|
3495
|
-
import { readFileSync
|
|
3455
|
+
import { readFileSync } from "fs";
|
|
3496
3456
|
import { join } from "path";
|
|
3497
3457
|
|
|
3498
3458
|
// src/agents/prompt-sources.ts
|
|
@@ -3542,7 +3502,7 @@ function loadPromptFile(filename) {
|
|
|
3542
3502
|
const path2 = join(getPromptsDir(), filename);
|
|
3543
3503
|
try {
|
|
3544
3504
|
const resolved = resolveRuntimeAssetPath(path2) ?? path2;
|
|
3545
|
-
return
|
|
3505
|
+
return readFileSync(resolved, PROMPT_CONFIG.ENCODING);
|
|
3546
3506
|
} catch {
|
|
3547
3507
|
return "";
|
|
3548
3508
|
}
|
|
@@ -3552,7 +3512,7 @@ function loadTechniqueFile(techniqueName) {
|
|
|
3552
3512
|
const filePath = join(getTechniquesDir(), filename);
|
|
3553
3513
|
try {
|
|
3554
3514
|
const resolved = resolveRuntimeAssetPath(filePath) ?? filePath;
|
|
3555
|
-
return
|
|
3515
|
+
return readFileSync(resolved, PROMPT_CONFIG.ENCODING);
|
|
3556
3516
|
} catch {
|
|
3557
3517
|
return "";
|
|
3558
3518
|
}
|