sf-builder-agent 0.7.1 → 0.7.3
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/browser.d.ts +6 -0
- package/dist/browser.js +39 -3
- package/dist/browser.js.map +1 -1
- package/dist/index.js +72 -2
- package/dist/index.js.map +1 -1
- package/dist/reporter.d.ts +1 -1
- package/dist/reporter.js.map +1 -1
- package/package.json +1 -1
- package/src/browser.ts +44 -3
- package/src/index.ts +122 -35
- package/src/reporter.ts +1 -1
package/dist/browser.d.ts
CHANGED
|
@@ -9,11 +9,17 @@ export declare function launchBrowser(): Promise<{
|
|
|
9
9
|
browser: Browser;
|
|
10
10
|
page: Page;
|
|
11
11
|
}>;
|
|
12
|
+
/**
|
|
13
|
+
* Check if the current page URL indicates a login/SSO redirect.
|
|
14
|
+
* Skips the check if the original target was itself a login page.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isLoginPage(currentUrl: string, originalTarget: string): boolean;
|
|
12
17
|
export interface CommandResult {
|
|
13
18
|
success: boolean;
|
|
14
19
|
result?: unknown;
|
|
15
20
|
error?: string;
|
|
16
21
|
screenshot?: string;
|
|
17
22
|
shutdown?: boolean;
|
|
23
|
+
waitingForLogin?: boolean;
|
|
18
24
|
}
|
|
19
25
|
export declare function executeCommand(page: Page, commandType: string, payload: Record<string, unknown>): Promise<CommandResult>;
|
package/dist/browser.js
CHANGED
|
@@ -85,14 +85,35 @@ async function findByText(page, selector, text) {
|
|
|
85
85
|
}, selector, text);
|
|
86
86
|
return handle;
|
|
87
87
|
}
|
|
88
|
+
// ─── Login Detection ─────────────────────────────────────────────────
|
|
89
|
+
const LOGIN_PATTERNS = [
|
|
90
|
+
"/identity/",
|
|
91
|
+
"login.microsoftonline.com",
|
|
92
|
+
"login.salesforce.com",
|
|
93
|
+
"/secur/frontdoor.jsp",
|
|
94
|
+
"/setup/secur/RemoteAccessAuthorizationPage",
|
|
95
|
+
];
|
|
96
|
+
/**
|
|
97
|
+
* Check if the current page URL indicates a login/SSO redirect.
|
|
98
|
+
* Skips the check if the original target was itself a login page.
|
|
99
|
+
*/
|
|
100
|
+
export function isLoginPage(currentUrl, originalTarget) {
|
|
101
|
+
if (LOGIN_PATTERNS.some((p) => originalTarget.includes(p)))
|
|
102
|
+
return false;
|
|
103
|
+
return LOGIN_PATTERNS.some((p) => currentUrl.includes(p));
|
|
104
|
+
}
|
|
88
105
|
export async function executeCommand(page, commandType, payload) {
|
|
89
106
|
try {
|
|
90
107
|
switch (commandType) {
|
|
91
108
|
// ── navigate ──
|
|
92
109
|
case "navigate": {
|
|
93
|
-
const
|
|
94
|
-
await page.goto(
|
|
95
|
-
|
|
110
|
+
const targetUrl = payload.url;
|
|
111
|
+
await page.goto(targetUrl, { waitUntil: "networkidle2", timeout: 30_000 });
|
|
112
|
+
const landedUrl = page.url();
|
|
113
|
+
if (isLoginPage(landedUrl, targetUrl)) {
|
|
114
|
+
return { success: false, waitingForLogin: true, result: { targetUrl, loginUrl: landedUrl } };
|
|
115
|
+
}
|
|
116
|
+
return { success: true, result: { url: targetUrl } };
|
|
96
117
|
}
|
|
97
118
|
// ── click ──
|
|
98
119
|
case "click": {
|
|
@@ -240,6 +261,21 @@ export async function executeCommand(page, commandType, payload) {
|
|
|
240
261
|
case "ping": {
|
|
241
262
|
return { success: true };
|
|
242
263
|
}
|
|
264
|
+
// ── stop ──
|
|
265
|
+
case "stop": {
|
|
266
|
+
return { success: true, result: { stopped: true } };
|
|
267
|
+
}
|
|
268
|
+
// ── restart ──
|
|
269
|
+
case "restart": {
|
|
270
|
+
// Close all pages and open a fresh one
|
|
271
|
+
const browser = page.browser();
|
|
272
|
+
const allPages = await browser.pages();
|
|
273
|
+
for (const p of allPages) {
|
|
274
|
+
await p.close().catch(() => { });
|
|
275
|
+
}
|
|
276
|
+
const newPage = await browser.newPage();
|
|
277
|
+
return { success: true, result: { restarted: true, newPage: true } };
|
|
278
|
+
}
|
|
243
279
|
// ── shutdown ──
|
|
244
280
|
case "shutdown": {
|
|
245
281
|
return { success: true, shutdown: true };
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { createInterface } from "node:readline/promises";
|
|
|
9
9
|
import { stdin, stdout } from "node:process";
|
|
10
10
|
import { pair } from "./pairing.js";
|
|
11
11
|
import { connectSSE } from "./sse-client.js";
|
|
12
|
-
import { launchBrowser, executeCommand } from "./browser.js";
|
|
12
|
+
import { launchBrowser, executeCommand, isLoginPage } from "./browser.js";
|
|
13
13
|
import { reportResult } from "./reporter.js";
|
|
14
14
|
import { startHeartbeat } from "./heartbeat.js";
|
|
15
15
|
// ─── Arg Parsing ─────────────────────────────────────────────────────
|
|
@@ -96,11 +96,47 @@ async function main() {
|
|
|
96
96
|
console.error("\u274C Browser launch failed:", err instanceof Error ? err.message : err);
|
|
97
97
|
process.exit(1);
|
|
98
98
|
}
|
|
99
|
+
// ── Login Wait Helper ──
|
|
100
|
+
const LOGIN_POLL_INTERVAL = 2_000;
|
|
101
|
+
const LOGIN_TIMEOUT = 5 * 60 * 1_000; // 5 minutes
|
|
102
|
+
async function waitForLogin(currentPage, targetUrl) {
|
|
103
|
+
const start = Date.now();
|
|
104
|
+
while (Date.now() - start < LOGIN_TIMEOUT) {
|
|
105
|
+
await new Promise((r) => setTimeout(r, LOGIN_POLL_INTERVAL));
|
|
106
|
+
const url = currentPage.url();
|
|
107
|
+
if (!isLoginPage(url, targetUrl)) {
|
|
108
|
+
return { loggedIn: true, waitedMs: Date.now() - start };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { loggedIn: false, waitedMs: Date.now() - start };
|
|
112
|
+
}
|
|
99
113
|
// ── Step 3: Start Heartbeat ──
|
|
100
114
|
const heartbeat = startHeartbeat(baseUrl, sessionId, token);
|
|
101
115
|
// ── Step 4: Connect to command stream ──
|
|
102
116
|
console.log("\uD83D\uDCE1 Connecting to command stream...");
|
|
103
|
-
|
|
117
|
+
// Serial command queue — ensures only one command runs at a time.
|
|
118
|
+
// SSE delivers all queued commands at once, but Puppeteer can only
|
|
119
|
+
// interact with one page action at a time. Without this, commands
|
|
120
|
+
// overlap and cause page flickering / race conditions.
|
|
121
|
+
let commandQueue = Promise.resolve();
|
|
122
|
+
let stopped = false; // When true, queued commands are skipped until reset
|
|
123
|
+
async function handleCommand(command) {
|
|
124
|
+
// ── Handle stop — flush the queue ──
|
|
125
|
+
if (command.commandType === "stop") {
|
|
126
|
+
stopped = true;
|
|
127
|
+
commandQueue = Promise.resolve(); // Reset the chain
|
|
128
|
+
console.log("\u23F9 Stop received — flushing command queue");
|
|
129
|
+
await reportResult(baseUrl, sessionId, token, command.id, "success", { stopped: true });
|
|
130
|
+
// Reset stopped flag so new commands after this can execute
|
|
131
|
+
stopped = false;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// Skip commands if stopped (they were queued before the stop arrived)
|
|
135
|
+
if (stopped) {
|
|
136
|
+
console.log(`\u23ED Skipping (stopped): ${command.commandType}`);
|
|
137
|
+
await reportResult(baseUrl, sessionId, token, command.id, "error", { error: "Cancelled by stop" });
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
104
140
|
const label = command.stepKey
|
|
105
141
|
? `${command.commandType} (step: ${command.stepKey})`
|
|
106
142
|
: command.commandType;
|
|
@@ -109,6 +145,34 @@ async function main() {
|
|
|
109
145
|
: "";
|
|
110
146
|
console.log(`\u26A1 Executing: ${label}${payloadHint}`);
|
|
111
147
|
const result = await executeCommand(page, command.commandType, command.payload);
|
|
148
|
+
// ── Handle login detection ──
|
|
149
|
+
if (result.waitingForLogin) {
|
|
150
|
+
console.log("\uD83D\uDD10 Login page detected — waiting for user to authenticate...");
|
|
151
|
+
// Report waiting_for_login immediately so the web UI can show the banner
|
|
152
|
+
await reportResult(baseUrl, sessionId, token, command.id, "waiting_for_login", result.result);
|
|
153
|
+
// Poll until login completes or timeout
|
|
154
|
+
const loginResult = await waitForLogin(page, command.payload.url);
|
|
155
|
+
if (loginResult.loggedIn) {
|
|
156
|
+
console.log(`\u2705 Login complete (waited ${Math.round(loginResult.waitedMs / 1000)}s)`);
|
|
157
|
+
await reportResult(baseUrl, sessionId, token, command.id, "success", {
|
|
158
|
+
loginDetected: true,
|
|
159
|
+
waitedMs: loginResult.waitedMs,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.error("\u274C Login timed out after 5 minutes");
|
|
164
|
+
await reportResult(baseUrl, sessionId, token, command.id, "error", {
|
|
165
|
+
error: "Login timed out — user did not complete authentication within 5 minutes",
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// ── Handle restart — update page reference ──
|
|
171
|
+
if (command.commandType === "restart" && result.success) {
|
|
172
|
+
const pages = await browser.pages();
|
|
173
|
+
page = pages[pages.length - 1];
|
|
174
|
+
console.log("\u2705 Browser restarted — new page ready");
|
|
175
|
+
}
|
|
112
176
|
if (result.success) {
|
|
113
177
|
console.log(`\u2705 Command complete: ${command.commandType}`);
|
|
114
178
|
}
|
|
@@ -129,6 +193,12 @@ async function main() {
|
|
|
129
193
|
console.log("\uD83D\uDC4B Shutting down (server requested)...");
|
|
130
194
|
shutdown();
|
|
131
195
|
}
|
|
196
|
+
}
|
|
197
|
+
const sse = connectSSE(baseUrl, sessionId, token, (command) => {
|
|
198
|
+
// Queue commands serially — each waits for the previous to complete
|
|
199
|
+
commandQueue = commandQueue.then(() => handleCommand(command)).catch((err) => {
|
|
200
|
+
console.error(`\u274C Unhandled command error: ${err instanceof Error ? err.message : err}`);
|
|
201
|
+
});
|
|
132
202
|
}, (err) => {
|
|
133
203
|
console.error(`\u274C SSE error: ${err.message}`);
|
|
134
204
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/reporter.d.ts
CHANGED
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Reporter — POST command results back to the web app.
|
|
3
3
|
* Uses /api/agent/result (flat route, not behind Easy Auth).
|
|
4
4
|
*/
|
|
5
|
-
export declare function reportResult(baseUrl: string, _sessionId: string, token: string, commandId: string, status: "success" | "error", result?: Record<string, unknown>): Promise<void>;
|
|
5
|
+
export declare function reportResult(baseUrl: string, _sessionId: string, token: string, commandId: string, status: "success" | "error" | "waiting_for_login", result?: Record<string, unknown>): Promise<void>;
|
package/dist/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,SAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,UAAkB,EAClB,KAAa,EACb,SAAiB,EACjB,MAAiD,EACjD,MAAgC;IAEhC,MAAM,GAAG,GAAG,GAAG,OAAO,mBAAmB,CAAC;IAE1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;SACpD,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,sBAAsB,EACtB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CACzC,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/browser.ts
CHANGED
|
@@ -125,6 +125,25 @@ async function findByText(
|
|
|
125
125
|
return handle as ElementHandle<Element>;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
// ─── Login Detection ─────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
const LOGIN_PATTERNS = [
|
|
131
|
+
"/identity/",
|
|
132
|
+
"login.microsoftonline.com",
|
|
133
|
+
"login.salesforce.com",
|
|
134
|
+
"/secur/frontdoor.jsp",
|
|
135
|
+
"/setup/secur/RemoteAccessAuthorizationPage",
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Check if the current page URL indicates a login/SSO redirect.
|
|
140
|
+
* Skips the check if the original target was itself a login page.
|
|
141
|
+
*/
|
|
142
|
+
export function isLoginPage(currentUrl: string, originalTarget: string): boolean {
|
|
143
|
+
if (LOGIN_PATTERNS.some((p) => originalTarget.includes(p))) return false;
|
|
144
|
+
return LOGIN_PATTERNS.some((p) => currentUrl.includes(p));
|
|
145
|
+
}
|
|
146
|
+
|
|
128
147
|
// ─── Command Executor ────────────────────────────────────────────────
|
|
129
148
|
|
|
130
149
|
export interface CommandResult {
|
|
@@ -133,6 +152,7 @@ export interface CommandResult {
|
|
|
133
152
|
error?: string;
|
|
134
153
|
screenshot?: string;
|
|
135
154
|
shutdown?: boolean;
|
|
155
|
+
waitingForLogin?: boolean;
|
|
136
156
|
}
|
|
137
157
|
|
|
138
158
|
export async function executeCommand(
|
|
@@ -144,9 +164,13 @@ export async function executeCommand(
|
|
|
144
164
|
switch (commandType) {
|
|
145
165
|
// ── navigate ──
|
|
146
166
|
case "navigate": {
|
|
147
|
-
const
|
|
148
|
-
await page.goto(
|
|
149
|
-
|
|
167
|
+
const targetUrl = payload.url as string;
|
|
168
|
+
await page.goto(targetUrl, { waitUntil: "networkidle2", timeout: 30_000 });
|
|
169
|
+
const landedUrl = page.url();
|
|
170
|
+
if (isLoginPage(landedUrl, targetUrl)) {
|
|
171
|
+
return { success: false, waitingForLogin: true, result: { targetUrl, loginUrl: landedUrl } };
|
|
172
|
+
}
|
|
173
|
+
return { success: true, result: { url: targetUrl } };
|
|
150
174
|
}
|
|
151
175
|
|
|
152
176
|
// ── click ──
|
|
@@ -321,6 +345,23 @@ export async function executeCommand(
|
|
|
321
345
|
return { success: true };
|
|
322
346
|
}
|
|
323
347
|
|
|
348
|
+
// ── stop ──
|
|
349
|
+
case "stop": {
|
|
350
|
+
return { success: true, result: { stopped: true } };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// ── restart ──
|
|
354
|
+
case "restart": {
|
|
355
|
+
// Close all pages and open a fresh one
|
|
356
|
+
const browser = page.browser();
|
|
357
|
+
const allPages = await browser.pages();
|
|
358
|
+
for (const p of allPages) {
|
|
359
|
+
await p.close().catch(() => {});
|
|
360
|
+
}
|
|
361
|
+
const newPage = await browser.newPage();
|
|
362
|
+
return { success: true, result: { restarted: true, newPage: true } };
|
|
363
|
+
}
|
|
364
|
+
|
|
324
365
|
// ── shutdown ──
|
|
325
366
|
case "shutdown": {
|
|
326
367
|
return { success: true, shutdown: true };
|
package/src/index.ts
CHANGED
|
@@ -11,10 +11,10 @@ import { createInterface } from "node:readline/promises";
|
|
|
11
11
|
import { stdin, stdout } from "node:process";
|
|
12
12
|
import { pair } from "./pairing.js";
|
|
13
13
|
import { connectSSE } from "./sse-client.js";
|
|
14
|
-
import { launchBrowser, executeCommand } from "./browser.js";
|
|
14
|
+
import { launchBrowser, executeCommand, isLoginPage } from "./browser.js";
|
|
15
15
|
import { reportResult } from "./reporter.js";
|
|
16
16
|
import { startHeartbeat } from "./heartbeat.js";
|
|
17
|
-
import type { Browser } from "puppeteer";
|
|
17
|
+
import type { Browser, Page } from "puppeteer";
|
|
18
18
|
|
|
19
19
|
// ─── Arg Parsing ─────────────────────────────────────────────────────
|
|
20
20
|
|
|
@@ -101,7 +101,7 @@ async function main() {
|
|
|
101
101
|
// ── Step 2: Launch Browser ──
|
|
102
102
|
console.log("\uD83C\uDF10 Launching browser...");
|
|
103
103
|
let browser: Browser;
|
|
104
|
-
let page:
|
|
104
|
+
let page: Page;
|
|
105
105
|
try {
|
|
106
106
|
const launched = await launchBrowser();
|
|
107
107
|
browser = launched.browser;
|
|
@@ -115,58 +115,145 @@ async function main() {
|
|
|
115
115
|
process.exit(1);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
// ── Login Wait Helper ──
|
|
119
|
+
const LOGIN_POLL_INTERVAL = 2_000;
|
|
120
|
+
const LOGIN_TIMEOUT = 5 * 60 * 1_000; // 5 minutes
|
|
121
|
+
|
|
122
|
+
async function waitForLogin(currentPage: Page, targetUrl: string): Promise<{ loggedIn: boolean; waitedMs: number }> {
|
|
123
|
+
const start = Date.now();
|
|
124
|
+
while (Date.now() - start < LOGIN_TIMEOUT) {
|
|
125
|
+
await new Promise((r) => setTimeout(r, LOGIN_POLL_INTERVAL));
|
|
126
|
+
const url = currentPage.url();
|
|
127
|
+
if (!isLoginPage(url, targetUrl)) {
|
|
128
|
+
return { loggedIn: true, waitedMs: Date.now() - start };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return { loggedIn: false, waitedMs: Date.now() - start };
|
|
132
|
+
}
|
|
133
|
+
|
|
118
134
|
// ── Step 3: Start Heartbeat ──
|
|
119
135
|
const heartbeat = startHeartbeat(baseUrl, sessionId, token);
|
|
120
136
|
|
|
121
137
|
// ── Step 4: Connect to command stream ──
|
|
122
138
|
console.log("\uD83D\uDCE1 Connecting to command stream...");
|
|
123
139
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
? `${command.commandType} (step: ${command.stepKey})`
|
|
131
|
-
: command.commandType;
|
|
140
|
+
// Serial command queue — ensures only one command runs at a time.
|
|
141
|
+
// SSE delivers all queued commands at once, but Puppeteer can only
|
|
142
|
+
// interact with one page action at a time. Without this, commands
|
|
143
|
+
// overlap and cause page flickering / race conditions.
|
|
144
|
+
let commandQueue: Promise<void> = Promise.resolve();
|
|
145
|
+
let stopped = false; // When true, queued commands are skipped until reset
|
|
132
146
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
async function handleCommand(command: { id: string; commandType: string; stepKey: string | null; payload: Record<string, unknown> }) {
|
|
148
|
+
// ── Handle stop — flush the queue ──
|
|
149
|
+
if (command.commandType === "stop") {
|
|
150
|
+
stopped = true;
|
|
151
|
+
commandQueue = Promise.resolve(); // Reset the chain
|
|
152
|
+
console.log("\u23F9 Stop received — flushing command queue");
|
|
153
|
+
await reportResult(baseUrl, sessionId!, token, command.id, "success", { stopped: true });
|
|
154
|
+
// Reset stopped flag so new commands after this can execute
|
|
155
|
+
stopped = false;
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
137
158
|
|
|
138
|
-
|
|
159
|
+
// Skip commands if stopped (they were queued before the stop arrived)
|
|
160
|
+
if (stopped) {
|
|
161
|
+
console.log(`\u23ED Skipping (stopped): ${command.commandType}`);
|
|
162
|
+
await reportResult(baseUrl, sessionId!, token, command.id, "error", { error: "Cancelled by stop" });
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
139
165
|
|
|
140
|
-
|
|
166
|
+
const label = command.stepKey
|
|
167
|
+
? `${command.commandType} (step: ${command.stepKey})`
|
|
168
|
+
: command.commandType;
|
|
141
169
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
170
|
+
const payloadHint =
|
|
171
|
+
command.commandType === "navigate"
|
|
172
|
+
? ` \u2192 ${command.payload.url}`
|
|
173
|
+
: "";
|
|
174
|
+
|
|
175
|
+
console.log(`\u26A1 Executing: ${label}${payloadHint}`);
|
|
149
176
|
|
|
150
|
-
|
|
151
|
-
const resultPayload: Record<string, unknown> = {};
|
|
152
|
-
if (result.result !== undefined) resultPayload.result = result.result;
|
|
153
|
-
if (result.screenshot) resultPayload.screenshot = result.screenshot;
|
|
154
|
-
if (result.error) resultPayload.error = result.error;
|
|
177
|
+
const result = await executeCommand(page, command.commandType, command.payload);
|
|
155
178
|
|
|
179
|
+
// ── Handle login detection ──
|
|
180
|
+
if (result.waitingForLogin) {
|
|
181
|
+
console.log("\uD83D\uDD10 Login page detected — waiting for user to authenticate...");
|
|
182
|
+
|
|
183
|
+
// Report waiting_for_login immediately so the web UI can show the banner
|
|
156
184
|
await reportResult(
|
|
157
185
|
baseUrl,
|
|
158
186
|
sessionId!,
|
|
159
187
|
token,
|
|
160
188
|
command.id,
|
|
161
|
-
|
|
162
|
-
|
|
189
|
+
"waiting_for_login",
|
|
190
|
+
result.result as Record<string, unknown> | undefined
|
|
163
191
|
);
|
|
164
192
|
|
|
165
|
-
//
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
193
|
+
// Poll until login completes or timeout
|
|
194
|
+
const loginResult = await waitForLogin(page, command.payload.url as string);
|
|
195
|
+
|
|
196
|
+
if (loginResult.loggedIn) {
|
|
197
|
+
console.log(`\u2705 Login complete (waited ${Math.round(loginResult.waitedMs / 1000)}s)`);
|
|
198
|
+
await reportResult(baseUrl, sessionId!, token, command.id, "success", {
|
|
199
|
+
loginDetected: true,
|
|
200
|
+
waitedMs: loginResult.waitedMs,
|
|
201
|
+
});
|
|
202
|
+
} else {
|
|
203
|
+
console.error("\u274C Login timed out after 5 minutes");
|
|
204
|
+
await reportResult(baseUrl, sessionId!, token, command.id, "error", {
|
|
205
|
+
error: "Login timed out — user did not complete authentication within 5 minutes",
|
|
206
|
+
});
|
|
169
207
|
}
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ── Handle restart — update page reference ──
|
|
212
|
+
if (command.commandType === "restart" && result.success) {
|
|
213
|
+
const pages = await browser.pages();
|
|
214
|
+
page = pages[pages.length - 1];
|
|
215
|
+
console.log("\u2705 Browser restarted — new page ready");
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (result.success) {
|
|
219
|
+
console.log(`\u2705 Command complete: ${command.commandType}`);
|
|
220
|
+
} else {
|
|
221
|
+
console.error(
|
|
222
|
+
`\u274C Command failed: ${command.commandType} \u2014 ${result.error}`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Report back to server
|
|
227
|
+
const resultPayload: Record<string, unknown> = {};
|
|
228
|
+
if (result.result !== undefined) resultPayload.result = result.result;
|
|
229
|
+
if (result.screenshot) resultPayload.screenshot = result.screenshot;
|
|
230
|
+
if (result.error) resultPayload.error = result.error;
|
|
231
|
+
|
|
232
|
+
await reportResult(
|
|
233
|
+
baseUrl,
|
|
234
|
+
sessionId!,
|
|
235
|
+
token,
|
|
236
|
+
command.id,
|
|
237
|
+
result.success ? "success" : "error",
|
|
238
|
+
Object.keys(resultPayload).length > 0 ? resultPayload : undefined
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// Handle shutdown command
|
|
242
|
+
if (result.shutdown) {
|
|
243
|
+
console.log("\uD83D\uDC4B Shutting down (server requested)...");
|
|
244
|
+
shutdown();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const sse = connectSSE(
|
|
249
|
+
baseUrl,
|
|
250
|
+
sessionId,
|
|
251
|
+
token,
|
|
252
|
+
(command) => {
|
|
253
|
+
// Queue commands serially — each waits for the previous to complete
|
|
254
|
+
commandQueue = commandQueue.then(() => handleCommand(command)).catch((err) => {
|
|
255
|
+
console.error(`\u274C Unhandled command error: ${err instanceof Error ? err.message : err}`);
|
|
256
|
+
});
|
|
170
257
|
},
|
|
171
258
|
(err) => {
|
|
172
259
|
console.error(`\u274C SSE error: ${err.message}`);
|
package/src/reporter.ts
CHANGED
|
@@ -8,7 +8,7 @@ export async function reportResult(
|
|
|
8
8
|
_sessionId: string,
|
|
9
9
|
token: string,
|
|
10
10
|
commandId: string,
|
|
11
|
-
status: "success" | "error",
|
|
11
|
+
status: "success" | "error" | "waiting_for_login",
|
|
12
12
|
result?: Record<string, unknown>
|
|
13
13
|
): Promise<void> {
|
|
14
14
|
const url = `${baseUrl}/api/agent/result`;
|