mo-mcp 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.
Files changed (114) hide show
  1. package/LICENSE +21 -0
  2. package/dist/browser/chrome-launcher.d.ts +6 -0
  3. package/dist/browser/chrome-launcher.d.ts.map +1 -0
  4. package/dist/browser/chrome-launcher.js +129 -0
  5. package/dist/browser/chrome-launcher.js.map +1 -0
  6. package/dist/browser/connection.d.ts +7 -0
  7. package/dist/browser/connection.d.ts.map +1 -0
  8. package/dist/browser/connection.js +109 -0
  9. package/dist/browser/connection.js.map +1 -0
  10. package/dist/browser/errors.d.ts +5 -0
  11. package/dist/browser/errors.d.ts.map +1 -0
  12. package/dist/browser/errors.js +40 -0
  13. package/dist/browser/errors.js.map +1 -0
  14. package/dist/browser/page-state.d.ts +5 -0
  15. package/dist/browser/page-state.d.ts.map +1 -0
  16. package/dist/browser/page-state.js +88 -0
  17. package/dist/browser/page-state.js.map +1 -0
  18. package/dist/browser/refs.d.ts +16 -0
  19. package/dist/browser/refs.d.ts.map +1 -0
  20. package/dist/browser/refs.js +67 -0
  21. package/dist/browser/refs.js.map +1 -0
  22. package/dist/browser/snapshot.d.ts +12 -0
  23. package/dist/browser/snapshot.d.ts.map +1 -0
  24. package/dist/browser/snapshot.js +253 -0
  25. package/dist/browser/snapshot.js.map +1 -0
  26. package/dist/credentials/bitwarden.d.ts +10 -0
  27. package/dist/credentials/bitwarden.d.ts.map +1 -0
  28. package/dist/credentials/bitwarden.js +72 -0
  29. package/dist/credentials/bitwarden.js.map +1 -0
  30. package/dist/credentials/dotenv.d.ts +20 -0
  31. package/dist/credentials/dotenv.d.ts.map +1 -0
  32. package/dist/credentials/dotenv.js +106 -0
  33. package/dist/credentials/dotenv.js.map +1 -0
  34. package/dist/credentials/lastpass.d.ts +7 -0
  35. package/dist/credentials/lastpass.d.ts.map +1 -0
  36. package/dist/credentials/lastpass.js +69 -0
  37. package/dist/credentials/lastpass.js.map +1 -0
  38. package/dist/credentials/onepassword.d.ts +8 -0
  39. package/dist/credentials/onepassword.d.ts.map +1 -0
  40. package/dist/credentials/onepassword.js +64 -0
  41. package/dist/credentials/onepassword.js.map +1 -0
  42. package/dist/credentials/provider.d.ts +14 -0
  43. package/dist/credentials/provider.d.ts.map +1 -0
  44. package/dist/credentials/provider.js +33 -0
  45. package/dist/credentials/provider.js.map +1 -0
  46. package/dist/credentials/resolver.d.ts +6 -0
  47. package/dist/credentials/resolver.d.ts.map +1 -0
  48. package/dist/credentials/resolver.js +50 -0
  49. package/dist/credentials/resolver.js.map +1 -0
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +90 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/server.d.ts +4 -0
  55. package/dist/server.d.ts.map +1 -0
  56. package/dist/server.js +51 -0
  57. package/dist/server.js.map +1 -0
  58. package/dist/setup.d.ts +5 -0
  59. package/dist/setup.d.ts.map +1 -0
  60. package/dist/setup.js +92 -0
  61. package/dist/setup.js.map +1 -0
  62. package/dist/tools/credential.d.ts +14 -0
  63. package/dist/tools/credential.d.ts.map +1 -0
  64. package/dist/tools/credential.js +33 -0
  65. package/dist/tools/credential.js.map +1 -0
  66. package/dist/tools/dialog.d.ts +18 -0
  67. package/dist/tools/dialog.d.ts.map +1 -0
  68. package/dist/tools/dialog.js +31 -0
  69. package/dist/tools/dialog.js.map +1 -0
  70. package/dist/tools/evaluate.d.ts +18 -0
  71. package/dist/tools/evaluate.d.ts.map +1 -0
  72. package/dist/tools/evaluate.js +32 -0
  73. package/dist/tools/evaluate.js.map +1 -0
  74. package/dist/tools/file.d.ts +22 -0
  75. package/dist/tools/file.d.ts.map +1 -0
  76. package/dist/tools/file.js +52 -0
  77. package/dist/tools/file.js.map +1 -0
  78. package/dist/tools/interact.d.ts +52 -0
  79. package/dist/tools/interact.d.ts.map +1 -0
  80. package/dist/tools/interact.js +153 -0
  81. package/dist/tools/interact.js.map +1 -0
  82. package/dist/tools/navigate.d.ts +18 -0
  83. package/dist/tools/navigate.d.ts.map +1 -0
  84. package/dist/tools/navigate.js +32 -0
  85. package/dist/tools/navigate.js.map +1 -0
  86. package/dist/tools/network.d.ts +28 -0
  87. package/dist/tools/network.d.ts.map +1 -0
  88. package/dist/tools/network.js +91 -0
  89. package/dist/tools/network.js.map +1 -0
  90. package/dist/tools/screenshot.d.ts +19 -0
  91. package/dist/tools/screenshot.d.ts.map +1 -0
  92. package/dist/tools/screenshot.js +29 -0
  93. package/dist/tools/screenshot.js.map +1 -0
  94. package/dist/tools/snapshot.d.ts +20 -0
  95. package/dist/tools/snapshot.d.ts.map +1 -0
  96. package/dist/tools/snapshot.js +27 -0
  97. package/dist/tools/snapshot.js.map +1 -0
  98. package/dist/tools/storage.d.ts +64 -0
  99. package/dist/tools/storage.d.ts.map +1 -0
  100. package/dist/tools/storage.js +107 -0
  101. package/dist/tools/storage.js.map +1 -0
  102. package/dist/tools/tabs.d.ts +18 -0
  103. package/dist/tools/tabs.d.ts.map +1 -0
  104. package/dist/tools/tabs.js +72 -0
  105. package/dist/tools/tabs.js.map +1 -0
  106. package/dist/tools/wait.d.ts +28 -0
  107. package/dist/tools/wait.d.ts.map +1 -0
  108. package/dist/tools/wait.js +51 -0
  109. package/dist/tools/wait.js.map +1 -0
  110. package/dist/types.d.ts +81 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +2 -0
  113. package/dist/types.js.map +1 -0
  114. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ export declare function setNoLaunch(v: boolean): void;
2
+ export declare function shouldLaunch(): boolean;
3
+ export declare function findChrome(): Promise<string | null>;
4
+ export declare function chromeDataDir(): string;
5
+ export declare function ensureChromeRunning(cdpUrl: string): Promise<void>;
6
+ //# sourceMappingURL=chrome-launcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chrome-launcher.d.ts","sourceRoot":"","sources":["../../src/browser/chrome-launcher.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAE5C;AAED,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2CzD;AAWD,wBAAgB,aAAa,IAAI,MAAM,CAetC;AAeD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+CvE"}
@@ -0,0 +1,129 @@
1
+ import { existsSync } from "fs";
2
+ import { join } from "path";
3
+ import { execFile, spawn } from "child_process";
4
+ import { homedir } from "os";
5
+ let _noLaunch = false;
6
+ export function setNoLaunch(v) {
7
+ _noLaunch = v;
8
+ }
9
+ export function shouldLaunch() {
10
+ return !_noLaunch;
11
+ }
12
+ export async function findChrome() {
13
+ const platform = process.platform;
14
+ if (platform === "win32") {
15
+ const envDirs = [
16
+ process.env.LOCALAPPDATA,
17
+ process.env.PROGRAMFILES,
18
+ process.env["PROGRAMFILES(X86)"],
19
+ ].filter(Boolean);
20
+ const suffixes = [
21
+ "Google\\Chrome\\Application\\chrome.exe",
22
+ "Microsoft\\Edge\\Application\\msedge.exe",
23
+ ];
24
+ for (const dir of envDirs) {
25
+ for (const suffix of suffixes) {
26
+ const p = join(dir, suffix);
27
+ if (existsSync(p))
28
+ return p;
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ if (platform === "darwin") {
34
+ const candidates = [
35
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
36
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
37
+ "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
38
+ ];
39
+ for (const p of candidates) {
40
+ if (existsSync(p))
41
+ return p;
42
+ }
43
+ return null;
44
+ }
45
+ // linux: use `which`
46
+ const names = ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"];
47
+ for (const name of names) {
48
+ const found = await whichBin(name);
49
+ if (found)
50
+ return found;
51
+ }
52
+ return null;
53
+ }
54
+ function whichBin(name) {
55
+ return new Promise((resolve) => {
56
+ execFile("which", [name], (err, stdout) => {
57
+ if (err || !stdout.trim())
58
+ return resolve(null);
59
+ resolve(stdout.trim());
60
+ });
61
+ });
62
+ }
63
+ export function chromeDataDir() {
64
+ const platform = process.platform;
65
+ if (platform === "win32") {
66
+ const localAppData = process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local");
67
+ return join(localAppData, "mo-mcp", "chrome-data");
68
+ }
69
+ if (platform === "darwin") {
70
+ return join(homedir(), "Library", "Application Support", "mo-mcp", "chrome-data");
71
+ }
72
+ // linux
73
+ const dataHome = process.env.XDG_DATA_HOME || join(homedir(), ".local", "share");
74
+ return join(dataHome, "mo-mcp", "chrome-data");
75
+ }
76
+ async function probeCdp(cdpUrl, timeoutMs) {
77
+ const controller = new AbortController();
78
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
79
+ try {
80
+ const resp = await fetch(`${cdpUrl}/json/version`, { signal: controller.signal });
81
+ return resp.ok;
82
+ }
83
+ catch {
84
+ return false;
85
+ }
86
+ finally {
87
+ clearTimeout(timer);
88
+ }
89
+ }
90
+ export async function ensureChromeRunning(cdpUrl) {
91
+ // Already running?
92
+ if (await probeCdp(cdpUrl, 2000))
93
+ return;
94
+ const chromePath = await findChrome();
95
+ if (!chromePath) {
96
+ throw new Error("Chrome/Chromium not found. Install Chrome or use --cdp-url to point to an existing CDP endpoint.");
97
+ }
98
+ // Extract port from cdpUrl
99
+ let port = 9222;
100
+ try {
101
+ const url = new URL(cdpUrl);
102
+ if (url.port)
103
+ port = parseInt(url.port, 10);
104
+ }
105
+ catch {
106
+ // keep default
107
+ }
108
+ const dataDir = chromeDataDir();
109
+ console.error(`[mo-mcp] Launching Chrome: ${chromePath} (port ${port})`);
110
+ const child = spawn(chromePath, [
111
+ `--remote-debugging-port=${port}`,
112
+ "--remote-allow-origins=*",
113
+ "--no-first-run",
114
+ "--no-default-browser-check",
115
+ `--user-data-dir=${dataDir}`,
116
+ ], { detached: true, stdio: "ignore" });
117
+ child.unref();
118
+ // Poll for CDP readiness
119
+ const deadline = Date.now() + 10_000;
120
+ while (Date.now() < deadline) {
121
+ await new Promise((r) => setTimeout(r, 500));
122
+ if (await probeCdp(cdpUrl, 2000)) {
123
+ console.error("[mo-mcp] Chrome is ready.");
124
+ return;
125
+ }
126
+ }
127
+ throw new Error("Chrome launched but CDP not responding after 10s.");
128
+ }
129
+ //# sourceMappingURL=chrome-launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chrome-launcher.js","sourceRoot":"","sources":["../../src/browser/chrome-launcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Browser, Page } from "playwright-core";
2
+ export declare function connectBrowser(cdpUrl: string): Promise<Browser>;
3
+ export declare function getAllPages(cdpUrl: string): Promise<Page[]>;
4
+ export declare function getPageTargetId(page: Page): Promise<string | null>;
5
+ export declare function getPage(cdpUrl: string, targetId?: string): Promise<Page>;
6
+ export declare function disconnectBrowser(): Promise<void>;
7
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/browser/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAuCrE,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA4CrE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAGjE;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxE;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAY9E;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAIvD"}
@@ -0,0 +1,109 @@
1
+ import { chromium } from "playwright-core";
2
+ import { ensureChromeRunning, shouldLaunch } from "./chrome-launcher.js";
3
+ let cached = null;
4
+ let connecting = null;
5
+ function normalize(raw) {
6
+ return raw.replace(/\/$/, "");
7
+ }
8
+ async function getChromeWebSocketUrl(cdpUrl, timeout) {
9
+ const controller = new AbortController();
10
+ const timer = setTimeout(() => controller.abort(), timeout);
11
+ try {
12
+ const versionUrl = `${cdpUrl}/json/version`;
13
+ const resp = await fetch(versionUrl, { signal: controller.signal });
14
+ const json = (await resp.json());
15
+ return json.webSocketDebuggerUrl || null;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ finally {
21
+ clearTimeout(timer);
22
+ }
23
+ }
24
+ function observeBrowser(browser) {
25
+ for (const context of browser.contexts()) {
26
+ for (const page of context.pages()) {
27
+ // Pages will be observed on-demand via ensurePageState
28
+ }
29
+ }
30
+ }
31
+ export async function connectBrowser(cdpUrl) {
32
+ const normalized = normalize(cdpUrl);
33
+ if (cached?.cdpUrl === normalized) {
34
+ return cached.browser;
35
+ }
36
+ if (connecting) {
37
+ return (await connecting).browser;
38
+ }
39
+ if (shouldLaunch()) {
40
+ await ensureChromeRunning(normalized);
41
+ }
42
+ const connectWithRetry = async () => {
43
+ let lastErr;
44
+ for (let attempt = 0; attempt < 3; attempt++) {
45
+ try {
46
+ const timeout = 5000 + attempt * 2000;
47
+ const wsUrl = await getChromeWebSocketUrl(normalized, timeout);
48
+ const endpoint = wsUrl ?? normalized;
49
+ const browser = await chromium.connectOverCDP(endpoint, { timeout });
50
+ const connected = { browser, cdpUrl: normalized };
51
+ cached = connected;
52
+ observeBrowser(browser);
53
+ browser.on("disconnected", () => {
54
+ if (cached?.browser === browser)
55
+ cached = null;
56
+ });
57
+ return connected;
58
+ }
59
+ catch (err) {
60
+ lastErr = err;
61
+ const delay = 250 + attempt * 250;
62
+ await new Promise((r) => setTimeout(r, delay));
63
+ }
64
+ }
65
+ throw lastErr instanceof Error
66
+ ? lastErr
67
+ : new Error(String(lastErr ?? "CDP connect failed"));
68
+ };
69
+ connecting = connectWithRetry().finally(() => {
70
+ connecting = null;
71
+ });
72
+ return (await connecting).browser;
73
+ }
74
+ export async function getAllPages(cdpUrl) {
75
+ const browser = await connectBrowser(cdpUrl);
76
+ return browser.contexts().flatMap((c) => c.pages());
77
+ }
78
+ export async function getPageTargetId(page) {
79
+ const session = await page.context().newCDPSession(page);
80
+ try {
81
+ const info = (await session.send("Target.getTargetInfo"));
82
+ return String(info?.targetInfo?.targetId ?? "").trim() || null;
83
+ }
84
+ finally {
85
+ await session.detach().catch(() => { });
86
+ }
87
+ }
88
+ export async function getPage(cdpUrl, targetId) {
89
+ const pages = await getAllPages(cdpUrl);
90
+ if (!pages.length)
91
+ throw new Error("No pages available in the connected browser.");
92
+ if (!targetId)
93
+ return pages[0];
94
+ for (const page of pages) {
95
+ const tid = await getPageTargetId(page).catch(() => null);
96
+ if (tid === targetId)
97
+ return page;
98
+ }
99
+ if (pages.length === 1)
100
+ return pages[0];
101
+ throw new Error(`Tab "${targetId}" not found.`);
102
+ }
103
+ export async function disconnectBrowser() {
104
+ const cur = cached;
105
+ cached = null;
106
+ if (cur)
107
+ await cur.browser.close().catch(() => { });
108
+ }
109
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/browser/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function toAIFriendlyError(error: unknown, selector: string): Error;
2
+ export declare function parseRoleRef(raw: string): string | null;
3
+ export declare function requireRef(value: unknown): string;
4
+ export declare function normalizeTimeout(timeoutMs: number | undefined, fallback: number): number;
5
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/browser/errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CA8BzE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASvD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAMjD;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExF"}
@@ -0,0 +1,40 @@
1
+ export function toAIFriendlyError(error, selector) {
2
+ const message = error instanceof Error ? error.message : String(error);
3
+ if (message.includes("strict mode violation")) {
4
+ const count = message.match(/resolved to (\d+) elements/)?.[1] ?? "multiple";
5
+ return new Error(`Ref "${selector}" matched ${count} elements. Run browser_snapshot to get updated refs.`);
6
+ }
7
+ if ((message.includes("Timeout") || message.includes("waiting for")) &&
8
+ (message.includes("to be visible") || message.includes("not visible"))) {
9
+ return new Error(`Element "${selector}" not found or not visible. Run browser_snapshot to see current page.`);
10
+ }
11
+ if (message.includes("intercepts pointer events") ||
12
+ message.includes("not visible") ||
13
+ message.includes("not receive pointer events")) {
14
+ return new Error(`Element "${selector}" not interactable (hidden/covered). Try scrolling into view or closing overlays.`);
15
+ }
16
+ return error instanceof Error ? error : new Error(message);
17
+ }
18
+ export function parseRoleRef(raw) {
19
+ const trimmed = raw.trim();
20
+ if (!trimmed)
21
+ return null;
22
+ const normalized = trimmed.startsWith("@")
23
+ ? trimmed.slice(1)
24
+ : trimmed.startsWith("ref=")
25
+ ? trimmed.slice(4)
26
+ : trimmed;
27
+ return /^e\d+$/.test(normalized) ? normalized : null;
28
+ }
29
+ export function requireRef(value) {
30
+ const raw = typeof value === "string" ? value.trim() : "";
31
+ const roleRef = raw ? parseRoleRef(raw) : null;
32
+ const ref = roleRef ?? (raw.startsWith("@") ? raw.slice(1) : raw);
33
+ if (!ref)
34
+ throw new Error("ref is required");
35
+ return ref;
36
+ }
37
+ export function normalizeTimeout(timeoutMs, fallback) {
38
+ return Math.max(500, Math.min(120_000, timeoutMs ?? fallback));
39
+ }
40
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/browser/errors.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,QAAgB;IAChE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEvE,IAAI,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC;QAC7E,OAAO,IAAI,KAAK,CACd,QAAQ,QAAQ,aAAa,KAAK,sDAAsD,CACzF,CAAC;IACJ,CAAC;IAED,IACE,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAChE,CAAC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,EACtE,CAAC;QACD,OAAO,IAAI,KAAK,CACd,YAAY,QAAQ,uEAAuE,CAC5F,CAAC;IACJ,CAAC;IAED,IACE,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC/B,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAC9C,CAAC;QACD,OAAO,IAAI,KAAK,CACd,YAAY,QAAQ,mFAAmF,CACxG,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QACxC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;YAC1B,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC;IACd,OAAO,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,MAAM,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC7C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAA6B,EAAE,QAAgB;IAC9E,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Page } from "playwright-core";
2
+ import type { PageState } from "../types.js";
3
+ export declare function ensurePageState(page: Page): PageState;
4
+ export declare function getPageState(page: Page): PageState | undefined;
5
+ //# sourceMappingURL=page-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-state.d.ts","sourceRoot":"","sources":["../../src/browser/page-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAqC,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAA8E,MAAM,aAAa,CAAC;AASzH,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAiFrD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAE9D"}
@@ -0,0 +1,88 @@
1
+ const MAX_CONSOLE = 500;
2
+ const MAX_ERRORS = 200;
3
+ const MAX_REQUESTS = 500;
4
+ const pageStates = new WeakMap();
5
+ const observedPages = new WeakSet();
6
+ export function ensurePageState(page) {
7
+ const existing = pageStates.get(page);
8
+ if (existing)
9
+ return existing;
10
+ const state = {
11
+ console: [],
12
+ errors: [],
13
+ requests: [],
14
+ requestIds: new WeakMap(),
15
+ nextRequestId: 0,
16
+ };
17
+ pageStates.set(page, state);
18
+ if (!observedPages.has(page)) {
19
+ observedPages.add(page);
20
+ page.on("console", (msg) => {
21
+ state.console.push({
22
+ type: msg.type(),
23
+ text: msg.text(),
24
+ timestamp: new Date().toISOString(),
25
+ });
26
+ if (state.console.length > MAX_CONSOLE)
27
+ state.console.shift();
28
+ });
29
+ page.on("pageerror", (err) => {
30
+ state.errors.push({
31
+ message: err?.message ? String(err.message) : String(err),
32
+ name: err?.name ? String(err.name) : undefined,
33
+ stack: err?.stack ? String(err.stack) : undefined,
34
+ timestamp: new Date().toISOString(),
35
+ });
36
+ if (state.errors.length > MAX_ERRORS)
37
+ state.errors.shift();
38
+ });
39
+ page.on("request", (req) => {
40
+ state.nextRequestId += 1;
41
+ const id = `r${state.nextRequestId}`;
42
+ state.requestIds.set(req, id);
43
+ state.requests.push({
44
+ id,
45
+ timestamp: new Date().toISOString(),
46
+ method: req.method(),
47
+ url: req.url(),
48
+ resourceType: req.resourceType(),
49
+ });
50
+ if (state.requests.length > MAX_REQUESTS)
51
+ state.requests.shift();
52
+ });
53
+ page.on("response", (resp) => {
54
+ const req = resp.request();
55
+ const id = state.requestIds.get(req);
56
+ if (!id)
57
+ return;
58
+ for (let i = state.requests.length - 1; i >= 0; i--) {
59
+ if (state.requests[i]?.id === id) {
60
+ state.requests[i].status = resp.status();
61
+ state.requests[i].ok = resp.ok();
62
+ break;
63
+ }
64
+ }
65
+ });
66
+ page.on("requestfailed", (req) => {
67
+ const id = state.requestIds.get(req);
68
+ if (!id)
69
+ return;
70
+ for (let i = state.requests.length - 1; i >= 0; i--) {
71
+ if (state.requests[i]?.id === id) {
72
+ state.requests[i].failureText = req.failure()?.errorText;
73
+ state.requests[i].ok = false;
74
+ break;
75
+ }
76
+ }
77
+ });
78
+ page.on("close", () => {
79
+ pageStates.delete(page);
80
+ observedPages.delete(page);
81
+ });
82
+ }
83
+ return state;
84
+ }
85
+ export function getPageState(page) {
86
+ return pageStates.get(page);
87
+ }
88
+ //# sourceMappingURL=page-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-state.js","sourceRoot":"","sources":["../../src/browser/page-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Page } from "playwright-core";
2
+ import type { RoleRefMap } from "../types.js";
3
+ export declare function rememberRefs(opts: {
4
+ cdpUrl: string;
5
+ targetId: string;
6
+ refs: RoleRefMap;
7
+ frameSelector?: string;
8
+ mode?: "role" | "aria";
9
+ }): void;
10
+ export declare function restoreRefs(opts: {
11
+ cdpUrl: string;
12
+ targetId?: string;
13
+ page: Page;
14
+ }): void;
15
+ export declare function refLocator(page: Page, ref: string): import("playwright-core").Locator;
16
+ //# sourceMappingURL=refs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../src/browser/refs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAC;AAkBvD,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB,GAAG,IAAI,CAaP;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC;CACZ,GAAG,IAAI,CAUP;AAID,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,qCA2CjD"}
@@ -0,0 +1,67 @@
1
+ import { ensurePageState } from "./page-state.js";
2
+ const roleRefsByTarget = new Map();
3
+ const MAX_CACHE = 50;
4
+ function cacheKey(cdpUrl, targetId) {
5
+ return `${cdpUrl.replace(/\/$/, "")}::${targetId}`;
6
+ }
7
+ export function rememberRefs(opts) {
8
+ const tid = opts.targetId.trim();
9
+ if (!tid)
10
+ return;
11
+ roleRefsByTarget.set(cacheKey(opts.cdpUrl, tid), {
12
+ refs: opts.refs,
13
+ ...(opts.frameSelector ? { frameSelector: opts.frameSelector } : {}),
14
+ ...(opts.mode ? { mode: opts.mode } : {}),
15
+ });
16
+ while (roleRefsByTarget.size > MAX_CACHE) {
17
+ const first = roleRefsByTarget.keys().next();
18
+ if (first.done)
19
+ break;
20
+ roleRefsByTarget.delete(first.value);
21
+ }
22
+ }
23
+ export function restoreRefs(opts) {
24
+ const tid = opts.targetId?.trim() || "";
25
+ if (!tid)
26
+ return;
27
+ const entry = roleRefsByTarget.get(cacheKey(opts.cdpUrl, tid));
28
+ if (!entry)
29
+ return;
30
+ const state = ensurePageState(opts.page);
31
+ if (state.roleRefs)
32
+ return;
33
+ state.roleRefs = entry.refs;
34
+ state.roleRefsFrameSelector = entry.frameSelector;
35
+ state.roleRefsMode = entry.mode;
36
+ }
37
+ // ── Ref Resolution ─────────────────────────────────────────
38
+ export function refLocator(page, ref) {
39
+ const normalized = ref.startsWith("@")
40
+ ? ref.slice(1)
41
+ : ref.startsWith("ref=")
42
+ ? ref.slice(4)
43
+ : ref;
44
+ if (/^e\d+$/.test(normalized)) {
45
+ const state = ensurePageState(page);
46
+ if (state.roleRefsMode === "aria") {
47
+ const scope = state.roleRefsFrameSelector
48
+ ? page.frameLocator(state.roleRefsFrameSelector)
49
+ : page;
50
+ return scope.locator(`aria-ref=${normalized}`);
51
+ }
52
+ const info = state.roleRefs?.[normalized];
53
+ if (!info) {
54
+ throw new Error(`Unknown ref "${normalized}". Run browser_snapshot to get updated refs.`);
55
+ }
56
+ const scope = state.roleRefsFrameSelector
57
+ ? page.frameLocator(state.roleRefsFrameSelector)
58
+ : page;
59
+ const locAny = scope;
60
+ const locator = info.name
61
+ ? locAny.getByRole(info.role, { name: info.name, exact: true })
62
+ : locAny.getByRole(info.role);
63
+ return info.nth !== undefined ? locator.nth(info.nth) : locator;
64
+ }
65
+ return page.locator(`aria-ref=${normalized}`);
66
+ }
67
+ //# sourceMappingURL=refs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refs.js","sourceRoot":"","sources":["../../src/browser/refs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Page } from "playwright-core";
2
+ import type { RoleRefMap, RoleSnapshotOptions, SnapshotResult } from "../types.js";
3
+ export declare function buildRoleSnapshot(ariaSnapshot: string, options?: RoleSnapshotOptions): {
4
+ snapshot: string;
5
+ refs: RoleRefMap;
6
+ };
7
+ export declare function buildRoleSnapshotFromAi(aiSnapshot: string, options?: RoleSnapshotOptions): {
8
+ snapshot: string;
9
+ refs: RoleRefMap;
10
+ };
11
+ export declare function takeSnapshot(page: Page, cdpUrl: string, targetId: string | undefined, options?: RoleSnapshotOptions): Promise<SnapshotResult>;
12
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/browser/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAW,UAAU,EAAE,mBAAmB,EAAqB,cAAc,EAAE,MAAM,aAAa,CAAC;AA0F/G,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,mBAAwB,GAChC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CA0DxC;AASD,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,mBAAwB,GAChC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CAuCxC;AAID,wBAAsB,YAAY,CAChC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CAkCzB"}