@detiq/crawler 0.1.6 → 0.1.7
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/package.json +1 -1
- package/src/ai-login.ts +14 -1
- package/src/crawler.ts +6 -2
- package/src/skyvern.ts +0 -6
package/package.json
CHANGED
package/src/ai-login.ts
CHANGED
|
@@ -141,7 +141,20 @@ export async function loginWithStagehand(
|
|
|
141
141
|
await logStep('fill_password', async () => {
|
|
142
142
|
const observations = await stagehand.observe('Find the password input field');
|
|
143
143
|
const selector = observations[0]?.selector || 'input[type="password"]';
|
|
144
|
-
|
|
144
|
+
try {
|
|
145
|
+
await pg.locator(selector).fill(creds.password);
|
|
146
|
+
} catch {
|
|
147
|
+
// Stagehand locator failed (e.g. form re-rendered, proxy can't locate element).
|
|
148
|
+
// Fall back to direct DOM fill via evaluate so the password never touches the LLM.
|
|
149
|
+
await pg.evaluate((pwd: string) => {
|
|
150
|
+
const input = document.querySelector('input[type="password"]') as HTMLInputElement | null;
|
|
151
|
+
if (!input) throw new Error('No password field found on page');
|
|
152
|
+
const setter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
|
|
153
|
+
setter?.call(input, pwd);
|
|
154
|
+
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
155
|
+
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
156
|
+
}, creds.password);
|
|
157
|
+
}
|
|
145
158
|
});
|
|
146
159
|
await logStep('click_submit', () => actWithMouseSim(stagehand, 'Click the sign in, log in, login, or continue button to submit credentials'));
|
|
147
160
|
await pg.waitForLoadState('networkidle').catch(() => pg.waitForTimeout(2000));
|
package/src/crawler.ts
CHANGED
|
@@ -1059,9 +1059,13 @@ export async function crawlProject(opts: {
|
|
|
1059
1059
|
}, state.origins);
|
|
1060
1060
|
}
|
|
1061
1061
|
|
|
1062
|
-
//
|
|
1062
|
+
// Navigate to appUrl with cookies now set.
|
|
1063
|
+
// We MUST navigate to appUrl (not reload current page) because the initial
|
|
1064
|
+
// goto ran without cookies and was redirected to /login. Reloading /login stays
|
|
1065
|
+
// at /login even with a valid cookie (public path, no auth redirect). Navigating
|
|
1066
|
+
// to appUrl lets server middleware see the cookie and route to the authenticated app.
|
|
1063
1067
|
await onProgress?.(12, 'Restoring session');
|
|
1064
|
-
await rawPage.
|
|
1068
|
+
await rawPage.goto(opts.appUrl, { waitUntil: 'domcontentloaded' }).catch(() => { });
|
|
1065
1069
|
await waitForStableDOM(page);
|
|
1066
1070
|
// SPA root pages redirect client-side (useEffect → router.replace). Wait for it.
|
|
1067
1071
|
if (page.url() === opts.appUrl || page.url() === opts.appUrl.replace(/\/$/, '')) {
|
package/src/skyvern.ts
CHANGED
|
@@ -67,9 +67,6 @@ export async function skyvernNavigate(
|
|
|
67
67
|
return { screenshotUrls: [], visitedUrls: [], status: 'failed' };
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const { assertResolvesToPublicAddress } = await import('@detiq/core');
|
|
71
|
-
await assertResolvesToPublicAddress(apiUrl);
|
|
72
|
-
|
|
73
70
|
const visitedUrls: string[] = [];
|
|
74
71
|
const screenshotUrls: string[] = [];
|
|
75
72
|
const skyvernSteps: SkyvernStep[] = [];
|
|
@@ -164,9 +161,6 @@ export async function skyvernFallback(task: SkyvernTask, tenantConfig?: SkyvernC
|
|
|
164
161
|
return 'failed';
|
|
165
162
|
}
|
|
166
163
|
|
|
167
|
-
const { assertResolvesToPublicAddress } = await import('@detiq/core');
|
|
168
|
-
await assertResolvesToPublicAddress(apiUrl);
|
|
169
|
-
|
|
170
164
|
try {
|
|
171
165
|
const res = await fetch(`${apiUrl}/api/v1/tasks`, {
|
|
172
166
|
method: 'POST',
|