aurix-ai 0.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/AgentLoop.d.ts +1 -1
- package/dist/agent/AgentLoop.d.ts.map +1 -1
- package/dist/agent/AgentLoop.js +49 -13
- package/dist/agent/AgentLoop.js.map +1 -1
- package/dist/agent/Context.d.ts.map +1 -1
- package/dist/agent/Context.js +13 -5
- package/dist/agent/Context.js.map +1 -1
- package/dist/agent/ContextManager.d.ts.map +1 -1
- package/dist/agent/ContextManager.js +5 -0
- package/dist/agent/ContextManager.js.map +1 -1
- package/dist/cli/App.d.ts.map +1 -1
- package/dist/cli/App.js +17 -2
- package/dist/cli/App.js.map +1 -1
- package/dist/gateway/Gateway.d.ts.map +1 -1
- package/dist/gateway/Gateway.js +8 -2
- package/dist/gateway/Gateway.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +58 -0
- package/dist/providers/index.js.map +1 -1
- package/dist/tools/ArchiveReader.d.ts +3 -0
- package/dist/tools/ArchiveReader.d.ts.map +1 -0
- package/dist/tools/ArchiveReader.js +297 -0
- package/dist/tools/ArchiveReader.js.map +1 -0
- package/dist/tools/Browser.d.ts.map +1 -1
- package/dist/tools/Browser.js +188 -44
- package/dist/tools/Browser.js.map +1 -1
- package/dist/tools/Osint.d.ts.map +1 -1
- package/dist/tools/Osint.js +554 -41
- package/dist/tools/Osint.js.map +1 -1
- package/package.json +1 -1
package/dist/tools/Browser.js
CHANGED
|
@@ -22,6 +22,116 @@ function warn(msg, details) {
|
|
|
22
22
|
lines.push(` ${k}: ${v}`);
|
|
23
23
|
return lines.join('\n');
|
|
24
24
|
}
|
|
25
|
+
// ─── Human-Like Mouse Utilities ────────────────────────────────────────────
|
|
26
|
+
function bezierPoint(t, points) {
|
|
27
|
+
if (points.length === 1)
|
|
28
|
+
return points[0];
|
|
29
|
+
const next = [];
|
|
30
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
31
|
+
next.push([
|
|
32
|
+
points[i][0] + (points[i + 1][0] - points[i][0]) * t,
|
|
33
|
+
points[i][1] + (points[i + 1][1] - points[i][1]) * t,
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
return bezierPoint(t, next);
|
|
37
|
+
}
|
|
38
|
+
function easeInOut(t) {
|
|
39
|
+
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
40
|
+
}
|
|
41
|
+
async function humanMove(x, y, page) {
|
|
42
|
+
const mouse = page.mouse;
|
|
43
|
+
const vp = page.viewportSize() || { width: 1280, height: 720 };
|
|
44
|
+
// Start from a random position if we don't know current pos
|
|
45
|
+
const startX = Math.random() * vp.width * 0.3;
|
|
46
|
+
const startY = Math.random() * vp.height * 0.3;
|
|
47
|
+
// Generate 2-4 control points for bezier curve
|
|
48
|
+
const numControls = 2 + Math.floor(Math.random() * 3);
|
|
49
|
+
const controlPoints = [[startX, startY]];
|
|
50
|
+
for (let i = 0; i < numControls; i++) {
|
|
51
|
+
const frac = (i + 1) / (numControls + 1);
|
|
52
|
+
const cx = startX + (x - startX) * frac + (Math.random() - 0.5) * 80;
|
|
53
|
+
const cy = startY + (y - startY) * frac + (Math.random() - 0.5) * 60;
|
|
54
|
+
controlPoints.push([cx, cy]);
|
|
55
|
+
}
|
|
56
|
+
controlPoints.push([x, y]);
|
|
57
|
+
// Step through the curve with eased timing
|
|
58
|
+
const totalSteps = 25 + Math.floor(Math.random() * 20);
|
|
59
|
+
for (let step = 0; step <= totalSteps; step++) {
|
|
60
|
+
const rawT = step / totalSteps;
|
|
61
|
+
const t = easeInOut(rawT);
|
|
62
|
+
const [px, py] = bezierPoint(t, controlPoints);
|
|
63
|
+
// Sine-wave micro-tremor (not uniform random)
|
|
64
|
+
const tremor = Math.sin(step * 0.3 + Math.random() * 0.5) * 0.4;
|
|
65
|
+
const tremorY = Math.cos(step * 0.25 + Math.random() * 0.5) * 0.3;
|
|
66
|
+
await mouse.move(px + tremor, py + tremorY);
|
|
67
|
+
// Variable step delay: faster in middle, slower at start/end
|
|
68
|
+
const speedFactor = 1 - Math.abs(rawT - 0.5) * 2;
|
|
69
|
+
const delay = 8 + Math.random() * 12 + speedFactor * 5;
|
|
70
|
+
await page.waitForTimeout(delay);
|
|
71
|
+
}
|
|
72
|
+
// Occasional overshoot + correction
|
|
73
|
+
if (Math.random() > 0.6) {
|
|
74
|
+
const overX = x + (Math.random() - 0.5) * 8;
|
|
75
|
+
const overY = y + (Math.random() - 0.5) * 8;
|
|
76
|
+
await mouse.move(overX, overY);
|
|
77
|
+
await page.waitForTimeout(30 + Math.random() * 40);
|
|
78
|
+
await mouse.move(x, y);
|
|
79
|
+
await page.waitForTimeout(20 + Math.random() * 30);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function warmupBehavior(page) {
|
|
83
|
+
const vp = page.viewportSize() || { width: 1280, height: 720 };
|
|
84
|
+
const spots = 3 + Math.floor(Math.random() * 3);
|
|
85
|
+
for (let i = 0; i < spots; i++) {
|
|
86
|
+
const rx = Math.random() * vp.width;
|
|
87
|
+
const ry = Math.random() * vp.height;
|
|
88
|
+
await humanMove(rx, ry, page);
|
|
89
|
+
await page.waitForTimeout(200 + Math.random() * 600);
|
|
90
|
+
}
|
|
91
|
+
// Small scroll
|
|
92
|
+
if (Math.random() > 0.4) {
|
|
93
|
+
const scrollDelta = Math.floor(Math.random() * 200) - 100;
|
|
94
|
+
await page.mouse.wheel(0, scrollDelta);
|
|
95
|
+
await page.waitForTimeout(300 + Math.random() * 500);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function humanHold(x, y, duration, page) {
|
|
99
|
+
const mouse = page.mouse;
|
|
100
|
+
const holdSteps = Math.floor(duration / 80);
|
|
101
|
+
const breathFreq = 0.15 + Math.random() * 0.1;
|
|
102
|
+
const breathAmpX = 0.3 + Math.random() * 0.4;
|
|
103
|
+
const breathAmpY = 0.2 + Math.random() * 0.3;
|
|
104
|
+
await mouse.down();
|
|
105
|
+
for (let i = 0; i < holdSteps; i++) {
|
|
106
|
+
// Sine-wave breathing movement (natural hand tremor)
|
|
107
|
+
const breathX = Math.sin(i * breathFreq) * breathAmpX;
|
|
108
|
+
const breathY = Math.cos(i * breathFreq * 0.7) * breathAmpY;
|
|
109
|
+
// Occasional micro-adjustment
|
|
110
|
+
const adjX = Math.random() > 0.95 ? (Math.random() - 0.5) * 2 : 0;
|
|
111
|
+
const adjY = Math.random() > 0.95 ? (Math.random() - 0.5) * 2 : 0;
|
|
112
|
+
await mouse.move(x + breathX + adjX, y + breathY + adjY);
|
|
113
|
+
await page.waitForTimeout(60 + Math.random() * 40);
|
|
114
|
+
}
|
|
115
|
+
// Release with slight upward drift
|
|
116
|
+
await mouse.move(x + (Math.random() - 0.5) * 3, y - 1 - Math.random() * 2);
|
|
117
|
+
await page.waitForTimeout(30 + Math.random() * 50);
|
|
118
|
+
await mouse.up();
|
|
119
|
+
}
|
|
120
|
+
async function humanClick(locator, page) {
|
|
121
|
+
const box = await locator.first().boundingBox();
|
|
122
|
+
if (box) {
|
|
123
|
+
const clickX = box.x + box.width * (0.3 + Math.random() * 0.4);
|
|
124
|
+
const clickY = box.y + box.height * (0.3 + Math.random() * 0.4);
|
|
125
|
+
await humanMove(clickX, clickY, page);
|
|
126
|
+
await page.waitForTimeout(60 + Math.random() * 100);
|
|
127
|
+
await page.mouse.down();
|
|
128
|
+
await page.waitForTimeout(50 + Math.random() * 80);
|
|
129
|
+
await page.mouse.up();
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
await locator.first().click({ force: true });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
25
135
|
const sessions = new Map();
|
|
26
136
|
let currentSessionKey = 'default';
|
|
27
137
|
let consecutiveEvalFailures = 0;
|
|
@@ -1143,7 +1253,7 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1143
1253
|
const checkbox = checkboxFrame.locator('#recaptcha-anchor, .recaptcha-checkbox, .rc-anchor-checkbox');
|
|
1144
1254
|
if (await checkbox.count() > 0) {
|
|
1145
1255
|
await p.waitForTimeout(1000 + Math.random() * 1500);
|
|
1146
|
-
await checkbox
|
|
1256
|
+
await humanClick(checkbox, p);
|
|
1147
1257
|
await p.waitForTimeout(3000);
|
|
1148
1258
|
const updatedFrames = p.frames();
|
|
1149
1259
|
const challengeFrame = updatedFrames.find(f => f.url().includes('/recaptcha/') && f.url().includes('/bframe'));
|
|
@@ -1164,7 +1274,8 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1164
1274
|
}
|
|
1165
1275
|
else {
|
|
1166
1276
|
results.push(warn('reCAPTCHA anchor frame found but checkbox element missing', { action: 'trying click on anchor body' }));
|
|
1167
|
-
|
|
1277
|
+
const anchor = checkboxFrame.locator('#recaptcha-anchor');
|
|
1278
|
+
await humanClick(anchor, p).catch(() => { });
|
|
1168
1279
|
await p.waitForTimeout(3000);
|
|
1169
1280
|
results.push('Use "captcha-grid" to check for image challenge.');
|
|
1170
1281
|
}
|
|
@@ -1173,7 +1284,7 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1173
1284
|
results.push(warn('No reCAPTCHA anchor frame found', { action: 'trying main page widget' }));
|
|
1174
1285
|
const mainCheckbox = p.locator('.g-recaptcha, [data-sitekey]');
|
|
1175
1286
|
if (await mainCheckbox.count() > 0) {
|
|
1176
|
-
await mainCheckbox
|
|
1287
|
+
await humanClick(mainCheckbox, p);
|
|
1177
1288
|
await p.waitForTimeout(3000);
|
|
1178
1289
|
results.push('Clicked reCAPTCHA widget. Use "captcha-grid" if image challenge appeared.');
|
|
1179
1290
|
}
|
|
@@ -1194,7 +1305,7 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1194
1305
|
const checkbox = checkboxFrame.locator('#checkbox, .check');
|
|
1195
1306
|
if (await checkbox.count() > 0) {
|
|
1196
1307
|
await p.waitForTimeout(800 + Math.random() * 1200);
|
|
1197
|
-
await checkbox
|
|
1308
|
+
await humanClick(checkbox, p);
|
|
1198
1309
|
await p.waitForTimeout(3000);
|
|
1199
1310
|
const updatedFrames = p.frames();
|
|
1200
1311
|
const challengeFrame = updatedFrames.find((f) => f.url().includes('hcaptcha') && f.url().includes('challenge'));
|
|
@@ -1233,7 +1344,7 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1233
1344
|
await p.waitForTimeout(1500 + Math.random() * 1000);
|
|
1234
1345
|
const cb = turnstileFrame.locator('input[type="checkbox"], .cb-lb');
|
|
1235
1346
|
if (await cb.count() > 0) {
|
|
1236
|
-
await cb
|
|
1347
|
+
await humanClick(cb, p);
|
|
1237
1348
|
await p.waitForTimeout(3000);
|
|
1238
1349
|
results.push(ok('Turnstile checkbox clicked'));
|
|
1239
1350
|
}
|
|
@@ -1502,7 +1613,19 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1502
1613
|
return err(`Tile index ${tileIndex} out of range (0-${tiles.length - 1})`);
|
|
1503
1614
|
try {
|
|
1504
1615
|
const tile = tiles[tileIndex];
|
|
1505
|
-
await tile.
|
|
1616
|
+
const tileBox = await tile.boundingBox();
|
|
1617
|
+
if (tileBox) {
|
|
1618
|
+
const clickX = tileBox.x + tileBox.width * (0.3 + Math.random() * 0.4);
|
|
1619
|
+
const clickY = tileBox.y + tileBox.height * (0.3 + Math.random() * 0.4);
|
|
1620
|
+
await humanMove(clickX, clickY, p);
|
|
1621
|
+
await p.waitForTimeout(80 + Math.random() * 120);
|
|
1622
|
+
await p.mouse.down();
|
|
1623
|
+
await p.waitForTimeout(60 + Math.random() * 100);
|
|
1624
|
+
await p.mouse.up();
|
|
1625
|
+
}
|
|
1626
|
+
else {
|
|
1627
|
+
await tile.click({ force: true });
|
|
1628
|
+
}
|
|
1506
1629
|
await p.waitForTimeout(500 + Math.random() * 400);
|
|
1507
1630
|
const isRecaptcha = provider === 'recaptcha';
|
|
1508
1631
|
const selectedClass = isRecaptcha ? '.rc-imageselect-dynamic-selected' : '.task-image.selected, .task .selected';
|
|
@@ -1561,7 +1684,7 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
1561
1684
|
if (await verifyBtn.count() === 0) {
|
|
1562
1685
|
return err('No verify button found', 'Use "captcha-grid" to analyze the challenge first');
|
|
1563
1686
|
}
|
|
1564
|
-
await verifyBtn
|
|
1687
|
+
await humanClick(verifyBtn, p);
|
|
1565
1688
|
await p.waitForTimeout(3000);
|
|
1566
1689
|
const screenshotPath = join(homedir(), '.aurix-captcha-verify-result.png');
|
|
1567
1690
|
const errorText = await challengeFrame.locator('.rc-imageselect-incorrect-response, .error-message, .incorrect').count();
|
|
@@ -2151,8 +2274,8 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
2151
2274
|
const sourceBox = await sourceEl.boundingBox();
|
|
2152
2275
|
if (!sourceBox)
|
|
2153
2276
|
return err(`Source element "${target}" not found or not visible`);
|
|
2154
|
-
const startX = sourceBox.x + sourceBox.width
|
|
2155
|
-
const startY = sourceBox.y + sourceBox.height
|
|
2277
|
+
const startX = sourceBox.x + sourceBox.width * (0.3 + Math.random() * 0.4);
|
|
2278
|
+
const startY = sourceBox.y + sourceBox.height * (0.3 + Math.random() * 0.4);
|
|
2156
2279
|
let endX, endY;
|
|
2157
2280
|
const coords = value.split(',').map(s => parseInt(s.trim()));
|
|
2158
2281
|
if (coords.length === 2 && !isNaN(coords[0]) && !isNaN(coords[1])) {
|
|
@@ -2164,28 +2287,52 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
2164
2287
|
const targetBox = await targetEl.boundingBox();
|
|
2165
2288
|
if (!targetBox)
|
|
2166
2289
|
return err(`Target element "${value}" not found or not visible`);
|
|
2167
|
-
endX = targetBox.x + targetBox.width
|
|
2168
|
-
endY = targetBox.y + targetBox.height
|
|
2290
|
+
endX = targetBox.x + targetBox.width * (0.3 + Math.random() * 0.4);
|
|
2291
|
+
endY = targetBox.y + targetBox.height * (0.3 + Math.random() * 0.4);
|
|
2169
2292
|
}
|
|
2170
|
-
await p
|
|
2171
|
-
await
|
|
2293
|
+
await warmupBehavior(p);
|
|
2294
|
+
await humanMove(startX, startY, p);
|
|
2295
|
+
await p.waitForTimeout(150 + Math.random() * 250);
|
|
2172
2296
|
await p.mouse.down();
|
|
2173
|
-
await p.waitForTimeout(200 + Math.random() *
|
|
2174
|
-
const
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
const
|
|
2181
|
-
const
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2297
|
+
await p.waitForTimeout(200 + Math.random() * 300);
|
|
2298
|
+
const distance = Math.sqrt((endX - startX) ** 2 + (endY - startY) ** 2);
|
|
2299
|
+
const numControls = distance > 200 ? 3 : 2;
|
|
2300
|
+
const dragPoints = [[startX, startY]];
|
|
2301
|
+
for (let i = 0; i < numControls; i++) {
|
|
2302
|
+
const frac = (i + 1) / (numControls + 1);
|
|
2303
|
+
const perpX = -(endY - startY) / distance;
|
|
2304
|
+
const perpY = (endX - startX) / distance;
|
|
2305
|
+
const offset = (Math.random() - 0.5) * Math.min(distance * 0.15, 40);
|
|
2306
|
+
const cx = startX + (endX - startX) * frac + perpX * offset;
|
|
2307
|
+
const cy = startY + (endY - startY) * frac + perpY * offset;
|
|
2308
|
+
dragPoints.push([cx, cy]);
|
|
2309
|
+
}
|
|
2310
|
+
dragPoints.push([endX, endY]);
|
|
2311
|
+
const dragSteps = 25 + Math.floor(Math.random() * 20);
|
|
2312
|
+
for (let step = 0; step <= dragSteps; step++) {
|
|
2313
|
+
const rawT = step / dragSteps;
|
|
2314
|
+
const t = easeInOut(rawT);
|
|
2315
|
+
const [px, py] = bezierPoint(t, dragPoints);
|
|
2316
|
+
const tremor = Math.sin(step * 0.35 + Math.random() * 0.5) * 0.5;
|
|
2317
|
+
const tremorY = Math.cos(step * 0.3 + Math.random() * 0.5) * 0.4;
|
|
2318
|
+
await p.mouse.move(px + tremor, py + tremorY);
|
|
2319
|
+
const speedFactor = 1 - Math.abs(rawT - 0.5) * 2;
|
|
2320
|
+
const delay = 10 + Math.random() * 15 + speedFactor * 8;
|
|
2321
|
+
await p.waitForTimeout(delay);
|
|
2322
|
+
}
|
|
2323
|
+
if (Math.random() > 0.5) {
|
|
2324
|
+
const overX = endX + (Math.random() - 0.5) * 6;
|
|
2325
|
+
const overY = endY + (Math.random() - 0.5) * 6;
|
|
2326
|
+
await p.mouse.move(overX, overY);
|
|
2327
|
+
await p.waitForTimeout(40 + Math.random() * 60);
|
|
2328
|
+
await p.mouse.move(endX, endY);
|
|
2329
|
+
await p.waitForTimeout(30 + Math.random() * 50);
|
|
2330
|
+
}
|
|
2331
|
+
await p.waitForTimeout(80 + Math.random() * 150);
|
|
2332
|
+
await p.mouse.move(endX + (Math.random() - 0.5) * 2, endY - 1 - Math.random());
|
|
2333
|
+
await p.waitForTimeout(30 + Math.random() * 40);
|
|
2187
2334
|
await p.mouse.up();
|
|
2188
|
-
await p.waitForTimeout(
|
|
2335
|
+
await p.waitForTimeout(400 + Math.random() * 300);
|
|
2189
2336
|
const screenshotPath = join(homedir(), '.aurix-drag-result.png');
|
|
2190
2337
|
await p.screenshot({ path: screenshotPath });
|
|
2191
2338
|
return ok(`Dragged "${target}" to (${Math.round(endX)}, ${Math.round(endY)})`, {
|
|
@@ -2203,29 +2350,26 @@ The browser profile persists at ~/.aurix-browser-profile — if the user is logg
|
|
|
2203
2350
|
const p = await ensureBrowser();
|
|
2204
2351
|
if (!target)
|
|
2205
2352
|
return err('hold-click requires a target element');
|
|
2206
|
-
const
|
|
2353
|
+
const baseDuration = parseInt(value) || 5000;
|
|
2354
|
+
const duration = baseDuration + Math.floor(Math.random() * 3000) - 1000;
|
|
2207
2355
|
try {
|
|
2208
2356
|
const el = p.locator(target).first();
|
|
2209
2357
|
const box = await el.boundingBox();
|
|
2210
2358
|
if (!box)
|
|
2211
2359
|
return err(`Element "${target}" not found or not visible`);
|
|
2212
|
-
const x = box.x + box.width / 2;
|
|
2213
|
-
const y = box.y + box.height / 2;
|
|
2214
|
-
|
|
2215
|
-
await p
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
await p.waitForTimeout(80 + Math.random() * 40);
|
|
2223
|
-
}
|
|
2224
|
-
await p.mouse.up();
|
|
2225
|
-
await p.waitForTimeout(500);
|
|
2360
|
+
const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
|
|
2361
|
+
const y = box.y + box.height / 2 + (Math.random() - 0.5) * box.height * 0.3;
|
|
2362
|
+
// Pre-interaction warmup: move mouse around naturally
|
|
2363
|
+
await warmupBehavior(p);
|
|
2364
|
+
// Bezier curve approach to target
|
|
2365
|
+
await humanMove(x, y, p);
|
|
2366
|
+
await p.waitForTimeout(100 + Math.random() * 200);
|
|
2367
|
+
// Human-like hold with breathing movements
|
|
2368
|
+
await humanHold(x, y, Math.max(2000, duration), p);
|
|
2369
|
+
await p.waitForTimeout(300 + Math.random() * 400);
|
|
2226
2370
|
const screenshotPath = join(homedir(), '.aurix-hold-result.png');
|
|
2227
2371
|
await p.screenshot({ path: screenshotPath });
|
|
2228
|
-
return ok(`Held click on "${target}" for ${duration}ms`, {
|
|
2372
|
+
return ok(`Held click on "${target}" for ${Math.round(duration)}ms (human-like)`, {
|
|
2229
2373
|
position: `(${Math.round(x)}, ${Math.round(y)})`,
|
|
2230
2374
|
screenshot: screenshotPath,
|
|
2231
2375
|
});
|