dsh-browser-playwright-codex 0.5.2 → 0.5.4

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +17 -7
  3. package/SECURITY.md +15 -10
  4. package/lib/browser-lifecycle.d.ts +12 -0
  5. package/lib/browser-lifecycle.js +186 -0
  6. package/lib/challenge.d.ts +20 -0
  7. package/lib/challenge.js +40 -0
  8. package/lib/config.d.ts +81 -0
  9. package/lib/config.js +61 -0
  10. package/lib/extract.d.ts +13 -0
  11. package/lib/extract.js +34 -0
  12. package/lib/index.d.ts +4 -2
  13. package/lib/index.js +3 -1
  14. package/lib/login-state.d.ts +10 -0
  15. package/lib/login-state.js +83 -0
  16. package/lib/page-actions.d.ts +134 -0
  17. package/lib/page-actions.js +725 -0
  18. package/lib/page-diagnostics.d.ts +65 -0
  19. package/lib/page-diagnostics.js +181 -0
  20. package/lib/page-probes.d.ts +78 -0
  21. package/lib/page-probes.js +281 -0
  22. package/lib/page-snapshot.d.ts +96 -0
  23. package/lib/page-snapshot.js +280 -0
  24. package/lib/playwright.d.ts +5 -644
  25. package/lib/playwright.js +28 -2602
  26. package/lib/provider.d.ts +157 -0
  27. package/lib/provider.js +352 -0
  28. package/lib/session.d.ts +410 -0
  29. package/lib/session.js +633 -0
  30. package/lib/tool-render.d.ts +20 -0
  31. package/lib/tool-render.js +137 -0
  32. package/lib/tool-schemas.d.ts +76 -0
  33. package/lib/tool-schemas.js +46 -0
  34. package/lib/tool-types.d.ts +82 -0
  35. package/lib/tool-types.js +1 -0
  36. package/lib/tool.d.ts +2 -26
  37. package/lib/tool.js +5 -252
  38. package/lib/url-policy.d.ts +2 -0
  39. package/lib/url-policy.js +26 -0
  40. package/lib/window-focus.d.ts +27 -0
  41. package/lib/window-focus.js +54 -0
  42. package/package.json +1 -1
  43. package/scripts/dsh-browser-verify.mjs +2 -1
  44. package/scripts/prompt-cost.mjs +1 -1
@@ -0,0 +1,26 @@
1
+ /**
2
+ * URL 策略:只允许访问白名单域名(含点击后导航的校验)。
3
+ * @module dsh-browser-playwright-codex/url-policy
4
+ */
5
+ import { BrowserError } from "./errors.js";
6
+ /** Validate one absolute URL against the navigation policy. */
7
+ export function assertAllowedUrl(raw, allowedDomains) {
8
+ let parsed;
9
+ try {
10
+ parsed = new URL(raw);
11
+ }
12
+ catch {
13
+ throw new BrowserError('URL_NOT_ALLOWED', 'invalid URL: ' + raw);
14
+ }
15
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
16
+ throw new BrowserError('URL_NOT_ALLOWED', 'only http(s) URLs can be navigated, got: ' + parsed.protocol);
17
+ }
18
+ if (allowedDomains.length > 0) {
19
+ const host = parsed.hostname.toLowerCase();
20
+ const allowed = allowedDomains.some((suffix) => host === suffix || host.endsWith('.' + suffix));
21
+ if (!allowed) {
22
+ throw new BrowserError('URL_NOT_ALLOWED', 'host ' + parsed.hostname + ' is not in allowedDomains');
23
+ }
24
+ }
25
+ return parsed;
26
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 窗口与焦点行为:判断承载页面的系统窗口是否最小化,以及在后台创建标签页 —— 两项都是为了让
3
+ * 窗口/标签不打扰用户。背景与实测见 FOCUS-STEALING.md。
4
+ * @module dsh-browser-playwright-codex/window-focus
5
+ */
6
+ import type { BrowserContext, Page } from 'playwright-core';
7
+ /**
8
+ * True when the OS window hosting this page is minimized. Tab selection lives
9
+ * in the browser context, not in the OS window, so activation is a side effect
10
+ * we are free to decline — and declining it is what keeps the agent from
11
+ * yanking a minimized window into the user's face. If the window state cannot
12
+ * be read we answer true (treat as minimized): the safe direction is to leave
13
+ * the user's desktop alone, and a skipped bringToFront costs nothing functional.
14
+ */
15
+ export declare function isWindowMinimized(page: Page): Promise<boolean>;
16
+ /**
17
+ * Create a tab without raising the window. context.newPage() routes through CDP
18
+ * Target.createTarget without `background`, and Chromium activates the window
19
+ * on every tab creation -- plainly visible once the user has minimized it.
20
+ * Sending the command ourselves with background:true creates the tab silently;
21
+ * Playwright still auto-attaches and returns a fully driveable Page (verified
22
+ * live: Playwright learns the page and evaluate() runs on it). The URL is left
23
+ * at about:blank on purpose so the caller's own goto keeps owning navigation
24
+ * policy, timeouts and abort handling. On any failure this falls back to
25
+ * newPage(): a tab that pops the window beats no tab at all.
26
+ */
27
+ export declare function createBackgroundPage(context: BrowserContext): Promise<Page>;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * True when the OS window hosting this page is minimized. Tab selection lives
3
+ * in the browser context, not in the OS window, so activation is a side effect
4
+ * we are free to decline — and declining it is what keeps the agent from
5
+ * yanking a minimized window into the user's face. If the window state cannot
6
+ * be read we answer true (treat as minimized): the safe direction is to leave
7
+ * the user's desktop alone, and a skipped bringToFront costs nothing functional.
8
+ */
9
+ export async function isWindowMinimized(page) {
10
+ let provider;
11
+ try {
12
+ provider = await page.context().newCDPSession(page);
13
+ const { windowId } = await provider.send('Browser.getWindowForTarget');
14
+ const { bounds } = await provider.send('Browser.getWindowBounds', { windowId });
15
+ return bounds.windowState === 'minimized';
16
+ }
17
+ catch {
18
+ return true;
19
+ }
20
+ finally {
21
+ await provider?.detach().catch(() => { });
22
+ }
23
+ }
24
+ /**
25
+ * Create a tab without raising the window. context.newPage() routes through CDP
26
+ * Target.createTarget without `background`, and Chromium activates the window
27
+ * on every tab creation -- plainly visible once the user has minimized it.
28
+ * Sending the command ourselves with background:true creates the tab silently;
29
+ * Playwright still auto-attaches and returns a fully driveable Page (verified
30
+ * live: Playwright learns the page and evaluate() runs on it). The URL is left
31
+ * at about:blank on purpose so the caller's own goto keeps owning navigation
32
+ * policy, timeouts and abort handling. On any failure this falls back to
33
+ * newPage(): a tab that pops the window beats no tab at all.
34
+ */
35
+ export async function createBackgroundPage(context) {
36
+ const anchor = context.pages()[0];
37
+ if (anchor === undefined)
38
+ return await context.newPage();
39
+ let provider;
40
+ try {
41
+ provider = await context.newCDPSession(anchor);
42
+ // Arm the listener before sending: Playwright attaches as soon as the
43
+ // target exists, which can happen before createTarget resolves.
44
+ const attached = context.waitForEvent('page', { timeout: 10000 });
45
+ await provider.send('Target.createTarget', { url: 'about:blank', background: true });
46
+ return await attached;
47
+ }
48
+ catch {
49
+ return await context.newPage();
50
+ }
51
+ finally {
52
+ await provider?.detach().catch(() => { });
53
+ }
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-browser-playwright-codex",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Browser automation for DeepSeek Harness: fill in forms, scrape lists and work across tabs in real pages, using the logins you already have. Runs in a visible window that stays quiet when minimised, and stops for sign-ins, CAPTCHAs and native dialogs instead of confirming for you.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,7 +23,8 @@ import http from 'node:http'
23
23
  import { readdirSync, statSync } from 'node:fs'
24
24
  import os from 'node:os'
25
25
  import path from 'node:path'
26
- import { Config as ConfigSchema, PlaywrightProvider } from '../lib/playwright.js'
26
+ import { PlaywrightProvider } from '../lib/provider.js'
27
+ import { Config as ConfigSchema } from '../lib/config.js'
27
28
  import { renderSnapshot } from '../lib/snapshot-render.js'
28
29
  import { getEffectiveEngine, setSnapshotEngine } from '../lib/runtime-state.js'
29
30
 
@@ -12,7 +12,7 @@ import { Context } from '@deepseek-ai/cordis'
12
12
  import ToolRuntime from '@deepseek-ai/dsh-tools'
13
13
  import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
14
14
  import BrowserRuntime from '../src/service.ts'
15
- import { PlaywrightProvider } from '../src/playwright.ts'
15
+ import { PlaywrightProvider } from '../src/provider.ts'
16
16
  import * as browserTool from '../src/tool.ts'
17
17
  import { bundleConfig } from './shipped-gates.mjs'
18
18