gologin-agent-browser-cli 0.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.
Potentially problematic release.
This version of gologin-agent-browser-cli might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +220 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +352 -0
- package/dist/commands/check.d.ts +2 -0
- package/dist/commands/check.js +17 -0
- package/dist/commands/click.d.ts +2 -0
- package/dist/commands/click.js +17 -0
- package/dist/commands/close.d.ts +2 -0
- package/dist/commands/close.js +12 -0
- package/dist/commands/current.d.ts +2 -0
- package/dist/commands/current.js +9 -0
- package/dist/commands/dblclick.d.ts +2 -0
- package/dist/commands/dblclick.js +17 -0
- package/dist/commands/fill.d.ts +2 -0
- package/dist/commands/fill.js +18 -0
- package/dist/commands/find.d.ts +2 -0
- package/dist/commands/find.js +86 -0
- package/dist/commands/focus.d.ts +2 -0
- package/dist/commands/focus.js +17 -0
- package/dist/commands/get.d.ts +2 -0
- package/dist/commands/get.js +19 -0
- package/dist/commands/hover.d.ts +2 -0
- package/dist/commands/hover.js +17 -0
- package/dist/commands/open.d.ts +2 -0
- package/dist/commands/open.js +67 -0
- package/dist/commands/pdf.d.ts +2 -0
- package/dist/commands/pdf.js +18 -0
- package/dist/commands/press.d.ts +2 -0
- package/dist/commands/press.js +19 -0
- package/dist/commands/screenshot.d.ts +2 -0
- package/dist/commands/screenshot.js +20 -0
- package/dist/commands/scroll.d.ts +2 -0
- package/dist/commands/scroll.js +25 -0
- package/dist/commands/scrollIntoView.d.ts +2 -0
- package/dist/commands/scrollIntoView.js +17 -0
- package/dist/commands/select.d.ts +2 -0
- package/dist/commands/select.js +18 -0
- package/dist/commands/sessions.d.ts +2 -0
- package/dist/commands/sessions.js +15 -0
- package/dist/commands/shared.d.ts +3 -0
- package/dist/commands/shared.js +13 -0
- package/dist/commands/snapshot.d.ts +2 -0
- package/dist/commands/snapshot.js +16 -0
- package/dist/commands/type.d.ts +2 -0
- package/dist/commands/type.js +18 -0
- package/dist/commands/uncheck.d.ts +2 -0
- package/dist/commands/uncheck.js +17 -0
- package/dist/commands/upload.d.ts +2 -0
- package/dist/commands/upload.js +18 -0
- package/dist/commands/wait.d.ts +2 -0
- package/dist/commands/wait.js +41 -0
- package/dist/daemon/browser.d.ts +37 -0
- package/dist/daemon/browser.js +557 -0
- package/dist/daemon/refStore.d.ts +9 -0
- package/dist/daemon/refStore.js +26 -0
- package/dist/daemon/server.d.ts +1 -0
- package/dist/daemon/server.js +235 -0
- package/dist/daemon/sessionManager.d.ts +50 -0
- package/dist/daemon/sessionManager.js +512 -0
- package/dist/daemon/snapshot.d.ts +8 -0
- package/dist/daemon/snapshot.js +285 -0
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.js +58 -0
- package/dist/lib/errors.d.ts +12 -0
- package/dist/lib/errors.js +63 -0
- package/dist/lib/types.d.ts +301 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/utils.d.ts +27 -0
- package/dist/lib/utils.js +165 -0
- package/examples/agent-flow.sh +19 -0
- package/package.json +59 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import type { Browser, BrowserContext, Page } from "playwright";
|
|
2
|
+
export type TransportKind = "socket" | "http";
|
|
3
|
+
export type SnapshotKind = "heading" | "paragraph" | "link" | "button" | "input" | "checkbox" | "radio" | "textarea" | "select";
|
|
4
|
+
export interface AgentConfig {
|
|
5
|
+
token?: string;
|
|
6
|
+
defaultProfileId?: string;
|
|
7
|
+
connectBase: string;
|
|
8
|
+
daemonPort: number;
|
|
9
|
+
daemonHost: string;
|
|
10
|
+
socketPath: string;
|
|
11
|
+
configPath: string;
|
|
12
|
+
logPath: string;
|
|
13
|
+
navigationTimeoutMs: number;
|
|
14
|
+
actionTimeoutMs: number;
|
|
15
|
+
}
|
|
16
|
+
export interface ResolvedTransport {
|
|
17
|
+
kind: TransportKind;
|
|
18
|
+
socketPath?: string;
|
|
19
|
+
host?: string;
|
|
20
|
+
port?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface SessionSummary {
|
|
23
|
+
sessionId: string;
|
|
24
|
+
profileId?: string;
|
|
25
|
+
url: string;
|
|
26
|
+
active: boolean;
|
|
27
|
+
hasSnapshot: boolean;
|
|
28
|
+
staleSnapshot: boolean;
|
|
29
|
+
liveViewUrl?: string;
|
|
30
|
+
proxy?: ProxySummary;
|
|
31
|
+
createdAt?: string;
|
|
32
|
+
lastActivityAt?: string;
|
|
33
|
+
idleTimeoutMs?: number;
|
|
34
|
+
lastScreenshotPath?: string;
|
|
35
|
+
lastPdfPath?: string;
|
|
36
|
+
}
|
|
37
|
+
export type ProxyMode = "gologin" | "http" | "socks4" | "socks5";
|
|
38
|
+
export interface ProxyConfig {
|
|
39
|
+
mode: ProxyMode;
|
|
40
|
+
country?: string;
|
|
41
|
+
host?: string;
|
|
42
|
+
port?: number;
|
|
43
|
+
username?: string;
|
|
44
|
+
password?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface ProxySummary {
|
|
47
|
+
mode: string;
|
|
48
|
+
country?: string;
|
|
49
|
+
host?: string;
|
|
50
|
+
port?: number;
|
|
51
|
+
username?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface RefDescriptor {
|
|
54
|
+
ref: string;
|
|
55
|
+
kind: SnapshotKind;
|
|
56
|
+
tag: string;
|
|
57
|
+
role?: string;
|
|
58
|
+
text?: string;
|
|
59
|
+
accessibleName?: string;
|
|
60
|
+
ariaLabel?: string;
|
|
61
|
+
placeholder?: string;
|
|
62
|
+
inputType?: string;
|
|
63
|
+
name?: string;
|
|
64
|
+
href?: string;
|
|
65
|
+
nth?: number;
|
|
66
|
+
checked?: boolean;
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
selectedText?: string;
|
|
69
|
+
}
|
|
70
|
+
export interface SnapshotItem {
|
|
71
|
+
ref: string;
|
|
72
|
+
kind: SnapshotKind;
|
|
73
|
+
text: string;
|
|
74
|
+
role?: string;
|
|
75
|
+
flags?: string[];
|
|
76
|
+
}
|
|
77
|
+
export interface SnapshotResponse {
|
|
78
|
+
sessionId: string;
|
|
79
|
+
url: string;
|
|
80
|
+
items: SnapshotItem[];
|
|
81
|
+
}
|
|
82
|
+
export interface SessionRecord {
|
|
83
|
+
sessionId: string;
|
|
84
|
+
profileId?: string;
|
|
85
|
+
autoCreatedProfile: boolean;
|
|
86
|
+
connectUrl: string;
|
|
87
|
+
browser: Browser;
|
|
88
|
+
context: BrowserContext;
|
|
89
|
+
page: Page;
|
|
90
|
+
currentUrl: string;
|
|
91
|
+
hasSnapshot: boolean;
|
|
92
|
+
staleSnapshot: boolean;
|
|
93
|
+
liveViewUrl?: string;
|
|
94
|
+
proxy?: ProxySummary;
|
|
95
|
+
createdAt: string;
|
|
96
|
+
lastActivityAt: string;
|
|
97
|
+
idleTimeoutMs?: number;
|
|
98
|
+
lastScreenshotPath?: string;
|
|
99
|
+
lastPdfPath?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface OpenSessionRequest {
|
|
102
|
+
url: string;
|
|
103
|
+
profileId?: string;
|
|
104
|
+
sessionId?: string;
|
|
105
|
+
proxy?: ProxyConfig;
|
|
106
|
+
idleTimeoutMs?: number;
|
|
107
|
+
}
|
|
108
|
+
export interface OpenSessionResponse {
|
|
109
|
+
sessionId: string;
|
|
110
|
+
profileId?: string;
|
|
111
|
+
url: string;
|
|
112
|
+
liveViewUrl?: string;
|
|
113
|
+
proxy?: ProxySummary;
|
|
114
|
+
idleTimeoutMs?: number;
|
|
115
|
+
}
|
|
116
|
+
export interface TargetRequest {
|
|
117
|
+
target: string;
|
|
118
|
+
}
|
|
119
|
+
export interface ClickRequest extends TargetRequest {
|
|
120
|
+
}
|
|
121
|
+
export interface ActionResponse {
|
|
122
|
+
sessionId: string;
|
|
123
|
+
url: string;
|
|
124
|
+
staleSnapshot: boolean;
|
|
125
|
+
}
|
|
126
|
+
export interface ClickResponse extends ActionResponse {
|
|
127
|
+
}
|
|
128
|
+
export interface TypeRequest extends TargetRequest {
|
|
129
|
+
text: string;
|
|
130
|
+
}
|
|
131
|
+
export interface TypeResponse extends ActionResponse {
|
|
132
|
+
}
|
|
133
|
+
export interface FillRequest extends TargetRequest {
|
|
134
|
+
text: string;
|
|
135
|
+
}
|
|
136
|
+
export interface FillResponse extends ActionResponse {
|
|
137
|
+
}
|
|
138
|
+
export interface HoverRequest extends TargetRequest {
|
|
139
|
+
}
|
|
140
|
+
export interface HoverResponse extends ActionResponse {
|
|
141
|
+
}
|
|
142
|
+
export interface FocusRequest extends TargetRequest {
|
|
143
|
+
}
|
|
144
|
+
export interface FocusResponse extends ActionResponse {
|
|
145
|
+
}
|
|
146
|
+
export interface DoubleClickRequest extends TargetRequest {
|
|
147
|
+
}
|
|
148
|
+
export interface DoubleClickResponse extends ActionResponse {
|
|
149
|
+
}
|
|
150
|
+
export interface SelectRequest extends TargetRequest {
|
|
151
|
+
value: string;
|
|
152
|
+
}
|
|
153
|
+
export interface SelectResponse extends ActionResponse {
|
|
154
|
+
}
|
|
155
|
+
export interface CheckRequest extends TargetRequest {
|
|
156
|
+
}
|
|
157
|
+
export interface CheckResponse extends ActionResponse {
|
|
158
|
+
}
|
|
159
|
+
export interface UncheckRequest extends TargetRequest {
|
|
160
|
+
}
|
|
161
|
+
export interface UncheckResponse extends ActionResponse {
|
|
162
|
+
}
|
|
163
|
+
export interface PressRequest {
|
|
164
|
+
key: string;
|
|
165
|
+
target?: string;
|
|
166
|
+
}
|
|
167
|
+
export interface PressResponse extends ActionResponse {
|
|
168
|
+
}
|
|
169
|
+
export interface ScreenshotRequest {
|
|
170
|
+
path: string;
|
|
171
|
+
annotate?: boolean;
|
|
172
|
+
}
|
|
173
|
+
export interface ScreenshotResponse {
|
|
174
|
+
sessionId: string;
|
|
175
|
+
path: string;
|
|
176
|
+
url: string;
|
|
177
|
+
annotated?: boolean;
|
|
178
|
+
}
|
|
179
|
+
export interface CloseSessionResponse {
|
|
180
|
+
sessionId: string;
|
|
181
|
+
closed: true;
|
|
182
|
+
}
|
|
183
|
+
export interface SessionsResponse {
|
|
184
|
+
activeSessionId?: string;
|
|
185
|
+
sessions: SessionSummary[];
|
|
186
|
+
}
|
|
187
|
+
export type WaitLoadState = "load" | "domcontentloaded" | "networkidle";
|
|
188
|
+
export interface WaitRequest {
|
|
189
|
+
target?: string;
|
|
190
|
+
text?: string;
|
|
191
|
+
urlPattern?: string;
|
|
192
|
+
loadState?: WaitLoadState;
|
|
193
|
+
timeoutMs?: number;
|
|
194
|
+
}
|
|
195
|
+
export interface WaitResponse {
|
|
196
|
+
sessionId: string;
|
|
197
|
+
url: string;
|
|
198
|
+
waitedFor: string;
|
|
199
|
+
}
|
|
200
|
+
export type ScrollDirection = "up" | "down" | "left" | "right";
|
|
201
|
+
export interface ScrollRequest {
|
|
202
|
+
direction: ScrollDirection;
|
|
203
|
+
pixels?: number;
|
|
204
|
+
target?: string;
|
|
205
|
+
}
|
|
206
|
+
export interface ScrollResponse {
|
|
207
|
+
sessionId: string;
|
|
208
|
+
url: string;
|
|
209
|
+
target?: string;
|
|
210
|
+
direction: ScrollDirection;
|
|
211
|
+
pixels: number;
|
|
212
|
+
}
|
|
213
|
+
export interface ScrollIntoViewRequest extends TargetRequest {
|
|
214
|
+
}
|
|
215
|
+
export interface ScrollIntoViewResponse extends ActionResponse {
|
|
216
|
+
}
|
|
217
|
+
export interface UploadRequest extends TargetRequest {
|
|
218
|
+
files: string[];
|
|
219
|
+
}
|
|
220
|
+
export interface UploadResponse extends ActionResponse {
|
|
221
|
+
files: string[];
|
|
222
|
+
}
|
|
223
|
+
export interface PdfRequest {
|
|
224
|
+
path: string;
|
|
225
|
+
}
|
|
226
|
+
export interface PdfResponse {
|
|
227
|
+
sessionId: string;
|
|
228
|
+
path: string;
|
|
229
|
+
url: string;
|
|
230
|
+
}
|
|
231
|
+
export type GetKind = "text" | "value" | "html" | "title" | "url";
|
|
232
|
+
export interface GetRequest {
|
|
233
|
+
kind: GetKind;
|
|
234
|
+
target?: string;
|
|
235
|
+
}
|
|
236
|
+
export interface GetResponse {
|
|
237
|
+
sessionId: string;
|
|
238
|
+
url: string;
|
|
239
|
+
value: string;
|
|
240
|
+
}
|
|
241
|
+
export type SemanticLocatorStrategy = "role" | "text" | "label" | "placeholder" | "first" | "last" | "nth";
|
|
242
|
+
export interface SemanticLocatorQuery {
|
|
243
|
+
strategy: SemanticLocatorStrategy;
|
|
244
|
+
role?: string;
|
|
245
|
+
name?: string;
|
|
246
|
+
text?: string;
|
|
247
|
+
label?: string;
|
|
248
|
+
placeholder?: string;
|
|
249
|
+
selector?: string;
|
|
250
|
+
nth?: number;
|
|
251
|
+
exact?: boolean;
|
|
252
|
+
}
|
|
253
|
+
export type SemanticFindAction = "click" | "fill" | "type" | "hover" | "text";
|
|
254
|
+
export interface FindRequest {
|
|
255
|
+
locator: SemanticLocatorQuery;
|
|
256
|
+
action: SemanticFindAction;
|
|
257
|
+
value?: string;
|
|
258
|
+
}
|
|
259
|
+
export interface FindResponse extends ActionResponse {
|
|
260
|
+
value?: string;
|
|
261
|
+
}
|
|
262
|
+
export interface HealthResponse {
|
|
263
|
+
ok: true;
|
|
264
|
+
pid: number;
|
|
265
|
+
transports: TransportKind[];
|
|
266
|
+
}
|
|
267
|
+
export interface DaemonErrorPayload {
|
|
268
|
+
code: string;
|
|
269
|
+
message: string;
|
|
270
|
+
status: number;
|
|
271
|
+
details?: Record<string, unknown>;
|
|
272
|
+
}
|
|
273
|
+
export interface SnapshotBuildResult {
|
|
274
|
+
items: SnapshotItem[];
|
|
275
|
+
refs: RefDescriptor[];
|
|
276
|
+
}
|
|
277
|
+
export interface RawSnapshotCandidate {
|
|
278
|
+
kind: SnapshotKind;
|
|
279
|
+
tag: string;
|
|
280
|
+
role?: string;
|
|
281
|
+
text?: string;
|
|
282
|
+
accessibleName?: string;
|
|
283
|
+
ariaLabel?: string;
|
|
284
|
+
placeholder?: string;
|
|
285
|
+
inputType?: string;
|
|
286
|
+
name?: string;
|
|
287
|
+
href?: string;
|
|
288
|
+
checked?: boolean;
|
|
289
|
+
disabled?: boolean;
|
|
290
|
+
selectedText?: string;
|
|
291
|
+
}
|
|
292
|
+
export interface DaemonClient {
|
|
293
|
+
transport: ResolvedTransport;
|
|
294
|
+
request<TResponse>(method: string, path: string, body?: unknown): Promise<TResponse>;
|
|
295
|
+
}
|
|
296
|
+
export interface CommandContext {
|
|
297
|
+
client: DaemonClient;
|
|
298
|
+
stdout: NodeJS.WriteStream;
|
|
299
|
+
stderr: NodeJS.WriteStream;
|
|
300
|
+
cwd: string;
|
|
301
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import type { DaemonErrorPayload, ProxySummary, RefDescriptor, ResolvedTransport, SessionSummary, SnapshotItem } from "./types";
|
|
3
|
+
export type ParsedArgs = {
|
|
4
|
+
positional: string[];
|
|
5
|
+
flags: Record<string, string | boolean>;
|
|
6
|
+
};
|
|
7
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
8
|
+
export declare function getFlagString(parsed: ParsedArgs, name: string): string | undefined;
|
|
9
|
+
export declare function getFlagBoolean(parsed: ParsedArgs, name: string): boolean;
|
|
10
|
+
export declare function generateSessionId(existingIds: Iterable<string>): string;
|
|
11
|
+
export declare function ensureAbsolutePath(baseDir: string, targetPath: string): string;
|
|
12
|
+
export declare function isRefTarget(target: string): boolean;
|
|
13
|
+
export declare function isNumericToken(token: string): boolean;
|
|
14
|
+
export declare function formatSnapshotItem(item: SnapshotItem): string;
|
|
15
|
+
export declare function formatProxyLabel(proxy?: ProxySummary): string | undefined;
|
|
16
|
+
export declare function formatSessionLine(session: SessionSummary): string;
|
|
17
|
+
export declare function formatCurrentLine(session: SessionSummary): string;
|
|
18
|
+
export declare function writeJsonResponse(response: http.ServerResponse, statusCode: number, payload: unknown): void;
|
|
19
|
+
export declare function readJsonBody(request: http.IncomingMessage): Promise<unknown>;
|
|
20
|
+
export declare function appendLog(logPath: string, line: string): void;
|
|
21
|
+
export declare function buildRefDisplayText(descriptor: RefDescriptor): string;
|
|
22
|
+
export declare function makeTransportLabel(transport: ResolvedTransport): string;
|
|
23
|
+
export declare function isDaemonErrorResponse(payload: unknown): payload is DaemonErrorPayload & {
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
status: number;
|
|
27
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseArgs = parseArgs;
|
|
7
|
+
exports.getFlagString = getFlagString;
|
|
8
|
+
exports.getFlagBoolean = getFlagBoolean;
|
|
9
|
+
exports.generateSessionId = generateSessionId;
|
|
10
|
+
exports.ensureAbsolutePath = ensureAbsolutePath;
|
|
11
|
+
exports.isRefTarget = isRefTarget;
|
|
12
|
+
exports.isNumericToken = isNumericToken;
|
|
13
|
+
exports.formatSnapshotItem = formatSnapshotItem;
|
|
14
|
+
exports.formatProxyLabel = formatProxyLabel;
|
|
15
|
+
exports.formatSessionLine = formatSessionLine;
|
|
16
|
+
exports.formatCurrentLine = formatCurrentLine;
|
|
17
|
+
exports.writeJsonResponse = writeJsonResponse;
|
|
18
|
+
exports.readJsonBody = readJsonBody;
|
|
19
|
+
exports.appendLog = appendLog;
|
|
20
|
+
exports.buildRefDisplayText = buildRefDisplayText;
|
|
21
|
+
exports.makeTransportLabel = makeTransportLabel;
|
|
22
|
+
exports.isDaemonErrorResponse = isDaemonErrorResponse;
|
|
23
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
24
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
25
|
+
const errors_1 = require("./errors");
|
|
26
|
+
function parseArgs(argv) {
|
|
27
|
+
const positional = [];
|
|
28
|
+
const flags = {};
|
|
29
|
+
const booleanFlags = new Set(["interactive", "exact", "annotate"]);
|
|
30
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
31
|
+
const token = argv[index];
|
|
32
|
+
if (token === "-i") {
|
|
33
|
+
flags.interactive = true;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (!token.startsWith("--")) {
|
|
37
|
+
positional.push(token);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const flagName = token.slice(2);
|
|
41
|
+
if (booleanFlags.has(flagName)) {
|
|
42
|
+
flags[flagName] = true;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const next = argv[index + 1];
|
|
46
|
+
if (!next || next.startsWith("--")) {
|
|
47
|
+
throw new errors_1.AppError("BAD_REQUEST", `Missing value for ${token}`, 400);
|
|
48
|
+
}
|
|
49
|
+
flags[flagName] = next;
|
|
50
|
+
index += 1;
|
|
51
|
+
}
|
|
52
|
+
return { positional, flags };
|
|
53
|
+
}
|
|
54
|
+
function getFlagString(parsed, name) {
|
|
55
|
+
const value = parsed.flags[name];
|
|
56
|
+
return typeof value === "string" ? value : undefined;
|
|
57
|
+
}
|
|
58
|
+
function getFlagBoolean(parsed, name) {
|
|
59
|
+
return parsed.flags[name] === true;
|
|
60
|
+
}
|
|
61
|
+
function generateSessionId(existingIds) {
|
|
62
|
+
const existing = new Set(existingIds);
|
|
63
|
+
let counter = 1;
|
|
64
|
+
while (existing.has(`s${counter}`)) {
|
|
65
|
+
counter += 1;
|
|
66
|
+
}
|
|
67
|
+
return `s${counter}`;
|
|
68
|
+
}
|
|
69
|
+
function ensureAbsolutePath(baseDir, targetPath) {
|
|
70
|
+
return node_path_1.default.isAbsolute(targetPath) ? targetPath : node_path_1.default.resolve(baseDir, targetPath);
|
|
71
|
+
}
|
|
72
|
+
function isRefTarget(target) {
|
|
73
|
+
return /^@e\d+$/.test(target);
|
|
74
|
+
}
|
|
75
|
+
function isNumericToken(token) {
|
|
76
|
+
return /^-?\d+$/.test(token);
|
|
77
|
+
}
|
|
78
|
+
function formatSnapshotItem(item) {
|
|
79
|
+
const flags = item.flags && item.flags.length > 0 ? ` ${item.flags.map((flag) => `[${flag}]`).join(" ")}` : "";
|
|
80
|
+
return `- ${item.kind} "${item.text}"${flags} [ref=${item.ref}]`;
|
|
81
|
+
}
|
|
82
|
+
function formatProxyLabel(proxy) {
|
|
83
|
+
if (!proxy) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
if (proxy.mode === "none") {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
if (proxy.mode === "gologin") {
|
|
90
|
+
return proxy.country ? `gologin:${proxy.country}` : "gologin";
|
|
91
|
+
}
|
|
92
|
+
if (proxy.host && proxy.port) {
|
|
93
|
+
return `${proxy.mode}:${proxy.host}:${proxy.port}`;
|
|
94
|
+
}
|
|
95
|
+
return proxy.mode;
|
|
96
|
+
}
|
|
97
|
+
function formatSessionLine(session) {
|
|
98
|
+
const prefix = session.active ? "*" : "-";
|
|
99
|
+
const profile = session.profileId ? ` profile=${session.profileId}` : "";
|
|
100
|
+
const snapshotState = session.hasSnapshot ? (session.staleSnapshot ? "stale" : "fresh") : "none";
|
|
101
|
+
const proxy = formatProxyLabel(session.proxy);
|
|
102
|
+
const proxyToken = proxy ? ` proxy=${proxy}` : "";
|
|
103
|
+
const idleTimeout = session.idleTimeoutMs !== undefined ? ` idleTimeoutMs=${session.idleTimeoutMs}` : "";
|
|
104
|
+
const liveView = session.liveViewUrl ? ` liveview=${session.liveViewUrl}` : "";
|
|
105
|
+
const screenshot = session.lastScreenshotPath ? ` shot=${session.lastScreenshotPath}` : "";
|
|
106
|
+
const pdf = session.lastPdfPath ? ` pdf=${session.lastPdfPath}` : "";
|
|
107
|
+
return `${prefix} session=${session.sessionId}${profile} url=${session.url} snapshot=${snapshotState}${proxyToken}${idleTimeout}${liveView}${screenshot}${pdf}`;
|
|
108
|
+
}
|
|
109
|
+
function formatCurrentLine(session) {
|
|
110
|
+
const profile = session.profileId ? ` profile=${session.profileId}` : "";
|
|
111
|
+
const snapshotState = session.hasSnapshot ? (session.staleSnapshot ? "stale" : "fresh") : "none";
|
|
112
|
+
const proxy = formatProxyLabel(session.proxy);
|
|
113
|
+
const proxyToken = proxy ? ` proxy=${proxy}` : "";
|
|
114
|
+
const idleTimeout = session.idleTimeoutMs !== undefined ? ` idleTimeoutMs=${session.idleTimeoutMs}` : "";
|
|
115
|
+
const liveView = session.liveViewUrl ? ` liveview=${session.liveViewUrl}` : "";
|
|
116
|
+
const screenshot = session.lastScreenshotPath ? ` shot=${session.lastScreenshotPath}` : "";
|
|
117
|
+
const pdf = session.lastPdfPath ? ` pdf=${session.lastPdfPath}` : "";
|
|
118
|
+
return `session=${session.sessionId}${profile} url=${session.url} snapshot=${snapshotState}${proxyToken}${idleTimeout}${liveView}${screenshot}${pdf}`;
|
|
119
|
+
}
|
|
120
|
+
function writeJsonResponse(response, statusCode, payload) {
|
|
121
|
+
response.statusCode = statusCode;
|
|
122
|
+
response.setHeader("content-type", "application/json; charset=utf-8");
|
|
123
|
+
response.end(JSON.stringify(payload));
|
|
124
|
+
}
|
|
125
|
+
function readJsonBody(request) {
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
const chunks = [];
|
|
128
|
+
request.on("data", (chunk) => chunks.push(chunk));
|
|
129
|
+
request.on("end", () => {
|
|
130
|
+
if (chunks.length === 0) {
|
|
131
|
+
resolve(undefined);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString("utf8")));
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
reject(new errors_1.AppError("BAD_REQUEST", "Request body must be valid JSON", 400));
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
request.on("error", reject);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function appendLog(logPath, line) {
|
|
145
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(logPath), { recursive: true });
|
|
146
|
+
node_fs_1.default.appendFileSync(logPath, `${new Date().toISOString()} ${line}\n`, "utf8");
|
|
147
|
+
}
|
|
148
|
+
function buildRefDisplayText(descriptor) {
|
|
149
|
+
return descriptor.accessibleName ?? descriptor.text ?? descriptor.placeholder ?? descriptor.name ?? "";
|
|
150
|
+
}
|
|
151
|
+
function makeTransportLabel(transport) {
|
|
152
|
+
if (transport.kind === "socket") {
|
|
153
|
+
return `socket:${transport.socketPath}`;
|
|
154
|
+
}
|
|
155
|
+
return `http://${transport.host}:${transport.port}`;
|
|
156
|
+
}
|
|
157
|
+
function isDaemonErrorResponse(payload) {
|
|
158
|
+
if (!payload || typeof payload !== "object") {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const value = payload;
|
|
162
|
+
return (typeof value.code === "string" &&
|
|
163
|
+
typeof value.message === "string" &&
|
|
164
|
+
typeof value.status === "number");
|
|
165
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
if [[ -z "${GOLOGIN_TOKEN:-}" ]]; then
|
|
5
|
+
echo "GOLOGIN_TOKEN is required" >&2
|
|
6
|
+
exit 1
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
node dist/cli.js open https://example.com --idle-timeout-ms 300000
|
|
10
|
+
node dist/cli.js snapshot -i
|
|
11
|
+
node dist/cli.js current
|
|
12
|
+
node dist/cli.js get title
|
|
13
|
+
node dist/cli.js find text "Learn more" click
|
|
14
|
+
node dist/cli.js scroll down 400
|
|
15
|
+
node dist/cli.js wait 1000
|
|
16
|
+
node dist/cli.js sessions
|
|
17
|
+
node dist/cli.js pdf examples/example-page.pdf
|
|
18
|
+
node dist/cli.js screenshot examples/example-page.png --annotate
|
|
19
|
+
node dist/cli.js close
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gologin-agent-browser-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent-native cloud browser automation CLI for GoLogin",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"types": "dist/lib/types.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"examples/agent-flow.sh"
|
|
12
|
+
],
|
|
13
|
+
"bin": {
|
|
14
|
+
"gologin-agent-browser": "dist/cli.js"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc -p tsconfig.json",
|
|
18
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
19
|
+
"dev:cli": "tsx src/cli.ts",
|
|
20
|
+
"dev:daemon": "tsx src/daemon/server.ts",
|
|
21
|
+
"test": "tsx --test tests/**/*.test.ts",
|
|
22
|
+
"prepublishOnly": "npm run build && npm test"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://gitlab.com/easync/agent-browser.git"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://gitlab.com/easync/agent-browser",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://gitlab.com/easync/agent-browser/-/issues"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"gologin",
|
|
37
|
+
"agent",
|
|
38
|
+
"cli",
|
|
39
|
+
"cloud-browser",
|
|
40
|
+
"anti-detect",
|
|
41
|
+
"fingerprint",
|
|
42
|
+
"proxy",
|
|
43
|
+
"playwright",
|
|
44
|
+
"browser"
|
|
45
|
+
],
|
|
46
|
+
"author": "GoLogin",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=18"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"playwright": "^1.58.2"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^24.0.0",
|
|
56
|
+
"tsx": "^4.20.5",
|
|
57
|
+
"typescript": "^5.9.2"
|
|
58
|
+
}
|
|
59
|
+
}
|