xhs-operator 1.0.0-beta.1
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 +100 -0
- package/dist/actions/account.d.ts +59 -0
- package/dist/actions/account.d.ts.map +1 -0
- package/dist/actions/account.js +142 -0
- package/dist/actions/account.js.map +1 -0
- package/dist/actions/interact.d.ts +37 -0
- package/dist/actions/interact.d.ts.map +1 -0
- package/dist/actions/interact.js +205 -0
- package/dist/actions/interact.js.map +1 -0
- package/dist/actions/publish.d.ts +18 -0
- package/dist/actions/publish.d.ts.map +1 -0
- package/dist/actions/publish.js +135 -0
- package/dist/actions/publish.js.map +1 -0
- package/dist/actions/scrape.d.ts +21 -0
- package/dist/actions/scrape.d.ts.map +1 -0
- package/dist/actions/scrape.js +145 -0
- package/dist/actions/scrape.js.map +1 -0
- package/dist/agents/copywriter.d.ts +21 -0
- package/dist/agents/copywriter.d.ts.map +1 -0
- package/dist/agents/copywriter.js +115 -0
- package/dist/agents/copywriter.js.map +1 -0
- package/dist/agents/image-composer.d.ts +26 -0
- package/dist/agents/image-composer.d.ts.map +1 -0
- package/dist/agents/image-composer.js +103 -0
- package/dist/agents/image-composer.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +204 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +61 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +182 -0
- package/dist/plugin.js.map +1 -0
- package/dist/risk/behavior-humanizer.d.ts +30 -0
- package/dist/risk/behavior-humanizer.d.ts.map +1 -0
- package/dist/risk/behavior-humanizer.js +105 -0
- package/dist/risk/behavior-humanizer.js.map +1 -0
- package/dist/risk/fingerprint-guard.d.ts +23 -0
- package/dist/risk/fingerprint-guard.d.ts.map +1 -0
- package/dist/risk/fingerprint-guard.js +127 -0
- package/dist/risk/fingerprint-guard.js.map +1 -0
- package/dist/risk/rate-guard.d.ts +33 -0
- package/dist/risk/rate-guard.d.ts.map +1 -0
- package/dist/risk/rate-guard.js +104 -0
- package/dist/risk/rate-guard.js.map +1 -0
- package/dist/runtime/standalone.d.ts +15 -0
- package/dist/runtime/standalone.d.ts.map +1 -0
- package/dist/runtime/standalone.js +199 -0
- package/dist/runtime/standalone.js.map +1 -0
- package/dist/scheduler.d.ts +42 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +139 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/storage/database.d.ts +23 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +142 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/kv-store.d.ts +13 -0
- package/dist/storage/kv-store.d.ts.map +1 -0
- package/dist/storage/kv-store.js +60 -0
- package/dist/storage/kv-store.js.map +1 -0
- package/dist/types/index.d.ts +320 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/helpers.d.ts +63 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +115 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/workflows/content-campaign.d.ts +58 -0
- package/dist/workflows/content-campaign.d.ts.map +1 -0
- package/dist/workflows/content-campaign.js +155 -0
- package/dist/workflows/content-campaign.js.map +1 -0
- package/dist/workflows/daily-operate.d.ts +36 -0
- package/dist/workflows/daily-operate.d.ts.map +1 -0
- package/dist/workflows/daily-operate.js +222 -0
- package/dist/workflows/daily-operate.js.map +1 -0
- package/manifest.json +29 -0
- package/package.json +66 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Page, BrowserFingerprint } from '../types/index.js';
|
|
2
|
+
import type { AppDatabase } from '../storage/database.js';
|
|
3
|
+
export declare class FingerprintGuard {
|
|
4
|
+
private db;
|
|
5
|
+
constructor(db: AppDatabase);
|
|
6
|
+
/**
|
|
7
|
+
* Generate a stable fingerprint for an account (created once, reused always).
|
|
8
|
+
*/
|
|
9
|
+
generateStableFingerprint(): BrowserFingerprint;
|
|
10
|
+
/**
|
|
11
|
+
* Get or create a persistent fingerprint for the given account.
|
|
12
|
+
*/
|
|
13
|
+
getOrCreateFingerprint(accountId: string): BrowserFingerprint;
|
|
14
|
+
/**
|
|
15
|
+
* Apply fingerprint overrides to a browser page.
|
|
16
|
+
*/
|
|
17
|
+
applyFingerprint(page: Page, accountId: string): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Build the JavaScript to inject for fingerprint spoofing.
|
|
20
|
+
*/
|
|
21
|
+
private buildFingerprintScript;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=fingerprint-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint-guard.d.ts","sourceRoot":"","sources":["../../src/risk/fingerprint-guard.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAY,MAAM,mBAAmB,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAmC1D,qBAAa,gBAAgB;IACf,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,WAAW;IAEnC;;OAEG;IACH,yBAAyB,IAAI,kBAAkB;IAc/C;;OAEG;IACH,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB;IAS7D;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAepE;;OAEG;IACH,OAAO,CAAC,sBAAsB;CA6C/B"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Fingerprint Guard — Browser fingerprint management
|
|
3
|
+
// ============================================================
|
|
4
|
+
import { randomBetween } from '../utils/helpers.js';
|
|
5
|
+
/** Common realistic user agents */
|
|
6
|
+
const USER_AGENTS = [
|
|
7
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
8
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
9
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36',
|
|
10
|
+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15',
|
|
11
|
+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
12
|
+
];
|
|
13
|
+
const VIEWPORTS = [
|
|
14
|
+
{ width: 1920, height: 1080 },
|
|
15
|
+
{ width: 1440, height: 900 },
|
|
16
|
+
{ width: 1536, height: 864 },
|
|
17
|
+
{ width: 1366, height: 768 },
|
|
18
|
+
{ width: 2560, height: 1440 },
|
|
19
|
+
];
|
|
20
|
+
const WEBGL_RENDERERS = [
|
|
21
|
+
'ANGLE (Intel, Intel(R) UHD Graphics 630, OpenGL 4.5)',
|
|
22
|
+
'ANGLE (NVIDIA, NVIDIA GeForce GTX 1060, OpenGL 4.5)',
|
|
23
|
+
'ANGLE (AMD, AMD Radeon RX 580, OpenGL 4.5)',
|
|
24
|
+
'ANGLE (Intel, Intel(R) Iris(TM) Plus Graphics 640, OpenGL 4.1)',
|
|
25
|
+
'ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)',
|
|
26
|
+
];
|
|
27
|
+
const FONTS = [
|
|
28
|
+
['Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia'],
|
|
29
|
+
['Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia', 'Trebuchet MS'],
|
|
30
|
+
['Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia', 'Impact', 'Comic Sans MS'],
|
|
31
|
+
['Arial', 'Helvetica', 'Times New Roman', 'Courier New', 'Verdana', 'Georgia', 'Lucida Console'],
|
|
32
|
+
];
|
|
33
|
+
export class FingerprintGuard {
|
|
34
|
+
db;
|
|
35
|
+
constructor(db) {
|
|
36
|
+
this.db = db;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generate a stable fingerprint for an account (created once, reused always).
|
|
40
|
+
*/
|
|
41
|
+
generateStableFingerprint() {
|
|
42
|
+
const pick = (arr) => arr[randomBetween(0, arr.length - 1)];
|
|
43
|
+
return {
|
|
44
|
+
userAgent: pick(USER_AGENTS),
|
|
45
|
+
viewport: pick(VIEWPORTS),
|
|
46
|
+
timezone: 'Asia/Shanghai',
|
|
47
|
+
language: 'zh-CN,zh;q=0.9,en;q=0.8',
|
|
48
|
+
webglRenderer: pick(WEBGL_RENDERERS),
|
|
49
|
+
canvas: Math.random() < 0.7 ? 'noise' : 'block',
|
|
50
|
+
fonts: pick(FONTS),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get or create a persistent fingerprint for the given account.
|
|
55
|
+
*/
|
|
56
|
+
getOrCreateFingerprint(accountId) {
|
|
57
|
+
const existing = this.db.getFingerprint(accountId);
|
|
58
|
+
if (existing)
|
|
59
|
+
return existing;
|
|
60
|
+
const fp = this.generateStableFingerprint();
|
|
61
|
+
this.db.saveFingerprint(accountId, fp);
|
|
62
|
+
return fp;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Apply fingerprint overrides to a browser page.
|
|
66
|
+
*/
|
|
67
|
+
async applyFingerprint(page, accountId) {
|
|
68
|
+
const fp = this.getOrCreateFingerprint(accountId);
|
|
69
|
+
// Inject fingerprint override script before page loads
|
|
70
|
+
await page.evaluateOnNewDocument(this.buildFingerprintScript(fp));
|
|
71
|
+
// Set viewport
|
|
72
|
+
await page.setViewport(fp.viewport);
|
|
73
|
+
// Set language header
|
|
74
|
+
await page.setExtraHTTPHeaders({
|
|
75
|
+
'Accept-Language': fp.language,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Build the JavaScript to inject for fingerprint spoofing.
|
|
80
|
+
*/
|
|
81
|
+
buildFingerprintScript(fp) {
|
|
82
|
+
return `
|
|
83
|
+
(() => {
|
|
84
|
+
// Override navigator.userAgent
|
|
85
|
+
Object.defineProperty(navigator, 'userAgent', { get: () => ${JSON.stringify(fp.userAgent)} });
|
|
86
|
+
Object.defineProperty(navigator, 'language', { get: () => 'zh-CN' });
|
|
87
|
+
Object.defineProperty(navigator, 'languages', { get: () => ['zh-CN', 'zh', 'en'] });
|
|
88
|
+
|
|
89
|
+
// Override WebGL renderer
|
|
90
|
+
const getParameterOrig = WebGLRenderingContext.prototype.getParameter;
|
|
91
|
+
WebGLRenderingContext.prototype.getParameter = function(param) {
|
|
92
|
+
if (param === 0x1F01) return ${JSON.stringify(fp.webglRenderer)}; // RENDERER
|
|
93
|
+
if (param === 0x1F00) return 'Google Inc. (${fp.webglRenderer.split(',')[0]?.replace('ANGLE (', '') || 'Intel'})'; // VENDOR
|
|
94
|
+
return getParameterOrig.call(this, param);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Canvas fingerprint ${fp.canvas === 'noise' ? 'noise injection' : 'blocking'}
|
|
98
|
+
${fp.canvas === 'noise' ? `
|
|
99
|
+
const origToDataURL = HTMLCanvasElement.prototype.toDataURL;
|
|
100
|
+
HTMLCanvasElement.prototype.toDataURL = function(...args) {
|
|
101
|
+
const ctx = this.getContext('2d');
|
|
102
|
+
if (ctx) {
|
|
103
|
+
const imageData = ctx.getImageData(0, 0, this.width, this.height);
|
|
104
|
+
for (let i = 0; i < imageData.data.length; i += 4) {
|
|
105
|
+
imageData.data[i] = imageData.data[i] ^ (Math.random() < 0.01 ? 1 : 0);
|
|
106
|
+
}
|
|
107
|
+
ctx.putImageData(imageData, 0, 0);
|
|
108
|
+
}
|
|
109
|
+
return origToDataURL.apply(this, args);
|
|
110
|
+
};` : `
|
|
111
|
+
HTMLCanvasElement.prototype.toDataURL = function() { return ''; };
|
|
112
|
+
HTMLCanvasElement.prototype.toBlob = function(cb) { cb(null); };
|
|
113
|
+
`}
|
|
114
|
+
|
|
115
|
+
// Timezone override
|
|
116
|
+
const DateOrig = Date;
|
|
117
|
+
const resolvedOptions = Intl.DateTimeFormat.prototype.resolvedOptions;
|
|
118
|
+
Intl.DateTimeFormat.prototype.resolvedOptions = function() {
|
|
119
|
+
const opts = resolvedOptions.call(this);
|
|
120
|
+
opts.timeZone = ${JSON.stringify(fp.timezone)};
|
|
121
|
+
return opts;
|
|
122
|
+
};
|
|
123
|
+
})();
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=fingerprint-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint-guard.js","sourceRoot":"","sources":["../../src/risk/fingerprint-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ActionType, DailyLimit, QuotaCheckResult } from '../types/index.js';
|
|
2
|
+
import type { AppDatabase } from '../storage/database.js';
|
|
3
|
+
export declare class RateGuard {
|
|
4
|
+
private db;
|
|
5
|
+
private circuitBreakers;
|
|
6
|
+
constructor(db: AppDatabase);
|
|
7
|
+
/**
|
|
8
|
+
* Check if an action is allowed for the given account.
|
|
9
|
+
*/
|
|
10
|
+
checkQuota(accountId: string, actionType: ActionType): QuotaCheckResult;
|
|
11
|
+
/**
|
|
12
|
+
* Record a successful action.
|
|
13
|
+
*/
|
|
14
|
+
recordAction(accountId: string, actionType: ActionType, targetId?: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* Record a failure for circuit breaker tracking.
|
|
17
|
+
*/
|
|
18
|
+
recordFailure(accountId: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Check if the circuit breaker is open (tripped) for an account.
|
|
21
|
+
*/
|
|
22
|
+
private isCircuitOpen;
|
|
23
|
+
private resetCircuitBreaker;
|
|
24
|
+
/**
|
|
25
|
+
* Get daily limits configuration (for external inspection).
|
|
26
|
+
*/
|
|
27
|
+
getDailyLimits(): Record<ActionType, DailyLimit>;
|
|
28
|
+
}
|
|
29
|
+
export declare class QuotaExceededError extends Error {
|
|
30
|
+
resetAt: Date;
|
|
31
|
+
constructor(resetAt: Date);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=rate-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-guard.d.ts","sourceRoot":"","sources":["../../src/risk/rate-guard.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAiB1D,qBAAa,SAAS;IAGR,OAAO,CAAC,EAAE;IAFtB,OAAO,CAAC,eAAe,CAAuE;gBAE1E,EAAE,EAAE,WAAW;IAEnC;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,gBAAgB;IAgCvE;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAKhF;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAWtC;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,mBAAmB;IAI3B;;OAEG;IACH,cAAc,IAAI,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC;CAGjD;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IACxB,OAAO,EAAE,IAAI;gBAAb,OAAO,EAAE,IAAI;CAIjC"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Rate Guard — Frequency limiting and circuit breaker
|
|
3
|
+
// ============================================================
|
|
4
|
+
/** Safe daily operation limits per account */
|
|
5
|
+
const DAILY_LIMITS = {
|
|
6
|
+
publish: { max: 3, minIntervalMin: 120 },
|
|
7
|
+
like: { max: 80, minIntervalSec: 15 },
|
|
8
|
+
comment: { max: 30, minIntervalSec: 60 },
|
|
9
|
+
follow: { max: 50, minIntervalSec: 30 },
|
|
10
|
+
collect: { max: 50, minIntervalSec: 20 },
|
|
11
|
+
};
|
|
12
|
+
/** Circuit breaker configuration */
|
|
13
|
+
const CIRCUIT_BREAKER = {
|
|
14
|
+
threshold: 3,
|
|
15
|
+
cooldownMinutes: 60,
|
|
16
|
+
};
|
|
17
|
+
export class RateGuard {
|
|
18
|
+
db;
|
|
19
|
+
circuitBreakers = new Map();
|
|
20
|
+
constructor(db) {
|
|
21
|
+
this.db = db;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if an action is allowed for the given account.
|
|
25
|
+
*/
|
|
26
|
+
checkQuota(accountId, actionType) {
|
|
27
|
+
// Check circuit breaker first
|
|
28
|
+
if (this.isCircuitOpen(accountId)) {
|
|
29
|
+
const breaker = this.circuitBreakers.get(accountId);
|
|
30
|
+
const resetAt = new Date(breaker.openedAt.getTime() + CIRCUIT_BREAKER.cooldownMinutes * 60 * 1000);
|
|
31
|
+
return { allowed: false, remaining: 0, resetAt };
|
|
32
|
+
}
|
|
33
|
+
const limit = DAILY_LIMITS[actionType];
|
|
34
|
+
const count = this.db.getInteractionCount(accountId, actionType, 24);
|
|
35
|
+
const remaining = Math.max(0, limit.max - count);
|
|
36
|
+
if (remaining <= 0) {
|
|
37
|
+
const resetAt = new Date();
|
|
38
|
+
resetAt.setHours(24, 0, 0, 0); // Reset at midnight
|
|
39
|
+
return { allowed: false, remaining: 0, resetAt };
|
|
40
|
+
}
|
|
41
|
+
// Check minimum interval
|
|
42
|
+
const lastAction = this.db.getLastInteractionTime(accountId, actionType);
|
|
43
|
+
if (lastAction) {
|
|
44
|
+
const elapsedSec = (Date.now() - lastAction.getTime()) / 1000;
|
|
45
|
+
const minInterval = limit.minIntervalSec ?? (limit.minIntervalMin ? limit.minIntervalMin * 60 : 0);
|
|
46
|
+
if (elapsedSec < minInterval) {
|
|
47
|
+
const resetAt = new Date(lastAction.getTime() + minInterval * 1000);
|
|
48
|
+
return { allowed: false, remaining, resetAt };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { allowed: true, remaining, resetAt: new Date() };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Record a successful action.
|
|
55
|
+
*/
|
|
56
|
+
recordAction(accountId, actionType, targetId) {
|
|
57
|
+
this.db.logInteraction(accountId, actionType, targetId);
|
|
58
|
+
this.resetCircuitBreaker(accountId);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Record a failure for circuit breaker tracking.
|
|
62
|
+
*/
|
|
63
|
+
recordFailure(accountId) {
|
|
64
|
+
const breaker = this.circuitBreakers.get(accountId) ?? { failures: 0, openedAt: null };
|
|
65
|
+
breaker.failures++;
|
|
66
|
+
if (breaker.failures >= CIRCUIT_BREAKER.threshold) {
|
|
67
|
+
breaker.openedAt = new Date();
|
|
68
|
+
}
|
|
69
|
+
this.circuitBreakers.set(accountId, breaker);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if the circuit breaker is open (tripped) for an account.
|
|
73
|
+
*/
|
|
74
|
+
isCircuitOpen(accountId) {
|
|
75
|
+
const breaker = this.circuitBreakers.get(accountId);
|
|
76
|
+
if (!breaker?.openedAt)
|
|
77
|
+
return false;
|
|
78
|
+
const elapsed = Date.now() - breaker.openedAt.getTime();
|
|
79
|
+
if (elapsed > CIRCUIT_BREAKER.cooldownMinutes * 60 * 1000) {
|
|
80
|
+
// Cooldown expired, reset
|
|
81
|
+
this.resetCircuitBreaker(accountId);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
resetCircuitBreaker(accountId) {
|
|
87
|
+
this.circuitBreakers.set(accountId, { failures: 0, openedAt: null });
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get daily limits configuration (for external inspection).
|
|
91
|
+
*/
|
|
92
|
+
getDailyLimits() {
|
|
93
|
+
return { ...DAILY_LIMITS };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export class QuotaExceededError extends Error {
|
|
97
|
+
resetAt;
|
|
98
|
+
constructor(resetAt) {
|
|
99
|
+
super(`Quota exceeded. Resets at ${resetAt.toISOString()}`);
|
|
100
|
+
this.resetAt = resetAt;
|
|
101
|
+
this.name = 'QuotaExceededError';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=rate-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-guard.js","sourceRoot":"","sources":["../../src/risk/rate-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { OpenClawRuntime } from '../types/index.js';
|
|
2
|
+
export interface StandaloneRuntimeOptions {
|
|
3
|
+
/** Anthropic API key. Falls back to ANTHROPIC_API_KEY env var. */
|
|
4
|
+
anthropicApiKey?: string;
|
|
5
|
+
/** Path to KV store database file. Defaults to ./data/runtime-kv.db */
|
|
6
|
+
kvDbPath?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create a standalone OpenClaw runtime backed by Playwright + Anthropic SDK.
|
|
10
|
+
* Use this when running outside the official OpenClaw framework.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createStandaloneRuntime(opts?: StandaloneRuntimeOptions): OpenClawRuntime & {
|
|
13
|
+
close: () => void;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=standalone.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../src/runtime/standalone.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EAahB,MAAM,mBAAmB,CAAC;AAsO3B,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,wBAA6B,GAAG,eAAe,GAAG;IAAE,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAUpH"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Standalone Runtime — OpenClaw runtime adapter using Playwright + Anthropic SDK
|
|
3
|
+
// Allows the plugin to run without the full OpenClaw framework.
|
|
4
|
+
// ============================================================
|
|
5
|
+
import { KVStore } from '../storage/kv-store.js';
|
|
6
|
+
// ─── Browser adapter (Playwright) ─────────────────────────────────────────────
|
|
7
|
+
class PlaywrightBrowser {
|
|
8
|
+
// Lazy-load Playwright to avoid hard dependency at import time
|
|
9
|
+
async getPlaywright() {
|
|
10
|
+
const { chromium } = await import('playwright');
|
|
11
|
+
return chromium;
|
|
12
|
+
}
|
|
13
|
+
async newPage(session) {
|
|
14
|
+
const chromium = await this.getPlaywright();
|
|
15
|
+
const launchOpts = {
|
|
16
|
+
headless: process.env['XHS_HEADLESS'] !== 'false',
|
|
17
|
+
};
|
|
18
|
+
if (session.proxy) {
|
|
19
|
+
launchOpts['proxy'] = {
|
|
20
|
+
server: `${session.proxy.protocol}://${session.proxy.host}:${session.proxy.port}`,
|
|
21
|
+
username: session.proxy.username,
|
|
22
|
+
password: session.proxy.password,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const browser = await chromium.launch(launchOpts);
|
|
26
|
+
const context = await browser.newContext({
|
|
27
|
+
storageState: session.cookieFile,
|
|
28
|
+
userAgent: session.fingerprint?.userAgent,
|
|
29
|
+
viewport: session.fingerprint?.viewport,
|
|
30
|
+
});
|
|
31
|
+
const pwPage = await context.newPage();
|
|
32
|
+
return new PlaywrightPage(pwPage, browser);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
class PlaywrightPage {
|
|
36
|
+
pw;
|
|
37
|
+
browser;
|
|
38
|
+
constructor(pw, browser) {
|
|
39
|
+
this.pw = pw;
|
|
40
|
+
this.browser = browser;
|
|
41
|
+
}
|
|
42
|
+
async navigate(url) {
|
|
43
|
+
await this.pw.goto(url, { waitUntil: 'domcontentloaded' });
|
|
44
|
+
}
|
|
45
|
+
async click(selector) {
|
|
46
|
+
await this.pw.click(selector);
|
|
47
|
+
}
|
|
48
|
+
async type(selector, text) {
|
|
49
|
+
await this.pw.fill(selector, text);
|
|
50
|
+
}
|
|
51
|
+
async waitForSelector(selector, opts) {
|
|
52
|
+
await this.pw.waitForSelector(selector, { timeout: opts?.timeout ?? 30000 });
|
|
53
|
+
}
|
|
54
|
+
async waitForNavigation(opts) {
|
|
55
|
+
await this.pw.waitForLoadState('domcontentloaded', { timeout: opts?.timeout ?? 30000 });
|
|
56
|
+
}
|
|
57
|
+
async evaluate(fn, ...args) {
|
|
58
|
+
if (typeof fn === 'string') {
|
|
59
|
+
return this.pw.evaluate(fn);
|
|
60
|
+
}
|
|
61
|
+
return this.pw.evaluate(fn, args);
|
|
62
|
+
}
|
|
63
|
+
async evaluateOnNewDocument(fn, ...args) {
|
|
64
|
+
const script = typeof fn === 'string' ? fn : `(${fn.toString()})(${args.map((a) => JSON.stringify(a)).join(',')})`;
|
|
65
|
+
await this.pw.addInitScript(script);
|
|
66
|
+
}
|
|
67
|
+
async screenshot(opts) {
|
|
68
|
+
return this.pw.screenshot(opts);
|
|
69
|
+
}
|
|
70
|
+
async setViewport(viewport) {
|
|
71
|
+
await this.pw.setViewportSize(viewport);
|
|
72
|
+
}
|
|
73
|
+
async setExtraHTTPHeaders(headers) {
|
|
74
|
+
await this.pw.setExtraHTTPHeaders(headers);
|
|
75
|
+
}
|
|
76
|
+
async mousePosition() {
|
|
77
|
+
// Playwright doesn't expose current mouse position; default to center
|
|
78
|
+
const size = this.pw.viewportSize() ?? { width: 800, height: 600 };
|
|
79
|
+
return { x: size.width / 2, y: size.height / 2 };
|
|
80
|
+
}
|
|
81
|
+
mouse = {
|
|
82
|
+
move: async (x, y) => {
|
|
83
|
+
await this.pw.mouse.move(x, y);
|
|
84
|
+
},
|
|
85
|
+
click: async (x, y) => {
|
|
86
|
+
await this.pw.mouse.click(x, y);
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
keyboard = {
|
|
90
|
+
type: async (text) => {
|
|
91
|
+
await this.pw.keyboard.type(text);
|
|
92
|
+
},
|
|
93
|
+
press: async (key) => {
|
|
94
|
+
await this.pw.keyboard.press(key);
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
async close() {
|
|
98
|
+
await this.pw.close();
|
|
99
|
+
await this.browser.close();
|
|
100
|
+
}
|
|
101
|
+
url() {
|
|
102
|
+
return this.pw.url();
|
|
103
|
+
}
|
|
104
|
+
async content() {
|
|
105
|
+
return this.pw.content();
|
|
106
|
+
}
|
|
107
|
+
async $(selector) {
|
|
108
|
+
const el = await this.pw.$(selector);
|
|
109
|
+
return el ? new PlaywrightElementHandle(el) : null;
|
|
110
|
+
}
|
|
111
|
+
async $$(selector) {
|
|
112
|
+
const els = await this.pw.$$(selector);
|
|
113
|
+
return els.map((el) => new PlaywrightElementHandle(el));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
class PlaywrightElementHandle {
|
|
117
|
+
el;
|
|
118
|
+
constructor(el) {
|
|
119
|
+
this.el = el;
|
|
120
|
+
}
|
|
121
|
+
async click() {
|
|
122
|
+
await this.el.click();
|
|
123
|
+
}
|
|
124
|
+
async type(text) {
|
|
125
|
+
await this.el.fill(text);
|
|
126
|
+
}
|
|
127
|
+
async textContent() {
|
|
128
|
+
return this.el.textContent();
|
|
129
|
+
}
|
|
130
|
+
async getAttribute(name) {
|
|
131
|
+
return this.el.getAttribute(name);
|
|
132
|
+
}
|
|
133
|
+
async boundingBox() {
|
|
134
|
+
return this.el.boundingBox();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ─── AI adapter (Anthropic SDK) ───────────────────────────────────────────────
|
|
138
|
+
class AnthropicAI {
|
|
139
|
+
clientPromise;
|
|
140
|
+
constructor(apiKey) {
|
|
141
|
+
this.clientPromise = import('@anthropic-ai/sdk').then(({ default: Anthropic }) => new Anthropic({ apiKey: apiKey ?? process.env['ANTHROPIC_API_KEY'] }));
|
|
142
|
+
}
|
|
143
|
+
async completion(opts) {
|
|
144
|
+
const client = await this.clientPromise;
|
|
145
|
+
const response = await client.messages.create({
|
|
146
|
+
model: opts.model || 'claude-sonnet-4-20250514',
|
|
147
|
+
max_tokens: 4096,
|
|
148
|
+
system: opts.system,
|
|
149
|
+
messages: [{ role: 'user', content: opts.prompt }],
|
|
150
|
+
});
|
|
151
|
+
const content = response.content[0];
|
|
152
|
+
return content?.type === 'text' ? content.text : '';
|
|
153
|
+
}
|
|
154
|
+
async imageGeneration(opts) {
|
|
155
|
+
// Claude API doesn't support image generation directly.
|
|
156
|
+
// Return a placeholder 1x1 PNG — in production integrate DALL-E / Flux.
|
|
157
|
+
console.warn('[ImageComposer] AI image generation not implemented in standalone runtime, returning placeholder.');
|
|
158
|
+
return generatePlaceholderPng();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function generatePlaceholderPng() {
|
|
162
|
+
// Minimal valid 1×1 white PNG (67 bytes)
|
|
163
|
+
return Buffer.from('89504e470d0a1a0a0000000d49484452000000010000000108060000001f15c489' +
|
|
164
|
+
'0000000a49444154789c6260000000020001e221bc330000000049454e44ae426082', 'hex');
|
|
165
|
+
}
|
|
166
|
+
// ─── Storage adapter (KV Store) ───────────────────────────────────────────────
|
|
167
|
+
class KVStorageAdapter {
|
|
168
|
+
kv;
|
|
169
|
+
constructor(dbPath) {
|
|
170
|
+
this.kv = new KVStore(dbPath);
|
|
171
|
+
}
|
|
172
|
+
async get(key) {
|
|
173
|
+
return this.kv.get(key);
|
|
174
|
+
}
|
|
175
|
+
async set(key, value) {
|
|
176
|
+
this.kv.set(key, value);
|
|
177
|
+
}
|
|
178
|
+
async getOrCreate(key, factory) {
|
|
179
|
+
return this.kv.getOrCreate(key, factory);
|
|
180
|
+
}
|
|
181
|
+
close() {
|
|
182
|
+
this.kv.close();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Create a standalone OpenClaw runtime backed by Playwright + Anthropic SDK.
|
|
187
|
+
* Use this when running outside the official OpenClaw framework.
|
|
188
|
+
*/
|
|
189
|
+
export function createStandaloneRuntime(opts = {}) {
|
|
190
|
+
const kvDbPath = opts.kvDbPath ?? './data/runtime-kv.db';
|
|
191
|
+
const storage = new KVStorageAdapter(kvDbPath);
|
|
192
|
+
return {
|
|
193
|
+
browser: new PlaywrightBrowser(),
|
|
194
|
+
ai: new AnthropicAI(opts.anthropicApiKey),
|
|
195
|
+
storage,
|
|
196
|
+
close: () => storage.close(),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=standalone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone.js","sourceRoot":"","sources":["../../src/runtime/standalone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { OpenClawRuntime, DailyConfig, AlertRule } from './types/index.js';
|
|
2
|
+
import type { AppDatabase } from './storage/database.js';
|
|
3
|
+
import { FingerprintGuard } from './risk/fingerprint-guard.js';
|
|
4
|
+
import { RateGuard } from './risk/rate-guard.js';
|
|
5
|
+
export declare class Scheduler {
|
|
6
|
+
private runtime;
|
|
7
|
+
private db;
|
|
8
|
+
private fingerprintGuard;
|
|
9
|
+
private rateGuard;
|
|
10
|
+
private alertRules;
|
|
11
|
+
private jobs;
|
|
12
|
+
private runningWorkers;
|
|
13
|
+
private dailyWorkflow;
|
|
14
|
+
private accountAction;
|
|
15
|
+
constructor(runtime: OpenClawRuntime, db: AppDatabase, fingerprintGuard: FingerprintGuard, rateGuard: RateGuard, alertRules?: AlertRule[]);
|
|
16
|
+
/**
|
|
17
|
+
* Start the scheduler with daily cron jobs.
|
|
18
|
+
*/
|
|
19
|
+
start(defaultConfig: DailyConfig): void;
|
|
20
|
+
/**
|
|
21
|
+
* Stop all scheduled jobs.
|
|
22
|
+
*/
|
|
23
|
+
stop(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Run a daily operation cycle for all active accounts.
|
|
26
|
+
*/
|
|
27
|
+
runDailyCycle(config: DailyConfig): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Run workflow for a single account with worker slot management.
|
|
30
|
+
*/
|
|
31
|
+
private runAccountWorkflow;
|
|
32
|
+
/**
|
|
33
|
+
* Run health check across all accounts.
|
|
34
|
+
*/
|
|
35
|
+
private runHealthCheck;
|
|
36
|
+
/**
|
|
37
|
+
* Handle alert based on error type.
|
|
38
|
+
*/
|
|
39
|
+
private handleAlert;
|
|
40
|
+
private chunk;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAW,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAWjD,qBAAa,SAAS;IAOlB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,UAAU;IAVpB,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,aAAa,CAAgB;gBAG3B,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,WAAW,EACf,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,SAAS,EACpB,UAAU,GAAE,SAAS,EAAwB;IAMvD;;OAEG;IACH,KAAK,CAAC,aAAa,EAAE,WAAW,GAAG,IAAI;IAoBvC;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBvD;;OAEG;YACW,kBAAkB;IAqBhC;;OAEG;YACW,cAAc;IAc5B;;OAEG;YACW,WAAW;IAWzB,OAAO,CAAC,KAAK;CAOd"}
|