@opentiny/webmcp-cli 0.0.6 → 0.0.8
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/README.md +17 -0
- package/dist/bin.cjs +139 -219
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +139 -219
- package/dist/bin.js.map +1 -1
- package/dist/index.cjs +101 -197
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +101 -197
- package/dist/index.js.map +1 -1
- package/dist/inject-bundle.js +1477 -936
- package/dist/webmcp-tools/editor.csdn.net.js +199 -9
- package/dist/webmcp-tools/juejin.cn.js +24454 -8
- package/dist/webmcp-tools/my.oschina.net.js +175 -33
- package/dist/webmcp-tools/segmentfault.com.js +157 -1
- package/dist/webmcp-tools/zhuanlan.zhihu.com.js +2261 -6
- package/package.json +8 -4
package/dist/inject-bundle.js
CHANGED
|
@@ -3104,9 +3104,9 @@
|
|
|
3104
3104
|
}
|
|
3105
3105
|
});
|
|
3106
3106
|
|
|
3107
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3107
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js
|
|
3108
3108
|
var require_utils = __commonJS({
|
|
3109
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3109
|
+
"../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/utils.js"(exports, module) {
|
|
3110
3110
|
"use strict";
|
|
3111
3111
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3112
3112
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
@@ -3417,9 +3417,9 @@
|
|
|
3417
3417
|
}
|
|
3418
3418
|
});
|
|
3419
3419
|
|
|
3420
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3420
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js
|
|
3421
3421
|
var require_schemes = __commonJS({
|
|
3422
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3422
|
+
"../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/lib/schemes.js"(exports, module) {
|
|
3423
3423
|
"use strict";
|
|
3424
3424
|
var { isUUID } = require_utils();
|
|
3425
3425
|
var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
|
|
@@ -3627,9 +3627,9 @@
|
|
|
3627
3627
|
}
|
|
3628
3628
|
});
|
|
3629
3629
|
|
|
3630
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
3630
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/index.js
|
|
3631
3631
|
var require_fast_uri = __commonJS({
|
|
3632
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
3632
|
+
"../../node_modules/.pnpm/fast-uri@3.1.5/node_modules/fast-uri/index.js"(exports, module) {
|
|
3633
3633
|
"use strict";
|
|
3634
3634
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
3635
3635
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
@@ -3645,7 +3645,12 @@
|
|
|
3645
3645
|
}
|
|
3646
3646
|
function resolve(baseURI, relativeURI, options) {
|
|
3647
3647
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3648
|
-
const
|
|
3648
|
+
const { parsed: baseParsed, malformedAuthorityOrPort: baseMalformed } = parseWithStatus(baseURI, schemelessOptions);
|
|
3649
|
+
const { parsed: relativeParsed, malformedAuthorityOrPort: relativeMalformed } = parseWithStatus(relativeURI, schemelessOptions);
|
|
3650
|
+
if (baseMalformed || relativeMalformed) {
|
|
3651
|
+
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
3652
|
+
}
|
|
3653
|
+
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
3649
3654
|
schemelessOptions.skipEscape = true;
|
|
3650
3655
|
return serialize(resolved, schemelessOptions);
|
|
3651
3656
|
}
|
|
@@ -3770,6 +3775,8 @@
|
|
|
3770
3775
|
return uriTokens.join("");
|
|
3771
3776
|
}
|
|
3772
3777
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
3778
|
+
var AUTHORITY_PREFIX = /^(?:[^#/:?]+:)?\/\/([^/?#]*)/;
|
|
3779
|
+
var AUTHORITY_INTRODUCER_REGION = /^(?:[^#/:?]+:)?([/\\\t\n\r]*)/;
|
|
3773
3780
|
function getParseError(parsed, matches2) {
|
|
3774
3781
|
if (matches2[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
3775
3782
|
return 'URI path must start with "/" when authority is present.';
|
|
@@ -3799,6 +3806,25 @@
|
|
|
3799
3806
|
uri2 = "//" + uri2;
|
|
3800
3807
|
}
|
|
3801
3808
|
}
|
|
3809
|
+
const authorityMatch = uri2.match(AUTHORITY_PREFIX);
|
|
3810
|
+
if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
|
|
3811
|
+
parsed.error = "URI authority must not contain a literal backslash.";
|
|
3812
|
+
malformedAuthorityOrPort = true;
|
|
3813
|
+
}
|
|
3814
|
+
const introducerMatch = uri2.match(AUTHORITY_INTRODUCER_REGION);
|
|
3815
|
+
if (introducerMatch !== null) {
|
|
3816
|
+
const region = introducerMatch[1];
|
|
3817
|
+
const normalizedRegion = region.replace(/[\t\n\r]/g, "");
|
|
3818
|
+
if (normalizedRegion.length >= 2) {
|
|
3819
|
+
if (normalizedRegion.slice(0, 2) !== "//") {
|
|
3820
|
+
parsed.error = parsed.error || "URI authority must not contain a literal backslash.";
|
|
3821
|
+
malformedAuthorityOrPort = true;
|
|
3822
|
+
} else if (region.length !== normalizedRegion.length) {
|
|
3823
|
+
parsed.error = parsed.error || "URI authority introducer must not contain whitespace.";
|
|
3824
|
+
malformedAuthorityOrPort = true;
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3802
3828
|
const matches2 = uri2.match(URI_PARSE);
|
|
3803
3829
|
if (matches2) {
|
|
3804
3830
|
parsed.scheme = matches2[1];
|
|
@@ -9569,7 +9595,7 @@ gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
|
9569
9595
|
}
|
|
9570
9596
|
});
|
|
9571
9597
|
|
|
9572
|
-
// ../../node_modules/.pnpm/@page-agent+page-controller@1.12.
|
|
9598
|
+
// ../../node_modules/.pnpm/@page-agent+page-controller@1.12.2/node_modules/@page-agent/page-controller/dist/lib/SimulatorMask-BHVXyogh.js
|
|
9573
9599
|
var SimulatorMask_BHVXyogh_exports = {};
|
|
9574
9600
|
__export(SimulatorMask_BHVXyogh_exports, {
|
|
9575
9601
|
SimulatorMask: () => SimulatorMask
|
|
@@ -9673,7 +9699,7 @@ gl_Position = vec4(aPosition, 0.0, 1.0);
|
|
|
9673
9699
|
}
|
|
9674
9700
|
var SimulatorMask_module_default, cursor_module_default, SimulatorMask;
|
|
9675
9701
|
var init_SimulatorMask_BHVXyogh = __esm({
|
|
9676
|
-
"../../node_modules/.pnpm/@page-agent+page-controller@1.12.
|
|
9702
|
+
"../../node_modules/.pnpm/@page-agent+page-controller@1.12.2/node_modules/@page-agent/page-controller/dist/lib/SimulatorMask-BHVXyogh.js"() {
|
|
9677
9703
|
init_Motion();
|
|
9678
9704
|
(function() {
|
|
9679
9705
|
try {
|
|
@@ -19606,7 +19632,7 @@ Known schemas:
|
|
|
19606
19632
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/classic/external.js
|
|
19607
19633
|
config(en_default2());
|
|
19608
19634
|
|
|
19609
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.
|
|
19635
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.13.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
19610
19636
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
19611
19637
|
var JSONRPC_VERSION = "2.0";
|
|
19612
19638
|
var AssertObjectSchema = custom2((v) => v !== null && (typeof v === "object" || typeof v === "function"));
|
|
@@ -22359,14 +22385,14 @@ Known schemas:
|
|
|
22359
22385
|
return combined;
|
|
22360
22386
|
};
|
|
22361
22387
|
|
|
22362
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.
|
|
22388
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.13.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
22363
22389
|
var import_ajv_formats = __toESM(require_dist(), 1);
|
|
22364
22390
|
|
|
22365
22391
|
// ../../node_modules/.pnpm/pkce-challenge@5.0.1/node_modules/pkce-challenge/dist/index.browser.js
|
|
22366
22392
|
var crypto2;
|
|
22367
22393
|
crypto2 = globalThis.crypto;
|
|
22368
22394
|
|
|
22369
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.
|
|
22395
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.13.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js
|
|
22370
22396
|
var SafeUrlSchema = url().superRefine((val, ctx) => {
|
|
22371
22397
|
if (!URL.canParse(val)) {
|
|
22372
22398
|
ctx.addIssue({
|
|
@@ -22510,7 +22536,7 @@ Known schemas:
|
|
|
22510
22536
|
token_type_hint: string2().optional()
|
|
22511
22537
|
}).strip();
|
|
22512
22538
|
|
|
22513
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.
|
|
22539
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.13.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/errors.js
|
|
22514
22540
|
var OAuthError = class extends Error {
|
|
22515
22541
|
constructor(message, errorUri) {
|
|
22516
22542
|
super(message);
|
|
@@ -22605,7 +22631,7 @@ Known schemas:
|
|
|
22605
22631
|
[InvalidTargetError.errorCode]: InvalidTargetError
|
|
22606
22632
|
};
|
|
22607
22633
|
|
|
22608
|
-
// ../../node_modules/.pnpm/@opentiny+next@0.3.2_@cfworker+json-schema@4.1.1_hono@4.
|
|
22634
|
+
// ../../node_modules/.pnpm/@opentiny+next@0.3.2_@cfworker+json-schema@4.1.1_hono@4.13.0_zod@3.25.76/node_modules/@opentiny/next/index.js
|
|
22609
22635
|
var _0x4f2826 = _0xad7a;
|
|
22610
22636
|
(function(_0x5153c5, _0x3abbea) {
|
|
22611
22637
|
const _0x5f186f = _0xad7a, _0x3f8155 = _0xad7a, _0x5ad68c = _0x5153c5();
|
|
@@ -22929,7 +22955,7 @@ Known schemas:
|
|
|
22929
22955
|
}, _0x275e(_0x25fced, _0x3ae797);
|
|
22930
22956
|
}
|
|
22931
22957
|
|
|
22932
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.
|
|
22958
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.25.3_@cfworker+json-schema@4.1.1_hono@4.13.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
22933
22959
|
var COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
|
|
22934
22960
|
var McpZodTypeKind;
|
|
22935
22961
|
(function(McpZodTypeKind2) {
|
|
@@ -23005,476 +23031,6 @@ Known schemas:
|
|
|
23005
23031
|
document.head.appendChild(style);
|
|
23006
23032
|
})();
|
|
23007
23033
|
|
|
23008
|
-
// ../next-sdk/utils/uuid.ts
|
|
23009
|
-
var randomUUID2 = () => {
|
|
23010
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
23011
|
-
return crypto.randomUUID();
|
|
23012
|
-
}
|
|
23013
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
23014
|
-
const r = Math.random() * 16 | 0;
|
|
23015
|
-
const v = c === "x" ? r : r & 3 | 8;
|
|
23016
|
-
return v.toString(16);
|
|
23017
|
-
});
|
|
23018
|
-
};
|
|
23019
|
-
|
|
23020
|
-
// ../next-sdk/utils/env.ts
|
|
23021
|
-
var isBrowser = () => {
|
|
23022
|
-
return typeof window !== "undefined" && typeof navigator !== "undefined";
|
|
23023
|
-
};
|
|
23024
|
-
var isDomAvailable = () => {
|
|
23025
|
-
return isBrowser() && typeof document !== "undefined";
|
|
23026
|
-
};
|
|
23027
|
-
|
|
23028
|
-
// ../next-sdk/page-tools/effects.ts
|
|
23029
|
-
var overlayElement = null;
|
|
23030
|
-
var labelElement = null;
|
|
23031
|
-
var styleElement = null;
|
|
23032
|
-
var activeCount = 0;
|
|
23033
|
-
var BODY_GLOW_CLASS = "next-sdk-tool-body-glow";
|
|
23034
|
-
function ensureDomReady() {
|
|
23035
|
-
return isDomAvailable();
|
|
23036
|
-
}
|
|
23037
|
-
function ensureStyleElement() {
|
|
23038
|
-
if (!ensureDomReady()) return;
|
|
23039
|
-
if (styleElement) return;
|
|
23040
|
-
const style = document.createElement("style");
|
|
23041
|
-
style.textContent = `
|
|
23042
|
-
.${BODY_GLOW_CLASS} {
|
|
23043
|
-
position: relative;
|
|
23044
|
-
}
|
|
23045
|
-
|
|
23046
|
-
.next-sdk-tool-overlay {
|
|
23047
|
-
position: fixed;
|
|
23048
|
-
inset: 0;
|
|
23049
|
-
z-index: 999999;
|
|
23050
|
-
pointer-events: none;
|
|
23051
|
-
display: flex;
|
|
23052
|
-
align-items: flex-end;
|
|
23053
|
-
justify-content: flex-start;
|
|
23054
|
-
padding: 0 0 18px 18px;
|
|
23055
|
-
background: transparent;
|
|
23056
|
-
animation: next-sdk-overlay-fade-in 260ms ease-out;
|
|
23057
|
-
}
|
|
23058
|
-
|
|
23059
|
-
.next-sdk-tool-overlay--exit {
|
|
23060
|
-
animation: next-sdk-overlay-fade-out 220ms ease-in forwards;
|
|
23061
|
-
}
|
|
23062
|
-
|
|
23063
|
-
.next-sdk-tool-overlay__glow-ring {
|
|
23064
|
-
display: none;
|
|
23065
|
-
}
|
|
23066
|
-
|
|
23067
|
-
.next-sdk-tool-overlay__panel {
|
|
23068
|
-
position: relative;
|
|
23069
|
-
min-width: min(320px, 78vw);
|
|
23070
|
-
max-width: min(420px, 82vw);
|
|
23071
|
-
padding: 10px 14px;
|
|
23072
|
-
border-radius: 999px;
|
|
23073
|
-
background:
|
|
23074
|
-
linear-gradient(135deg, rgba(15, 23, 42, 0.9), rgba(17, 24, 39, 0.9)),
|
|
23075
|
-
radial-gradient(circle at top left, rgba(96, 165, 250, 0.25), transparent 55%),
|
|
23076
|
-
radial-gradient(circle at bottom right, rgba(45, 212, 191, 0.22), transparent 60%);
|
|
23077
|
-
box-shadow:
|
|
23078
|
-
0 12px 28px rgba(15, 23, 42, 0.78),
|
|
23079
|
-
0 0 0 1px rgba(148, 163, 184, 0.26);
|
|
23080
|
-
display: flex;
|
|
23081
|
-
align-items: center;
|
|
23082
|
-
gap: 10px;
|
|
23083
|
-
pointer-events: none;
|
|
23084
|
-
transform-origin: center;
|
|
23085
|
-
animation: next-sdk-panel-pop-in 260ms cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
|
23086
|
-
color: #e5e7eb;
|
|
23087
|
-
font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif;
|
|
23088
|
-
}
|
|
23089
|
-
|
|
23090
|
-
.next-sdk-tool-overlay__indicator {
|
|
23091
|
-
width: 26px;
|
|
23092
|
-
height: 26px;
|
|
23093
|
-
border-radius: 999px;
|
|
23094
|
-
background: radial-gradient(circle at 30% 10%, #f9fafb, #93c5fd);
|
|
23095
|
-
box-shadow:
|
|
23096
|
-
0 0 0 1px rgba(191, 219, 254, 0.6),
|
|
23097
|
-
0 8px 18px rgba(37, 99, 235, 0.8),
|
|
23098
|
-
0 0 28px rgba(56, 189, 248, 0.9);
|
|
23099
|
-
position: relative;
|
|
23100
|
-
flex-shrink: 0;
|
|
23101
|
-
display: flex;
|
|
23102
|
-
align-items: center;
|
|
23103
|
-
justify-content: center;
|
|
23104
|
-
overflow: hidden;
|
|
23105
|
-
}
|
|
23106
|
-
|
|
23107
|
-
.next-sdk-tool-overlay__indicator-orbit {
|
|
23108
|
-
position: absolute;
|
|
23109
|
-
inset: 2px;
|
|
23110
|
-
border-radius: inherit;
|
|
23111
|
-
border: 1px solid rgba(248, 250, 252, 0.6);
|
|
23112
|
-
box-sizing: border-box;
|
|
23113
|
-
opacity: 0.9;
|
|
23114
|
-
}
|
|
23115
|
-
|
|
23116
|
-
.next-sdk-tool-overlay__indicator-orbit::before {
|
|
23117
|
-
content: '';
|
|
23118
|
-
position: absolute;
|
|
23119
|
-
width: 6px;
|
|
23120
|
-
height: 6px;
|
|
23121
|
-
border-radius: 999px;
|
|
23122
|
-
background: #f9fafb;
|
|
23123
|
-
box-shadow:
|
|
23124
|
-
0 0 12px rgba(248, 250, 252, 0.9),
|
|
23125
|
-
0 0 24px rgba(250, 249, 246, 0.9);
|
|
23126
|
-
top: 0;
|
|
23127
|
-
left: 50%;
|
|
23128
|
-
transform: translate(-50%, -50%);
|
|
23129
|
-
transform-origin: 50% 18px;
|
|
23130
|
-
animation: next-sdk-indicator-orbit 1.4s linear infinite;
|
|
23131
|
-
}
|
|
23132
|
-
|
|
23133
|
-
.next-sdk-tool-overlay__indicator-core {
|
|
23134
|
-
width: 14px;
|
|
23135
|
-
height: 14px;
|
|
23136
|
-
border-radius: inherit;
|
|
23137
|
-
background: radial-gradient(circle at 30% 20%, #f9fafb, #bfdbfe);
|
|
23138
|
-
box-shadow:
|
|
23139
|
-
0 0 12px rgba(248, 250, 252, 0.9),
|
|
23140
|
-
0 0 32px rgba(191, 219, 254, 0.8);
|
|
23141
|
-
opacity: 0.96;
|
|
23142
|
-
}
|
|
23143
|
-
|
|
23144
|
-
.next-sdk-tool-overlay__content {
|
|
23145
|
-
display: flex;
|
|
23146
|
-
flex-direction: column;
|
|
23147
|
-
gap: 1px;
|
|
23148
|
-
min-width: 0;
|
|
23149
|
-
}
|
|
23150
|
-
|
|
23151
|
-
.next-sdk-tool-overlay__title {
|
|
23152
|
-
font-size: 11px;
|
|
23153
|
-
letter-spacing: 0.08em;
|
|
23154
|
-
text-transform: uppercase;
|
|
23155
|
-
color: rgba(156, 163, 175, 0.96);
|
|
23156
|
-
display: flex;
|
|
23157
|
-
align-items: center;
|
|
23158
|
-
gap: 6px;
|
|
23159
|
-
}
|
|
23160
|
-
|
|
23161
|
-
.next-sdk-tool-overlay__title-dot {
|
|
23162
|
-
width: 6px;
|
|
23163
|
-
height: 6px;
|
|
23164
|
-
border-radius: 999px;
|
|
23165
|
-
background: #22c55e;
|
|
23166
|
-
box-shadow:
|
|
23167
|
-
0 0 8px rgba(34, 197, 94, 0.9),
|
|
23168
|
-
0 0 14px rgba(22, 163, 74, 0.9);
|
|
23169
|
-
}
|
|
23170
|
-
|
|
23171
|
-
.next-sdk-tool-overlay__label {
|
|
23172
|
-
font-size: 12px;
|
|
23173
|
-
font-weight: 500;
|
|
23174
|
-
color: #e5e7eb;
|
|
23175
|
-
white-space: nowrap;
|
|
23176
|
-
text-overflow: ellipsis;
|
|
23177
|
-
overflow: hidden;
|
|
23178
|
-
}
|
|
23179
|
-
|
|
23180
|
-
@keyframes next-sdk-overlay-fade-in {
|
|
23181
|
-
from { opacity: 0; }
|
|
23182
|
-
to { opacity: 1; }
|
|
23183
|
-
}
|
|
23184
|
-
|
|
23185
|
-
@keyframes next-sdk-overlay-fade-out {
|
|
23186
|
-
from { opacity: 1; }
|
|
23187
|
-
to { opacity: 0; }
|
|
23188
|
-
}
|
|
23189
|
-
|
|
23190
|
-
@keyframes next-sdk-indicator-orbit {
|
|
23191
|
-
from {
|
|
23192
|
-
transform: translate(-50%, -50%) rotate(0deg) translateY(0);
|
|
23193
|
-
}
|
|
23194
|
-
to {
|
|
23195
|
-
transform: translate(-50%, -50%) rotate(360deg) translateY(0);
|
|
23196
|
-
}
|
|
23197
|
-
}
|
|
23198
|
-
|
|
23199
|
-
@keyframes next-sdk-panel-pop-in {
|
|
23200
|
-
0% {
|
|
23201
|
-
opacity: 0;
|
|
23202
|
-
transform: scale(0.92) translateY(10px);
|
|
23203
|
-
}
|
|
23204
|
-
100% {
|
|
23205
|
-
opacity: 1;
|
|
23206
|
-
transform: scale(1) translateY(0);
|
|
23207
|
-
}
|
|
23208
|
-
}
|
|
23209
|
-
`;
|
|
23210
|
-
document.head.appendChild(style);
|
|
23211
|
-
styleElement = style;
|
|
23212
|
-
}
|
|
23213
|
-
function ensureOverlayElement() {
|
|
23214
|
-
if (!ensureDomReady()) return;
|
|
23215
|
-
if (overlayElement) return;
|
|
23216
|
-
ensureStyleElement();
|
|
23217
|
-
const overlay = document.createElement("div");
|
|
23218
|
-
overlay.className = "next-sdk-tool-overlay";
|
|
23219
|
-
const glowRing = document.createElement("div");
|
|
23220
|
-
glowRing.className = "next-sdk-tool-overlay__glow-ring";
|
|
23221
|
-
const panel = document.createElement("div");
|
|
23222
|
-
panel.className = "next-sdk-tool-overlay__panel";
|
|
23223
|
-
const indicator = document.createElement("div");
|
|
23224
|
-
indicator.className = "next-sdk-tool-overlay__indicator";
|
|
23225
|
-
const indicatorOrbit = document.createElement("div");
|
|
23226
|
-
indicatorOrbit.className = "next-sdk-tool-overlay__indicator-orbit";
|
|
23227
|
-
const indicatorCore = document.createElement("div");
|
|
23228
|
-
indicatorCore.className = "next-sdk-tool-overlay__indicator-core";
|
|
23229
|
-
const content = document.createElement("div");
|
|
23230
|
-
content.className = "next-sdk-tool-overlay__content";
|
|
23231
|
-
const titleRow = document.createElement("div");
|
|
23232
|
-
titleRow.className = "next-sdk-tool-overlay__title";
|
|
23233
|
-
titleRow.textContent = "AI \u6B63\u5728\u8C03\u7528\u9875\u9762\u5DE5\u5177";
|
|
23234
|
-
const titleDot = document.createElement("span");
|
|
23235
|
-
titleDot.className = "next-sdk-tool-overlay__title-dot";
|
|
23236
|
-
const label = document.createElement("div");
|
|
23237
|
-
label.className = "next-sdk-tool-overlay__label";
|
|
23238
|
-
titleRow.prepend(titleDot);
|
|
23239
|
-
content.appendChild(titleRow);
|
|
23240
|
-
content.appendChild(label);
|
|
23241
|
-
indicator.appendChild(indicatorOrbit);
|
|
23242
|
-
indicator.appendChild(indicatorCore);
|
|
23243
|
-
panel.appendChild(indicator);
|
|
23244
|
-
panel.appendChild(content);
|
|
23245
|
-
overlay.appendChild(glowRing);
|
|
23246
|
-
overlay.appendChild(panel);
|
|
23247
|
-
document.body.appendChild(overlay);
|
|
23248
|
-
overlayElement = overlay;
|
|
23249
|
-
labelElement = label;
|
|
23250
|
-
}
|
|
23251
|
-
function updateOverlay(config2) {
|
|
23252
|
-
if (!ensureDomReady()) return;
|
|
23253
|
-
ensureOverlayElement();
|
|
23254
|
-
if (!overlayElement || !labelElement) return;
|
|
23255
|
-
overlayElement.classList.remove("next-sdk-tool-overlay--exit");
|
|
23256
|
-
labelElement.textContent = config2.label;
|
|
23257
|
-
}
|
|
23258
|
-
function removeOverlayWithAnimation() {
|
|
23259
|
-
if (!overlayElement) return;
|
|
23260
|
-
overlayElement.classList.add("next-sdk-tool-overlay--exit");
|
|
23261
|
-
const localOverlay = overlayElement;
|
|
23262
|
-
let handled = false;
|
|
23263
|
-
let timerId;
|
|
23264
|
-
const handle = () => {
|
|
23265
|
-
if (handled) return;
|
|
23266
|
-
handled = true;
|
|
23267
|
-
if (timerId !== void 0) {
|
|
23268
|
-
clearTimeout(timerId);
|
|
23269
|
-
timerId = void 0;
|
|
23270
|
-
}
|
|
23271
|
-
if (localOverlay.parentNode) {
|
|
23272
|
-
localOverlay.parentNode.removeChild(localOverlay);
|
|
23273
|
-
}
|
|
23274
|
-
if (overlayElement === localOverlay) {
|
|
23275
|
-
overlayElement = null;
|
|
23276
|
-
labelElement = null;
|
|
23277
|
-
}
|
|
23278
|
-
localOverlay.removeEventListener("animationend", handle);
|
|
23279
|
-
};
|
|
23280
|
-
localOverlay.addEventListener("animationend", handle);
|
|
23281
|
-
timerId = setTimeout(handle, 500);
|
|
23282
|
-
}
|
|
23283
|
-
function showToolInvokeEffect(config2) {
|
|
23284
|
-
if (!ensureDomReady()) return;
|
|
23285
|
-
activeCount += 1;
|
|
23286
|
-
updateOverlay(config2);
|
|
23287
|
-
}
|
|
23288
|
-
function hideToolInvokeEffect() {
|
|
23289
|
-
if (!ensureDomReady() || activeCount <= 0) return;
|
|
23290
|
-
activeCount -= 1;
|
|
23291
|
-
if (activeCount === 0) {
|
|
23292
|
-
removeOverlayWithAnimation();
|
|
23293
|
-
}
|
|
23294
|
-
}
|
|
23295
|
-
function resolveRuntimeEffectConfig(toolName, toolTitle, value) {
|
|
23296
|
-
if (!value) return void 0;
|
|
23297
|
-
const baseLabel = toolTitle || toolName;
|
|
23298
|
-
if (typeof value === "boolean") {
|
|
23299
|
-
return value ? { label: baseLabel } : void 0;
|
|
23300
|
-
}
|
|
23301
|
-
return {
|
|
23302
|
-
label: value.label || baseLabel
|
|
23303
|
-
};
|
|
23304
|
-
}
|
|
23305
|
-
|
|
23306
|
-
// ../next-sdk/page-tools/bridge.ts
|
|
23307
|
-
var MSG_TOOL_CALL = "next-sdk:tool-call";
|
|
23308
|
-
var MSG_TOOL_RESPONSE = "next-sdk:tool-response";
|
|
23309
|
-
var MSG_TOOL_REGISTERED = "next-sdk:tool-registered";
|
|
23310
|
-
var MSG_TOOL_UNREGISTERED = "next-sdk:tool-unregistered";
|
|
23311
|
-
var MSG_REMOTER_READY = "next-sdk:remoter-ready";
|
|
23312
|
-
var activePages = /* @__PURE__ */ new Map();
|
|
23313
|
-
var normalizeRoute = (value) => value.replace(/\/+$/, "") || "/";
|
|
23314
|
-
var broadcastTargets = /* @__PURE__ */ new Set();
|
|
23315
|
-
function initBroadcastTargets() {
|
|
23316
|
-
if (isBrowser()) {
|
|
23317
|
-
broadcastTargets.add({ win: window, origin: window.location.origin || "*" });
|
|
23318
|
-
}
|
|
23319
|
-
}
|
|
23320
|
-
initBroadcastTargets();
|
|
23321
|
-
function broadcastToolChange(type) {
|
|
23322
|
-
if (!isBrowser()) return;
|
|
23323
|
-
const msg = { type };
|
|
23324
|
-
broadcastTargets.forEach(({ win, origin }) => {
|
|
23325
|
-
try {
|
|
23326
|
-
win.postMessage(msg, origin);
|
|
23327
|
-
} catch {
|
|
23328
|
-
}
|
|
23329
|
-
});
|
|
23330
|
-
}
|
|
23331
|
-
function setupIframeRemoterBridge() {
|
|
23332
|
-
if (!isBrowser()) return;
|
|
23333
|
-
window.addEventListener("message", (event) => {
|
|
23334
|
-
if (event.data?.type !== MSG_REMOTER_READY || !event.source) return;
|
|
23335
|
-
if (event.origin !== window.location.origin) return;
|
|
23336
|
-
const target = event.source;
|
|
23337
|
-
broadcastTargets.add({ win: target, origin: event.origin || "*" });
|
|
23338
|
-
});
|
|
23339
|
-
}
|
|
23340
|
-
setupIframeRemoterBridge();
|
|
23341
|
-
function isToolReadyOnRoute(route, toolName) {
|
|
23342
|
-
const toolNames = activePages.get(route);
|
|
23343
|
-
return !!toolNames && toolNames.has(toolName);
|
|
23344
|
-
}
|
|
23345
|
-
var _navigator = null;
|
|
23346
|
-
function buildPageHandler(name, route, timeout = 3e4, effectConfig) {
|
|
23347
|
-
return (input) => {
|
|
23348
|
-
const callId = randomUUID2();
|
|
23349
|
-
return new Promise((resolve, reject) => {
|
|
23350
|
-
let timer;
|
|
23351
|
-
let readyHandler;
|
|
23352
|
-
const cleanup = () => {
|
|
23353
|
-
clearTimeout(timer);
|
|
23354
|
-
window.removeEventListener("message", responseHandler);
|
|
23355
|
-
if (readyHandler) {
|
|
23356
|
-
window.removeEventListener("message", readyHandler);
|
|
23357
|
-
}
|
|
23358
|
-
if (effectConfig) {
|
|
23359
|
-
hideToolInvokeEffect();
|
|
23360
|
-
}
|
|
23361
|
-
};
|
|
23362
|
-
timer = setTimeout(() => {
|
|
23363
|
-
cleanup();
|
|
23364
|
-
reject(new Error(`\u5DE5\u5177 [${name}] \u8C03\u7528\u8D85\u65F6 (${timeout}ms)\uFF0C\u8BF7\u68C0\u67E5\u76EE\u6807\u9875\u9762\u662F\u5426\u6B63\u786E\u8C03\u7528\u4E86 registerPageTool`));
|
|
23365
|
-
}, timeout);
|
|
23366
|
-
const responseHandler = (event) => {
|
|
23367
|
-
if (event.source === window && event.data?.type === MSG_TOOL_RESPONSE && event.data.callId === callId) {
|
|
23368
|
-
cleanup();
|
|
23369
|
-
event.data.error ? reject(new Error(event.data.error)) : resolve(event.data.result);
|
|
23370
|
-
}
|
|
23371
|
-
};
|
|
23372
|
-
window.addEventListener("message", responseHandler);
|
|
23373
|
-
const sendCall = () => {
|
|
23374
|
-
window.postMessage({ type: MSG_TOOL_CALL, callId, toolName: name, route, input }, window.location.origin || "*");
|
|
23375
|
-
};
|
|
23376
|
-
let callSent = false;
|
|
23377
|
-
const sendCallOnce = () => {
|
|
23378
|
-
if (callSent) return;
|
|
23379
|
-
callSent = true;
|
|
23380
|
-
sendCall();
|
|
23381
|
-
};
|
|
23382
|
-
const run = async () => {
|
|
23383
|
-
try {
|
|
23384
|
-
if (effectConfig) {
|
|
23385
|
-
showToolInvokeEffect(effectConfig);
|
|
23386
|
-
}
|
|
23387
|
-
if (isToolReadyOnRoute(route, name)) {
|
|
23388
|
-
sendCallOnce();
|
|
23389
|
-
return;
|
|
23390
|
-
}
|
|
23391
|
-
readyHandler = (event) => {
|
|
23392
|
-
if (event.source !== window || event.data?.type !== MSG_TOOL_REGISTERED) return;
|
|
23393
|
-
window.removeEventListener("message", readyHandler);
|
|
23394
|
-
sendCallOnce();
|
|
23395
|
-
};
|
|
23396
|
-
window.addEventListener("message", readyHandler);
|
|
23397
|
-
if (_navigator) {
|
|
23398
|
-
const isReady = await _navigator(route);
|
|
23399
|
-
if (isReady === true) {
|
|
23400
|
-
if (readyHandler) {
|
|
23401
|
-
window.removeEventListener("message", readyHandler);
|
|
23402
|
-
}
|
|
23403
|
-
sendCallOnce();
|
|
23404
|
-
return;
|
|
23405
|
-
}
|
|
23406
|
-
}
|
|
23407
|
-
if (isToolReadyOnRoute(route, name)) {
|
|
23408
|
-
window.removeEventListener("message", readyHandler);
|
|
23409
|
-
sendCallOnce();
|
|
23410
|
-
}
|
|
23411
|
-
} catch (err) {
|
|
23412
|
-
cleanup();
|
|
23413
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
23414
|
-
}
|
|
23415
|
-
};
|
|
23416
|
-
void run();
|
|
23417
|
-
});
|
|
23418
|
-
};
|
|
23419
|
-
}
|
|
23420
|
-
var _registeredTools = /* @__PURE__ */ new Map();
|
|
23421
|
-
function setupModelContextBridge() {
|
|
23422
|
-
if (typeof document === "undefined") return;
|
|
23423
|
-
const doc = document;
|
|
23424
|
-
const nativeCtx = doc.modelContext;
|
|
23425
|
-
if (!nativeCtx || nativeCtx.__isNextSdkBridgeSetup) return;
|
|
23426
|
-
if (isBrowser()) {
|
|
23427
|
-
;
|
|
23428
|
-
window.__nextSdkRegisteredTools = () => Array.from(_registeredTools.values());
|
|
23429
|
-
}
|
|
23430
|
-
const originalRegisterTool = nativeCtx.registerTool?.bind(nativeCtx);
|
|
23431
|
-
const originalUnregisterTool = nativeCtx.unregisterTool?.bind(nativeCtx);
|
|
23432
|
-
if (typeof originalRegisterTool === "function") {
|
|
23433
|
-
nativeCtx.registerTool = (config2, options) => {
|
|
23434
|
-
const name = config2.name;
|
|
23435
|
-
const toolConfig = { ...config2 };
|
|
23436
|
-
if (options?.signal) {
|
|
23437
|
-
options.signal.addEventListener("abort", () => {
|
|
23438
|
-
_registeredTools.delete(name);
|
|
23439
|
-
broadcastToolChange(MSG_TOOL_UNREGISTERED);
|
|
23440
|
-
});
|
|
23441
|
-
}
|
|
23442
|
-
const routeConfig = toolConfig.routeConfig && typeof toolConfig.routeConfig === "object" && "route" in toolConfig.routeConfig ? toolConfig.routeConfig : null;
|
|
23443
|
-
if (routeConfig) {
|
|
23444
|
-
const normalizedRoute = normalizeRoute(routeConfig.route);
|
|
23445
|
-
const effectConfig = resolveRuntimeEffectConfig(name, toolConfig.title, routeConfig.invokeEffect);
|
|
23446
|
-
const pageHandler = buildPageHandler(name, normalizedRoute, routeConfig.timeout, effectConfig);
|
|
23447
|
-
toolConfig.execute = pageHandler;
|
|
23448
|
-
delete toolConfig.routeConfig;
|
|
23449
|
-
}
|
|
23450
|
-
_registeredTools.set(name, {
|
|
23451
|
-
name,
|
|
23452
|
-
title: config2.title,
|
|
23453
|
-
description: config2.description,
|
|
23454
|
-
inputSchema: config2.inputSchema
|
|
23455
|
-
});
|
|
23456
|
-
try {
|
|
23457
|
-
originalRegisterTool(toolConfig, options);
|
|
23458
|
-
broadcastToolChange(MSG_TOOL_REGISTERED);
|
|
23459
|
-
} catch (err) {
|
|
23460
|
-
_registeredTools.delete(name);
|
|
23461
|
-
}
|
|
23462
|
-
};
|
|
23463
|
-
}
|
|
23464
|
-
nativeCtx.unregisterTool = (name) => {
|
|
23465
|
-
try {
|
|
23466
|
-
if (typeof originalUnregisterTool === "function") {
|
|
23467
|
-
originalUnregisterTool(name);
|
|
23468
|
-
}
|
|
23469
|
-
} catch (err) {
|
|
23470
|
-
} finally {
|
|
23471
|
-
_registeredTools.delete(name);
|
|
23472
|
-
broadcastToolChange(MSG_TOOL_UNREGISTERED);
|
|
23473
|
-
}
|
|
23474
|
-
};
|
|
23475
|
-
nativeCtx.__isNextSdkBridgeSetup = true;
|
|
23476
|
-
}
|
|
23477
|
-
|
|
23478
23034
|
// ../next-sdk/skills/index.ts
|
|
23479
23035
|
var SKILL_INPUT_SCHEMA = external_exports.object({
|
|
23480
23036
|
skillName: external_exports.string().optional().describe(
|
|
@@ -23486,6 +23042,11 @@ Known schemas:
|
|
|
23486
23042
|
)
|
|
23487
23043
|
});
|
|
23488
23044
|
|
|
23045
|
+
// ../next-sdk/utils/env.ts
|
|
23046
|
+
var isBrowser = () => {
|
|
23047
|
+
return typeof window !== "undefined" && typeof navigator !== "undefined";
|
|
23048
|
+
};
|
|
23049
|
+
|
|
23489
23050
|
// ../next-sdk/page-tools/initialize-builtin-WebMCP.ts
|
|
23490
23051
|
var initialized = false;
|
|
23491
23052
|
var initializeBuiltinWebMCP = () => {
|
|
@@ -23493,18 +23054,17 @@ Known schemas:
|
|
|
23493
23054
|
try {
|
|
23494
23055
|
if (initialized) return;
|
|
23495
23056
|
initializeWebMCPPolyfill();
|
|
23496
|
-
setupModelContextBridge();
|
|
23497
23057
|
initialized = true;
|
|
23498
23058
|
} catch (err) {
|
|
23499
|
-
console.warn("[next-sdk] \u81EA\u52A8\u6CE8\u5165 modelContext polyfill \
|
|
23059
|
+
console.warn("[next-sdk] \u81EA\u52A8\u6CE8\u5165 modelContext polyfill \u5931\u8D25:", err);
|
|
23500
23060
|
}
|
|
23501
23061
|
}
|
|
23502
23062
|
};
|
|
23503
23063
|
|
|
23504
23064
|
// query-loader:/home/runner/work/webmcp-sdk/webmcp-sdk/packages/next-sdk/page-tools/page-agent-prompt.md
|
|
23505
|
-
var page_agent_prompt_default = '## \u89D2\u8272\n\n\u4F60\u662F\u6D4F\u89C8\u5668\u9875\u9762\u7684\u64CD\u4F5C\u5DE5\u5177\uFF0C\u4F60\u62E5\u6709\u8BC6\u522B\u7F51\u9875\u5185\u5BB9\uFF0C\u70B9\u51FB\uFF0C\u586B\u5199\uFF0C\u9009\u62E9\u4E0B\u62C9\u6846\u548C\u6EDA\u52A8\u9875\u9762\u7B49\u529F\u80FD\u3002\n\n\u5728\u6267\u884C\u9875\u9762\u64CD\u4F5C\u4E4B\u524D\uFF0C\u4F60\u5FC5\u987B\u5148\u8C03\u7528`browserState`\u5DE5\u5177\u4E00\u6B21\uFF0C\u6839\u636E\u6700\u65B0\u7684\u7F51\u9875\u72B6\u6001\uFF0C\u518D\u8C03\u7528\u64CD\u4F5C\u52A8\u4F5C\uFF0C\u6BD4\u5982 \'click\',\'fill\',\'select\' \u7B49\u52A8\u4F5C\u3002\n\n<intro>\n\u4F60\u64C5\u957F\u4EE5\u4E0B\u4EFB\u52A1\uFF1A\n1. \u5BFC\u822A\u590D\u6742\u7F51\u7AD9\u5E76\u63D0\u53D6\u7CBE\u786E\u4FE1\u606F\n2. \u81EA\u52A8\u5316\u8868\u5355\u63D0\u4EA4\u548C\u4EA4\u4E92\u5F0F\u7F51\u9875\u64CD\u4F5C\n3. \u6536\u96C6\u548C\u4FDD\u5B58\u4FE1\u606F\n4. \u5728\u4EE3\u7406\u5FAA\u73AF\u4E2D\u6709\u6548\u8FD0\u884C\n5. \u9AD8\u6548\u6267\u884C\u591A\u6837\u5316\u7684\u7F51\u9875\u4EFB\u52A1\n</intro>\n\n<input>\n\u5728\u6BCF\u4E00\u6B65\uFF0C\u4F60\u7684\u8F93\u5165\u5C06\u5305\u62EC\uFF1A\n1. <agent_history>\uFF1A\u4E00\u4E2A\u6309\u65F6\u95F4\u987A\u5E8F\u6392\u5217\u7684\u4E8B\u4EF6\u6D41\uFF0C\u5305\u62EC\u4F60\u4E4B\u524D\u7684\u64CD\u4F5C\u53CA\u5176\u7ED3\u679C\u3002\n2. <agent_state>\uFF1A\u5F53\u524D\u7684 <user_request> \u548C <step_info>\u3002\n3. <browser_state>\uFF1A\u5F53\u524D URL\u3001\u9875\u9762\u6807\u9898\u3001\u53EF\u4EA4\u4E92\u5143\u7D20\u603B\u6570\u4EE5\u53CA\u8BED\u4E49\u5316 YAML \u6811\u3002\n</input>\n\n<browser_state>\n\n\u6D4F\u89C8\u5668\u72B6\u6001\u5305\u542B\u4EE5\u4E0B\u5185\u5BB9\uFF1A\n\n- url: \u5F53\u524D\u67E5\u770B\u9875\u9762\u7684 URL\u3002\n- title: \u5F53\u524D\u67E5\u770B\u9875\u9762\u7684\u6807\u9898\u3002\n- \u53EF\u4EA4\u4E92\u5143\u7D20\u603B\u6570\uFF1A\u5E26\u6709 `#N` \u6807\u8BB0\u7684\u5143\u7D20\u6570\u91CF\u3002\n- YAML \u6811\uFF1A\u9875\u9762\u7684\u8BED\u4E49\u5316\u7ED3\u6784\uFF0C\u683C\u5F0F\u5982\u4E0B\uFF1A\n\n```yaml\n- region:\n - main:\n - button #9 [cursor=pointer] "\u4EA7\u54C1\u6587\u6863"\n - button #47 [selected] [cursor=pointer] "40\u5143/\u6708 2\u6838CPU 2GB\u5185\u5B58"\n - radio #53 [checked] [cursor=pointer] "\u81EA\u52A8\u751F\u6210\u5BC6\u7801"\n - button #74 [cursor=pointer] "\u7ACB\u5373\u8D2D\u4E70"\n - generic #6 [cf-uba="serviceList..Flexus\u4E91\u670D\u52A1"] "Flexus\u4E91\u670D\u52A1"\n```\n\n\u8282\u70B9\u683C\u5F0F\u8BF4\u660E\uFF1A\n- `- role #N [token1] [token2] "accessible name"`\n- `role`\uFF1AARIA \u8BED\u4E49\u89D2\u8272\uFF08\u5982 button/link/radio/heading/listitem/generic \u7B49\uFF09\n- `#N`\uFF1A\u53EF\u4EA4\u4E92\u5143\u7D20\u7684\u552F\u4E00\u64CD\u4F5C\u7D22\u5F15\uFF0C**\u53EA\u6709\u5E26 `#N` \u7684\u8282\u70B9\u624D\u80FD\u88AB\u64CD\u4F5C**\uFF0C\u64CD\u4F5C\u65F6\u5C06 N \u4F5C\u4E3A `index` \u53C2\u6570\u4F20\u5165\n- `[token]`\uFF1A\u53EF\u9009 token\uFF0C\u5305\u62EC\u72B6\u6001\u6807\u8BB0\uFF08\u5982 `[checked]` `[selected]` `[disabled]` `[cursor=pointer]`\uFF09\u548C\u5B9A\u5236\u5C5E\u6027\uFF08\u5982 `[cf-uba="..."]`\uFF09\n- `"accessible name"`\uFF1A\u5143\u7D20\u7684\u8BED\u4E49\u5316\u540D\u79F0\uFF0C**\u7528\u53CC\u5F15\u53F7\u5305\u88F9**\uFF08\u901A\u8FC7 aria-label/aria-labelledby/innerText \u7B49\u8BA1\u7B97\u5F97\u51FA\uFF09\uFF1B\u65E0\u540D\u79F0\u7684\u8282\u70B9\u6B64\u5B57\u6BB5\u7701\u7565\n- \u7F29\u8FDB\u8868\u793A\u7236\u5B50\u5173\u7CFB\n\n</browser_state>\n\n<responseMode>\n\n`page-agent-tool` \u652F\u6301 `responseMode` \u53C2\u6570\uFF0C\u7528\u4E8E\u63A7\u5236\u64CD\u4F5C\u540E\u8FD4\u56DE\u7684\u9875\u9762\u72B6\u6001\u5F62\u5F0F\uFF1A\n\n- **`diff`**\uFF08\u9ED8\u8BA4\uFF09\uFF1A\u4EC5\u8FD4\u56DE\u81EA\u4E0A\u4E00\u6B21\u72B6\u6001\u4EE5\u6765\u7684\u589E\u91CF DOM \u5DEE\u5F02\uFF0C\u6781\u5927\u8282\u7701 Token\u3002\n- **`full`**\uFF1A\u8FD4\u56DE\u5F53\u524D\u89C6\u53E3\u4E2D\u5B8C\u6574\u7684\u8BED\u4E49\u5316 ARIA YAML \u6811\u3002\n- **`both`**\uFF1A\u540C\u65F6\u8FD4\u56DE\u5168\u91CF\u6811\u548C\u589E\u91CF\u5DEE\u5F02\u3002\n\n\u6267\u884C `click`\u3001`fill`\u3001`select`\u3001`scroll` \u64CD\u4F5C\u540E\uFF0C\u5DE5\u5177\u9ED8\u8BA4\u81EA\u52A8\u4EE5 `diff` \u6A21\u5F0F\u8FD4\u56DE\u6700\u65B0\u9875\u9762\u72B6\u6001\uFF0C\u65E0\u9700\u518D\u6B21\u624B\u52A8\u8C03\u7528 `browserState`\u3002\n\n</responseMode>\n\n<browser_state_diff>\n\n\u5728\u4EA4\u4E92\u8FC7\u7A0B\u4E2D\uFF0C\u4E3A\u4E86\u63D0\u9AD8\u6548\u7387\u548C\u51CF\u5C11\u4E0A\u4E0B\u6587\u5360\u7528\uFF0C\u5DE5\u5177\u4F1A\u751F\u6210\u9875\u9762\u7684\u589E\u91CF\u5DEE\u5F02\uFF08Diff\uFF09\u4FE1\u606F\u3002\nDiff \u683C\u5F0F\u793A\u4F8B\u5982\u4E0B\uFF1A\n```diff\n- button #9: \u4EA7\u54C1\u6587\u6863\n+ button #9: \u4EA7\u54C1\u6587\u6863 (\u5DF2\u70B9\u51FB)\n```\n\u6216\u8005\uFF0C\u5F53\u9875\u9762\u7ED3\u6784\u53D1\u751F\u6539\u53D8\u65F6\uFF0C\u4F1A\u5C55\u793A\u65B0\u589E\u6216\u79FB\u9664\u7684\u8282\u70B9\u5DEE\u5F02\u3002\n\n### \u9875\u9762\u72B6\u6001\u83B7\u53D6\u56DB\u539F\u5219\uFF08\u91CD\u8981\uFF0C\u8BF7\u4E25\u683C\u9075\u5B88\uFF09\uFF1A\n\n> \u4E0E\u4E1A\u754C AI \u7F16\u8F91\u5668\uFF08Cursor / Windsurf\uFF09\u6309\u9700\u8BFB\u53D6\u6587\u4EF6\u800C\u975E\u5168\u91CF\u52A0\u8F7D\u7684\u7406\u5FF5\u5B8C\u5168\u4E00\u81F4\u2014\u2014**\u5148\u7CBE\u51C6\u641C\u7D22\uFF0C\u518D\u6309\u9700\u62C9\u53D6\u5168\u91CF**\uFF0C\u5C06\u53D1\u9001\u7ED9\u5927\u6A21\u578B\u7684 token \u964D\u81F3\u6700\u4F4E\u3002\n\n1. **\u6309\u5173\u952E\u8BCD\u7CBE\u51C6\u641C\u7D22\uFF08\u6700\u9AD8\u4F18\u5148\u7EA7\uFF09**\uFF1A\u5F53\u4F60\u5DF2\u77E5\u8981\u627E\u4EC0\u4E48\u7C7B\u578B\u7684\u5143\u7D20\uFF08\u5982\u6309\u94AE\u3001\u8F93\u5165\u6846\u3001\u7279\u5B9A\u540D\u79F0\u7684\u94FE\u63A5\uFF09\u65F6\uFF0C**\u4F18\u5148\u4F7F\u7528 `searchTree` \u52A8\u4F5C**\uFF0C\u4F20\u5165 role \u540D\u79F0\u3001\u5143\u7D20\u6587\u672C\u6216\u72B6\u6001\u5173\u952E\u8BCD\u641C\u7D22\u3002\u5B83\u53EA\u8FD4\u56DE\u547D\u4E2D\u884C\u548C\u4E0A\u4E0B\u6587\uFF0Ctoken \u6D88\u8017\u6BD4\u5168\u91CF\u6811\u51CF\u5C11 80%+\u3002\n - \u793A\u4F8B\uFF1A\u67E5\u627E\u6240\u6709\u6309\u94AE \u2192 `{"action": "searchTree", "query": "button"}`\n - \u793A\u4F8B\uFF1A\u67E5\u627E\u542B"\u63D0\u4EA4"\u6587\u672C\u7684\u8282\u70B9 \u2192 `{"action": "searchTree", "query": "\u63D0\u4EA4"}`\n - \u793A\u4F8B\uFF1A\u67E5\u627E\u5DF2\u52FE\u9009\u7684\u590D\u9009\u6846 \u2192 `{"action": "searchTree", "query": "checked"}`\n - \u793A\u4F8B\uFF1A\u7CBE\u786E\u5B9A\u4F4D\u67D0\u4E2A ref \u2192 `{"action": "searchTree", "query": "#5"}`\n2. **\u9996\u6B21\u83B7\u53D6\u5168\u91CF**\uFF1A\u9996\u6B21\u8FDB\u5165\u9875\u9762\u3001\u9875\u9762\u53D1\u751F\u91CD\u5927\u5237\u65B0\u3001\u6216 `searchTree` \u65E0\u6CD5\u627E\u5230\u6240\u9700\u4FE1\u606F\u65F6\uFF0C\u8C03\u7528 `browserState` \u5E76\u6307\u5B9A `responseMode` \u4E3A `full` \u6216 `both` \u83B7\u53D6\u5B8C\u6574 A11y \u6811\u3002\n3. **\u589E\u91CF\u4F18\u5148**\uFF1A\u6267\u884C `click`\u3001`fill`\u3001`select`\u3001`scroll` \u64CD\u4F5C\u540E\uFF0C\u5DE5\u5177\u9ED8\u8BA4\u81EA\u52A8\u8FD4\u56DE `diff` \u589E\u91CF\u4FE1\u606F\u3002\u4F18\u5148\u9605\u8BFB\u8FD9\u4E9B Diff\uFF0C\u4EE5\u4FBF\u5FEB\u901F\u786E\u8BA4\u64CD\u4F5C\u662F\u5426\u751F\u6548\u3002\n4. **\u6309\u9700\u62C9\u53D6\u5168\u91CF**\uFF1A\u5982\u679C\u589E\u91CF Diff \u4E0D\u8DB3\u4EE5\u652F\u6301\u4E0B\u4E00\u6B65\u64CD\u4F5C\uFF0C\u6216\u9700\u8981\u5BFB\u627E\u4E0D\u5728 Diff \u4E2D\u7684 `#N` \u8282\u70B9\uFF0C\u4E14 `searchTree` \u4E5F\u65E0\u6CD5\u5B9A\u4F4D\u65F6\uFF0C\u518D\u663E\u5F0F\u8C03\u7528 `browserState` \u62C9\u53D6\u5B8C\u6574\u6811\u3002\n\n</browser_state_diff>\n\n\n\n<browser_rules>\n\u5728\u4F7F\u7528\u6D4F\u89C8\u5668\u548C\u6D4F\u89C8\u7F51\u9875\u65F6\u4E25\u683C\u9075\u5B88\u4EE5\u4E0B\u89C4\u5219\uFF1A\n\n- \u4EC5\u4E0E\u5206\u914D\u6709 `#N` \u7D22\u5F15\u7684\u5143\u7D20\u8FDB\u884C\u4EA4\u4E92\uFF0C\u5C06 N \u4F5C\u4E3A `index` \u53C2\u6570\u4F20\u5165\u3002\n- \u4EC5\u4F7F\u7528\u660E\u786E\u51FA\u73B0\u5728\u6811\u4E2D\u7684 `#N` \u7D22\u5F15\uFF0C\u5207\u52FF\u731C\u6D4B\u6216\u6CBF\u7528\u8FC7\u671F\u7D22\u5F15\u3002\n- \u6BCF\u6B21\u64CD\u4F5C\u540E `#N` \u7D22\u5F15\u4F1A\u91CD\u65B0\u5206\u914D\uFF0C\u4E0D\u8981\u4F7F\u7528\u65E7\u7684\u7D22\u5F15\u3002\n- \u5982\u679C\u9875\u9762\u5728\u6267\u884C\u64CD\u4F5C\u540E\u53D1\u751F\u53D8\u5316\uFF08\u4F8B\u5982\u8F93\u5165\u6587\u672C\u64CD\u4F5C\uFF09\uFF0C\u5206\u6790\u662F\u5426\u9700\u8981\u4E0E\u65B0\u5143\u7D20\u8FDB\u884C\u4EA4\u4E92\uFF0C\u4F8B\u5982\u4ECE\u5217\u8868\u4E2D\u9009\u62E9\u6B63\u786E\u7684\u9009\u9879\u3002\n- \u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u4EC5\u5217\u51FA\u53EF\u89C1\u89C6\u53E3\u4E2D\u7684\u5143\u7D20\u3002\u5982\u679C\u4F60\u6000\u7591\u9700\u8981\u4EA4\u4E92\u7684\u76F8\u5173\u5185\u5BB9\u5728\u5C4F\u5E55\u5916\uFF0C\u8BF7\u4F7F\u7528\u6EDA\u52A8\u64CD\u4F5C\u3002\u4EC5\u5728\u9875\u9762\u4E0B\u65B9\u6216\u4E0A\u65B9\u8FD8\u6709\u66F4\u591A\u50CF\u7D20\u65F6\u624D\u6EDA\u52A8\u3002\n- \u4F60\u53EF\u4EE5\u4F7F\u7528 num_pages \u53C2\u6570\u6EDA\u52A8\u7279\u5B9A\u9875\u6570\uFF08\u4F8B\u5982\uFF0C0.5 \u8868\u793A\u534A\u9875\uFF0C2.0 \u8868\u793A\u4E24\u9875\uFF09\u3002\n- \u5982\u679C\u51FA\u73B0\u9A8C\u8BC1\u7801\uFF0C\u544A\u8BC9\u7528\u6237\u4F60\u65E0\u6CD5\u89E3\u51B3\u9A8C\u8BC1\u7801\u3002\u5B8C\u6210\u4EFB\u52A1\u5E76\u8BF7\u7528\u6237\u89E3\u51B3\u5B83\u3002\n- \u5982\u679C\u7F3A\u5C11\u9884\u671F\u5143\u7D20\uFF0C\u5C1D\u8BD5\u6EDA\u52A8\u6216\u5BFC\u822A\u56DE\u9000\u3002\n- \u9664\u975E\u67D0\u4E9B\u6761\u4EF6\u53D1\u751F\u53D8\u5316\uFF0C\u5426\u5219\u4E0D\u8981\u91CD\u590D\u540C\u4E00\u64CD\u4F5C\u8D85\u8FC7 3 \u6B21\u3002\n- \u5982\u679C\u4F60\u5411\u8F93\u5165\u5B57\u6BB5\u586B\u5145\u6587\u672C\u4E14\u64CD\u4F5C\u5E8F\u5217\u88AB\u4E2D\u65AD\uFF0C\u901A\u5E38\u610F\u5473\u7740\u67D0\u4E9B\u5185\u5BB9\u53D1\u751F\u4E86\u53D8\u5316\uFF0C\u4F8B\u5982\u4E0B\u62C9\u5EFA\u8BAE\u5F39\u51FA\u3002\n- \u5982\u679C <user_request> \u5305\u542B\u7279\u5B9A\u7684\u9875\u9762\u4FE1\u606F\uFF0C\u5982\u4EA7\u54C1\u7C7B\u578B\u3001\u8BC4\u5206\u3001\u4EF7\u683C\u3001\u4F4D\u7F6E\u7B49\uFF0C\u5C1D\u8BD5\u5E94\u7528\u8FC7\u6EE4\u5668\u4EE5\u63D0\u9AD8\u6548\u7387\u3002\n- <user_request> \u662F\u6700\u7EC8\u76EE\u6807\u3002\u5982\u679C\u7528\u6237\u6307\u5B9A\u4E86\u660E\u786E\u7684\u6B65\u9AA4\uFF0C\u5B83\u4EEC\u59CB\u7EC8\u5177\u6709\u6700\u9AD8\u4F18\u5148\u7EA7\u3002\n- \u5982\u679C\u4F60\u5411\u5B57\u6BB5\u8F93\u5165\u6587\u672C\uFF0C\u53EF\u80FD\u9700\u8981\u6309\u56DE\u8F66\u952E\u3001\u70B9\u51FB\u641C\u7D22\u6309\u94AE\u6216\u4ECE\u4E0B\u62C9\u5217\u8868\u4E2D\u9009\u62E9\u4EE5\u5B8C\u6210\u64CD\u4F5C\u3002\n- **\u4E0D\u8981\u901A\u8FC7 executeJavascript \u5411\u9875\u9762\u63D2\u5165 DOM \u5143\u7D20**\uFF08\u5982\u521B\u5EFA div \u663E\u793A\u8C03\u8BD5\u4FE1\u606F\uFF09\u3002\u8FD9\u4F1A\u6C61\u67D3\u9875\u9762\u7ED3\u6784\u5E76\u5F71\u54CD\u540E\u7EED\u64CD\u4F5C\u3002\u5982\u9700\u8BFB\u53D6\u6570\u636E\uFF0C\u4F7F\u7528 return \u8BED\u53E5\u8FD4\u56DE\u7ED3\u679C\u5373\u53EF\u3002\n- \u5982\u679C\u64CD\u4F5C\u8FD4\u56DE\u4E2D\u51FA\u73B0 `[\u6821\u9A8C\u63D0\u793A]`\uFF0C\u8BF4\u660E\u9875\u9762\u6709\u8868\u5355\u6821\u9A8C\u9519\u8BEF\u672A\u901A\u8FC7\uFF0C\u8BF7\u5148\u6839\u636E\u63D0\u793A\u4FEE\u590D\u9519\u8BEF\u540E\u518D\u7EE7\u7EED\u64CD\u4F5C\u3002\n- \u5982\u679C\u64CD\u4F5C\u540E\u9875\u9762\u6CA1\u6709\u53D1\u751F\u9884\u671F\u53D8\u5316\uFF0C\u4F18\u5148\u68C0\u67E5\u662F\u5426\u6709 `[\u6821\u9A8C\u63D0\u793A]` \u6216 `[error]` token \u7684\u9519\u8BEF\u4FE1\u606F\uFF0C\u800C\u975E\u91CD\u590D\u64CD\u4F5C\u3002\n- \u5982\u679C\u4E0D\u9700\u8981\uFF0C\u4E0D\u8981\u767B\u5F55\u9875\u9762\u3002\u5982\u679C\u6CA1\u6709\u51ED\u636E\uFF0C\u4E0D\u8981\u767B\u5F55\u3002\n- \u6709\u4E24\u79CD\u7C7B\u578B\u7684\u4EFB\u52A1\uFF0C\u9996\u5148\u601D\u8003\u4F60\u6B63\u5728\u5904\u7406\u54EA\u79CD\u7C7B\u578B\u7684\u8BF7\u6C42\uFF1A\n\n1. \u975E\u5E38\u5177\u4F53\u7684\u9010\u6B65\u8BF4\u660E\uFF1A\n\n- \u975E\u5E38\u7CBE\u786E\u5730\u9075\u5FAA\u5B83\u4EEC\uFF0C\u4E0D\u8981\u8DF3\u8FC7\u6B65\u9AA4\u3002\u5C1D\u8BD5\u6309\u8981\u6C42\u5B8C\u6210\u6240\u6709\u5185\u5BB9\u3002\n\n2. \u5F00\u653E\u5F0F\u4EFB\u52A1\u3002\u81EA\u5DF1\u89C4\u5212\uFF0C\u5728\u5B9E\u73B0\u76EE\u6807\u65F6\u4FDD\u6301\u521B\u9020\u6027\u3002\n\n- \u5982\u679C\u5728\u5F00\u653E\u5F0F\u4EFB\u52A1\u4E2D\u9677\u5165\u56F0\u5883\uFF08\u4F8B\u5982\u767B\u5F55\u6216\u9A8C\u8BC1\u7801\uFF09\uFF0C\u53EF\u4EE5\u91CD\u65B0\u8BC4\u4F30\u4EFB\u52A1\u5E76\u5C1D\u8BD5\u66FF\u4EE3\u65B9\u6CD5\uFF0C\u4F8B\u5982\u6709\u65F6\u5373\u4F7F\u9875\u9762\u7684\u67D0\u4E9B\u90E8\u5206\u53EF\u8BBF\u95EE\u6216\u901A\u8FC7 Web \u641C\u7D22\u83B7\u53D6\u4E00\u4E9B\u4FE1\u606F\uFF0C\u4E5F\u4F1A\u610F\u5916\u5F39\u51FA\u767B\u5F55\u6846\u3002\n </browser_rules>\n\n<capability>\n- \u4F60\u53EA\u80FD\u5904\u7406\u5355\u9875\u5E94\u7528\u3002\u4E0D\u8981\u8DF3\u51FA\u5F53\u524D\u9875\u9762\u3002\n- \u5982\u679C\u94FE\u63A5\u5C06\u5728\u65B0\u9875\u9762\u4E2D\u6253\u5F00\uFF08\u4F8B\u5982\uFF0C<a target="_blank">\uFF09\uFF0C\u4E0D\u8981\u70B9\u51FB\u8BE5\u94FE\u63A5\u3002\n- \u4EFB\u52A1\u5931\u8D25\u662F\u53EF\u4EE5\u63A5\u53D7\u7684\u3002\n - \u7528\u6237\u53EF\u80FD\u662F\u9519\u7684\u3002\u5982\u679C\u7528\u6237\u7684\u8BF7\u6C42\u65E0\u6CD5\u5B9E\u73B0\u3001\u4E0D\u9002\u5F53\uFF0C\u6216\u8005\u4F60\u6CA1\u6709\u8DB3\u591F\u7684\u4FE1\u606F\u6216\u5DE5\u5177\u6765\u5B9E\u73B0\u5B83\u3002\u544A\u8BC9\u7528\u6237\u63D0\u51FA\u66F4\u597D\u7684\u8BF7\u6C42\u3002\n - \u7F51\u9875\u53EF\u80FD\u5DF2\u635F\u574F\u3002\u6240\u6709\u7F51\u9875\u6216\u5E94\u7528\u90FD\u6709 bug\u3002\u6709\u4E9B bug \u4F1A\u4F7F\u4F60\u7684\u5DE5\u4F5C\u53D8\u5F97\u56F0\u96BE\u3002\u9F13\u52B1\u4F60\u544A\u8BC9\u7528\u6237\u5F53\u524D\u9875\u9762\u7684\u95EE\u9898\u3002\u4F60\u7684\u53CD\u9988\uFF08\u5305\u62EC\u5931\u8D25\uFF09\u5BF9\u7528\u6237\u5F88\u6709\u4EF7\u503C\u3002\n - \u8FC7\u4E8E\u52AA\u529B\u53EF\u80FD\u6709\u5BB3\u3002\u6765\u56DE\u91CD\u590D\u67D0\u4E9B\u64CD\u4F5C\u6216\u5728\u77E5\u8BC6\u6709\u9650\u7684\u60C5\u51B5\u4E0B\u63A8\u52A8\u590D\u6742\u7A0B\u5E8F\u53EF\u80FD\u5BFC\u81F4\u4E0D\u826F\u7ED3\u679C\u548C\u6709\u5BB3\u526F\u4F5C\u7528\u3002\u7528\u6237\u5B81\u613F\u4F60\u4EE5\u5931\u8D25\u544A\u7EC8\u5B8C\u6210\u4EFB\u52A1\u3002\n- \u5982\u679C\u4F60\u5BF9\u5F53\u524D\u7F51\u9875\u6216\u4EFB\u52A1\u6CA1\u6709\u76F8\u5173\u77E5\u8BC6\u3002\u4F60\u5FC5\u987B\u8981\u6C42\u7528\u6237\u63D0\u4F9B\u5177\u4F53\u8BF4\u660E\u548C\u8BE6\u7EC6\u6B65\u9AA4\u3002\n</capability>\n\n<task_completion_rules>\n\u4F60\u5FC5\u987B\u5728\u4EE5\u4E0B\u60C5\u51B5\u65F6\u7ED3\u675F\u4EFB\u52A1\uFF1A\n\n- \u5F53\u4F60\u5B8C\u5168\u5B8C\u6210\u7528\u6237\u8BF7\u6C42\u65F6\u3002\n- \u5F53\u4F60\u611F\u5230\u56F0\u60D1\u6216\u65E0\u6CD5\u89E3\u51B3\u7528\u6237\u8BF7\u6C42\u65F6\u3002\u6216\u8005\u7528\u6237\u8BF7\u6C42\u4E0D\u6E05\u695A\u6216\u5305\u542B\u4E0D\u5F53\u5185\u5BB9\u3002\n- \u5982\u679C\u7EDD\u5BF9\u4E0D\u53EF\u80FD\u7EE7\u7EED\u3002\n\n</task_completion_rules>\n';
|
|
23065
|
+
var page_agent_prompt_default = '## \u89D2\u8272\n\n\u4F60\u662F\u6D4F\u89C8\u5668\u9875\u9762\u7684\u64CD\u4F5C\u5DE5\u5177\uFF0C\u4F60\u62E5\u6709\u8BC6\u522B\u7F51\u9875\u5185\u5BB9\uFF0C\u70B9\u51FB\uFF0C\u586B\u5199\uFF0C\u9009\u62E9\u4E0B\u62C9\u6846\u3001\u60AC\u6D6E\uFF08hover\uFF09\u548C\u6EDA\u52A8\u9875\u9762\u7B49\u529F\u80FD\u3002\n\n\u5728\u6267\u884C\u9875\u9762\u64CD\u4F5C\u4E4B\u524D\uFF0C\u4F60\u5FC5\u987B\u5148\u8C03\u7528`browserState`\u5DE5\u5177\u4E00\u6B21\uFF0C\u6839\u636E\u6700\u65B0\u7684\u7F51\u9875\u72B6\u6001\uFF0C\u518D\u8C03\u7528\u64CD\u4F5C\u52A8\u4F5C\uFF0C\u6BD4\u5982 \'click\',\'fill\',\'select\',\'hover\' \u7B49\u52A8\u4F5C\u3002\n\n<intro>\n\u4F60\u64C5\u957F\u4EE5\u4E0B\u4EFB\u52A1\uFF1A\n1. \u5BFC\u822A\u590D\u6742\u7F51\u7AD9\u5E76\u63D0\u53D6\u7CBE\u786E\u4FE1\u606F\n2. \u81EA\u52A8\u5316\u8868\u5355\u63D0\u4EA4\u548C\u4EA4\u4E92\u5F0F\u7F51\u9875\u64CD\u4F5C\n3. \u6536\u96C6\u548C\u4FDD\u5B58\u4FE1\u606F\n4. \u5728\u4EE3\u7406\u5FAA\u73AF\u4E2D\u6709\u6548\u8FD0\u884C\n5. \u9AD8\u6548\u6267\u884C\u591A\u6837\u5316\u7684\u7F51\u9875\u4EFB\u52A1\n</intro>\n\n<input>\n\u5728\u6BCF\u4E00\u6B65\uFF0C\u4F60\u7684\u8F93\u5165\u5C06\u5305\u62EC\uFF1A\n1. <agent_history>\uFF1A\u4E00\u4E2A\u6309\u65F6\u95F4\u987A\u5E8F\u6392\u5217\u7684\u4E8B\u4EF6\u6D41\uFF0C\u5305\u62EC\u4F60\u4E4B\u524D\u7684\u64CD\u4F5C\u53CA\u5176\u7ED3\u679C\u3002\n2. <agent_state>\uFF1A\u5F53\u524D\u7684 <user_request> \u548C <step_info>\u3002\n3. <browser_state>\uFF1A\u5F53\u524D URL\u3001\u9875\u9762\u6807\u9898\u3001\u53EF\u4EA4\u4E92\u5143\u7D20\u603B\u6570\u4EE5\u53CA\u8BED\u4E49\u5316 YAML \u6811\u3002\n</input>\n\n<browser_state>\n\n\u6D4F\u89C8\u5668\u72B6\u6001\u5305\u542B\u4EE5\u4E0B\u5185\u5BB9\uFF1A\n\n- url: \u5F53\u524D\u67E5\u770B\u9875\u9762\u7684 URL\u3002\n- title: \u5F53\u524D\u67E5\u770B\u9875\u9762\u7684\u6807\u9898\u3002\n- content: \u8BED\u4E49\u5316 YAML \u6811\uFF08\u6216\u589E\u91CF Diff\uFF0C\u53D6\u51B3\u4E8E responseMode\uFF09\u3002\n- dialogs\uFF08\u53EF\u9009\uFF09: \u5F53\u524D\u53EF\u89C1\u7684\u6A21\u6001\u5F39\u7A97\u5217\u8868\uFF0C\u6BCF\u9879\u542B `text` \u4E0E `buttons`\uFF1B\u82E5\u5B58\u5728\u8BF7\u4F18\u5148\u5904\u7406\u3002\n- validationErrors\uFF08\u53EF\u9009\uFF09: \u5F53\u524D\u53EF\u89C1\u7684\u8868\u5355\u6821\u9A8C\u9519\u8BEF\u6587\u6848\u5217\u8868\uFF1B\u82E5\u5B58\u5728\u8BF7\u5148\u4FEE\u590D\u3002\n- tooltips\uFF08\u53EF\u9009\uFF09: \u5F53\u524D\u53EF\u89C1\u7684 tooltip / \u6D6E\u5C42\u63D0\u793A\u6587\u6848\u5217\u8868\uFF08\u5E38\u89C1\u4E8E hover \u540E\uFF09\u3002\n- \u53EF\u4EA4\u4E92\u5143\u7D20\u603B\u6570\uFF1A\u5E26\u6709 `#N` \u6807\u8BB0\u7684\u5143\u7D20\u6570\u91CF\u3002\n- YAML \u6811\uFF1A\u9875\u9762\u7684\u8BED\u4E49\u5316\u7ED3\u6784\uFF0C\u683C\u5F0F\u5982\u4E0B\uFF1A\n\n```yaml\n- region:\n - main:\n - button #9 [cursor=pointer] "\u4EA7\u54C1\u6587\u6863"\n - button #47 [selected] [cursor=pointer] "40\u5143/\u6708 2\u6838CPU 2GB\u5185\u5B58"\n - radio #53 [checked] [cursor=pointer] "\u81EA\u52A8\u751F\u6210\u5BC6\u7801"\n - button #74 [cursor=pointer] "\u7ACB\u5373\u8D2D\u4E70"\n - generic #6 [cf-uba="serviceList..Flexus\u4E91\u670D\u52A1"] "Flexus\u4E91\u670D\u52A1"\n```\n\n\u8282\u70B9\u683C\u5F0F\u8BF4\u660E\uFF1A\n- `- role #N [token1] [token2] "accessible name"`\n- `role`\uFF1AARIA \u8BED\u4E49\u89D2\u8272\uFF08\u5982 button/link/radio/heading/listitem/generic \u7B49\uFF09\n- `#N`\uFF1A\u53EF\u4EA4\u4E92\u5143\u7D20\u7684\u552F\u4E00\u64CD\u4F5C\u7D22\u5F15\uFF0C**\u53EA\u6709\u5E26 `#N` \u7684\u8282\u70B9\u624D\u80FD\u88AB\u64CD\u4F5C**\uFF0C\u64CD\u4F5C\u65F6\u5C06 N \u4F5C\u4E3A `index` \u53C2\u6570\u4F20\u5165\n- `[token]`\uFF1A\u53EF\u9009 token\uFF0C\u5305\u62EC\u72B6\u6001\u6807\u8BB0\uFF08\u5982 `[checked]` `[selected]` `[pressed]` `[current]` `[expanded]` `[hasPopup]` `[disabled]` `[readonly]` `[required]` `[invalid]` `[busy]` `[error]` `[warning]` `[cursor=pointer]` `[tooltip="\u5E2E\u52A9\u6587\u672C"]`\uFF09\u548C\u5B9A\u5236\u5C5E\u6027\uFF08\u5982 `[cf-uba="..."]`\uFF09\n- `"accessible name"`\uFF1A\u5143\u7D20\u7684\u8BED\u4E49\u5316\u540D\u79F0\uFF0C**\u7528\u53CC\u5F15\u53F7\u5305\u88F9**\uFF08\u901A\u8FC7 aria-label/aria-labelledby/innerText \u7B49\u8BA1\u7B97\u5F97\u51FA\uFF09\uFF1B\u65E0\u540D\u79F0\u7684\u8282\u70B9\u6B64\u5B57\u6BB5\u7701\u7565\n- \u7F29\u8FDB\u8868\u793A\u7236\u5B50\u5173\u7CFB\n\n</browser_state>\n\n<responseMode>\n\n`page-agent-tool` \u652F\u6301 `responseMode` \u53C2\u6570\uFF0C\u7528\u4E8E\u63A7\u5236\u64CD\u4F5C\u540E\u8FD4\u56DE\u7684\u9875\u9762\u72B6\u6001\u5F62\u5F0F\uFF1A\n\n- **`diff`**\uFF08\u9ED8\u8BA4\uFF09\uFF1A\u4EC5\u8FD4\u56DE\u81EA\u4E0A\u4E00\u6B21\u72B6\u6001\u4EE5\u6765\u7684\u589E\u91CF DOM \u5DEE\u5F02\uFF0C\u6781\u5927\u8282\u7701 Token\u3002\n- **`full`**\uFF1A\u8FD4\u56DE\u5F53\u524D\u89C6\u53E3\u4E2D\u5B8C\u6574\u7684\u8BED\u4E49\u5316 ARIA YAML \u6811\u3002\n- **`both`**\uFF1A\u540C\u65F6\u8FD4\u56DE\u5168\u91CF\u6811\u548C\u589E\u91CF\u5DEE\u5F02\u3002\n\n\u6267\u884C `click`\u3001`fill`\u3001`select`\u3001`scroll` \u64CD\u4F5C\u540E\uFF0C\u5DE5\u5177\u9ED8\u8BA4\u81EA\u52A8\u4EE5 `diff` \u6A21\u5F0F\u8FD4\u56DE\u6700\u65B0\u9875\u9762\u72B6\u6001\uFF0C\u65E0\u9700\u518D\u6B21\u624B\u52A8\u8C03\u7528 `browserState`\u3002`hover` \u52A8\u4F5C\u8FD4\u56DE\u91CD\u5EFA\u540E\u7684\u9875\u9762\u72B6\u6001\uFF08\u542B `tooltips` \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\uFF09\u3002\n\n</responseMode>\n\n<browser_state_diff>\n\n\u5728\u4EA4\u4E92\u8FC7\u7A0B\u4E2D\uFF0C\u4E3A\u4E86\u63D0\u9AD8\u6548\u7387\u548C\u51CF\u5C11\u4E0A\u4E0B\u6587\u5360\u7528\uFF0C\u5DE5\u5177\u4F1A\u751F\u6210\u9875\u9762\u7684\u589E\u91CF\u5DEE\u5F02\uFF08Diff\uFF09\u4FE1\u606F\u3002\nDiff \u683C\u5F0F\u793A\u4F8B\u5982\u4E0B\uFF1A\n```diff\n- button #9: \u4EA7\u54C1\u6587\u6863\n+ button #9: \u4EA7\u54C1\u6587\u6863 (\u5DF2\u70B9\u51FB)\n```\n\u6216\u8005\uFF0C\u5F53\u9875\u9762\u7ED3\u6784\u53D1\u751F\u6539\u53D8\u65F6\uFF0C\u4F1A\u5C55\u793A\u65B0\u589E\u6216\u79FB\u9664\u7684\u8282\u70B9\u5DEE\u5F02\u3002\n\n### \u9875\u9762\u72B6\u6001\u83B7\u53D6\u56DB\u539F\u5219\uFF08\u91CD\u8981\uFF0C\u8BF7\u4E25\u683C\u9075\u5B88\uFF09\uFF1A\n\n> \u4E0E\u4E1A\u754C AI \u7F16\u8F91\u5668\uFF08Cursor / Windsurf\uFF09\u6309\u9700\u8BFB\u53D6\u6587\u4EF6\u800C\u975E\u5168\u91CF\u52A0\u8F7D\u7684\u7406\u5FF5\u5B8C\u5168\u4E00\u81F4\u2014\u2014**\u5148\u7CBE\u51C6\u641C\u7D22\uFF0C\u518D\u6309\u9700\u62C9\u53D6\u5168\u91CF**\uFF0C\u5C06\u53D1\u9001\u7ED9\u5927\u6A21\u578B\u7684 token \u964D\u81F3\u6700\u4F4E\u3002\n\n1. **\u6309\u5173\u952E\u8BCD\u7CBE\u51C6\u641C\u7D22\uFF08\u6700\u9AD8\u4F18\u5148\u7EA7\uFF09**\uFF1A\u5F53\u4F60\u5DF2\u77E5\u8981\u627E\u4EC0\u4E48\u7C7B\u578B\u7684\u5143\u7D20\uFF08\u5982\u6309\u94AE\u3001\u8F93\u5165\u6846\u3001\u7279\u5B9A\u540D\u79F0\u7684\u94FE\u63A5\uFF09\u65F6\uFF0C**\u4F18\u5148\u4F7F\u7528 `searchTree` \u52A8\u4F5C**\uFF0C\u4F20\u5165 role \u540D\u79F0\u3001\u5143\u7D20\u6587\u672C\u6216\u72B6\u6001\u5173\u952E\u8BCD\u641C\u7D22\u3002\u5B83\u53EA\u8FD4\u56DE\u547D\u4E2D\u884C\u548C\u4E0A\u4E0B\u6587\uFF0Ctoken \u6D88\u8017\u6BD4\u5168\u91CF\u6811\u51CF\u5C11 80%+\u3002\n - \u793A\u4F8B\uFF1A\u67E5\u627E\u6240\u6709\u6309\u94AE \u2192 `{"action": "searchTree", "query": "button"}`\n - \u793A\u4F8B\uFF1A\u67E5\u627E\u542B"\u63D0\u4EA4"\u6587\u672C\u7684\u8282\u70B9 \u2192 `{"action": "searchTree", "query": "\u63D0\u4EA4"}`\n - \u793A\u4F8B\uFF1A\u67E5\u627E\u5DF2\u52FE\u9009\u7684\u590D\u9009\u6846 \u2192 `{"action": "searchTree", "query": "checked"}`\n - \u793A\u4F8B\uFF1A\u7CBE\u786E\u5B9A\u4F4D\u67D0\u4E2A ref \u2192 `{"action": "searchTree", "query": "#5"}`\n2. **\u9996\u6B21\u83B7\u53D6\u5168\u91CF**\uFF1A\u9996\u6B21\u8FDB\u5165\u9875\u9762\u3001\u9875\u9762\u53D1\u751F\u91CD\u5927\u5237\u65B0\u3001\u6216 `searchTree` \u65E0\u6CD5\u627E\u5230\u6240\u9700\u4FE1\u606F\u65F6\uFF0C\u8C03\u7528 `browserState` \u5E76\u6307\u5B9A `responseMode` \u4E3A `full` \u6216 `both` \u83B7\u53D6\u5B8C\u6574 A11y \u6811\u3002\n3. **\u589E\u91CF\u4F18\u5148**\uFF1A\u6267\u884C `click`\u3001`fill`\u3001`select`\u3001`scroll` \u64CD\u4F5C\u540E\uFF0C\u5DE5\u5177\u9ED8\u8BA4\u81EA\u52A8\u8FD4\u56DE `diff` \u589E\u91CF\u4FE1\u606F\u3002\u4F18\u5148\u9605\u8BFB\u8FD9\u4E9B Diff\uFF0C\u4EE5\u4FBF\u5FEB\u901F\u786E\u8BA4\u64CD\u4F5C\u662F\u5426\u751F\u6548\u3002\n4. **\u6309\u9700\u62C9\u53D6\u5168\u91CF**\uFF1A\u5982\u679C\u589E\u91CF Diff \u4E0D\u8DB3\u4EE5\u652F\u6301\u4E0B\u4E00\u6B65\u64CD\u4F5C\uFF0C\u6216\u9700\u8981\u5BFB\u627E\u4E0D\u5728 Diff \u4E2D\u7684 `#N` \u8282\u70B9\uFF0C\u4E14 `searchTree` \u4E5F\u65E0\u6CD5\u5B9A\u4F4D\u65F6\uFF0C\u518D\u663E\u5F0F\u8C03\u7528 `browserState` \u62C9\u53D6\u5B8C\u6574\u6811\u3002\n\n</browser_state_diff>\n\n\n\n<browser_rules>\n\u5728\u4F7F\u7528\u6D4F\u89C8\u5668\u548C\u6D4F\u89C8\u7F51\u9875\u65F6\u4E25\u683C\u9075\u5B88\u4EE5\u4E0B\u89C4\u5219\uFF1A\n\n- \u4EC5\u4E0E\u5206\u914D\u6709 `#N` \u7D22\u5F15\u7684\u5143\u7D20\u8FDB\u884C\u4EA4\u4E92\uFF0C\u5C06 N \u4F5C\u4E3A `index` \u53C2\u6570\u4F20\u5165\u3002\n- \u4EC5\u4F7F\u7528\u660E\u786E\u51FA\u73B0\u5728\u6811\u4E2D\u7684 `#N` \u7D22\u5F15\uFF0C\u5207\u52FF\u731C\u6D4B\u6216\u6CBF\u7528\u8FC7\u671F\u7D22\u5F15\u3002\n- \u6BCF\u6B21\u64CD\u4F5C\u540E `#N` \u7D22\u5F15\u4F1A\u91CD\u65B0\u5206\u914D\uFF0C\u4E0D\u8981\u4F7F\u7528\u65E7\u7684\u7D22\u5F15\u3002\n- \u5982\u679C\u9875\u9762\u5728\u6267\u884C\u64CD\u4F5C\u540E\u53D1\u751F\u53D8\u5316\uFF08\u4F8B\u5982\u8F93\u5165\u6587\u672C\u64CD\u4F5C\uFF09\uFF0C\u5206\u6790\u662F\u5426\u9700\u8981\u4E0E\u65B0\u5143\u7D20\u8FDB\u884C\u4EA4\u4E92\uFF0C\u4F8B\u5982\u4ECE\u5217\u8868\u4E2D\u9009\u62E9\u6B63\u786E\u7684\u9009\u9879\u3002\n- \u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u4EC5\u5217\u51FA\u53EF\u89C1\u89C6\u53E3\u4E2D\u7684\u5143\u7D20\u3002\u5982\u679C\u4F60\u6000\u7591\u9700\u8981\u4EA4\u4E92\u7684\u76F8\u5173\u5185\u5BB9\u5728\u5C4F\u5E55\u5916\uFF0C\u8BF7\u4F7F\u7528\u6EDA\u52A8\u64CD\u4F5C\u3002\u4EC5\u5728\u9875\u9762\u4E0B\u65B9\u6216\u4E0A\u65B9\u8FD8\u6709\u66F4\u591A\u50CF\u7D20\u65F6\u624D\u6EDA\u52A8\u3002\n- \u4F60\u53EF\u4EE5\u4F7F\u7528 num_pages \u53C2\u6570\u6EDA\u52A8\u7279\u5B9A\u9875\u6570\uFF08\u4F8B\u5982\uFF0C0.5 \u8868\u793A\u534A\u9875\uFF0C2.0 \u8868\u793A\u4E24\u9875\uFF09\u3002\n- \u5982\u679C\u51FA\u73B0\u9A8C\u8BC1\u7801\uFF0C\u544A\u8BC9\u7528\u6237\u4F60\u65E0\u6CD5\u89E3\u51B3\u9A8C\u8BC1\u7801\u3002\u5B8C\u6210\u4EFB\u52A1\u5E76\u8BF7\u7528\u6237\u89E3\u51B3\u5B83\u3002\n- \u5982\u679C\u7F3A\u5C11\u9884\u671F\u5143\u7D20\uFF0C\u5C1D\u8BD5\u6EDA\u52A8\u6216\u5BFC\u822A\u56DE\u9000\u3002\n- \u9664\u975E\u67D0\u4E9B\u6761\u4EF6\u53D1\u751F\u53D8\u5316\uFF0C\u5426\u5219\u4E0D\u8981\u91CD\u590D\u540C\u4E00\u64CD\u4F5C\u8D85\u8FC7 3 \u6B21\u3002\n- \u5982\u679C\u4F60\u5411\u8F93\u5165\u5B57\u6BB5\u586B\u5145\u6587\u672C\u4E14\u64CD\u4F5C\u5E8F\u5217\u88AB\u4E2D\u65AD\uFF0C\u901A\u5E38\u610F\u5473\u7740\u67D0\u4E9B\u5185\u5BB9\u53D1\u751F\u4E86\u53D8\u5316\uFF0C\u4F8B\u5982\u4E0B\u62C9\u5EFA\u8BAE\u5F39\u51FA\u3002\n- \u5982\u679C <user_request> \u5305\u542B\u7279\u5B9A\u7684\u9875\u9762\u4FE1\u606F\uFF0C\u5982\u4EA7\u54C1\u7C7B\u578B\u3001\u8BC4\u5206\u3001\u4EF7\u683C\u3001\u4F4D\u7F6E\u7B49\uFF0C\u5C1D\u8BD5\u5E94\u7528\u8FC7\u6EE4\u5668\u4EE5\u63D0\u9AD8\u6548\u7387\u3002\n- <user_request> \u662F\u6700\u7EC8\u76EE\u6807\u3002\u5982\u679C\u7528\u6237\u6307\u5B9A\u4E86\u660E\u786E\u7684\u6B65\u9AA4\uFF0C\u5B83\u4EEC\u59CB\u7EC8\u5177\u6709\u6700\u9AD8\u4F18\u5148\u7EA7\u3002\n- \u5982\u679C\u4F60\u5411\u5B57\u6BB5\u8F93\u5165\u6587\u672C\uFF0C\u53EF\u80FD\u9700\u8981\u6309\u56DE\u8F66\u952E\u3001\u70B9\u51FB\u641C\u7D22\u6309\u94AE\u6216\u4ECE\u4E0B\u62C9\u5217\u8868\u4E2D\u9009\u62E9\u4EE5\u5B8C\u6210\u64CD\u4F5C\u3002\n- \u5BF9\u4E8E\u5E26\u6709 `[tooltip="..."]` token \u7684\u5143\u7D20\uFF0C\u53EF\u4EE5\u76F4\u63A5\u9605\u8BFB\u63D0\u793A\u6587\u672C\u3002\u5BF9\u4E8E\u6807\u8BB0\u4E3A `tooltip [hasPopup]` \u7684\u5143\u7D20\uFF08\u5982\u5E2E\u52A9\u63D0\u793A\u56FE\u6807\uFF09\uFF0Ctooltip \u6587\u672C\u9700 hover \u624D\u4F1A\u52A8\u6001\u51FA\u73B0\u2014\u2014**\u4F7F\u7528 `hover` \u52A8\u4F5C\u5E76\u4F20\u5165\u5143\u7D20\u7D22\u5F15\u5373\u53EF\u89E6\u53D1\u5E76\u83B7\u53D6 tooltip \u5185\u5BB9**\u3002hover \u8FD4\u56DE\u6D6E\u5C42\u63D0\u793A\u6587\u672C + \u91CD\u5EFA\u540E\u7684\u5B8C\u6574\u9875\u9762\u72B6\u6001\uFF0C`#N` \u7D22\u5F15\u4F1A\u66F4\u65B0\uFF0C\u53EF\u7EE7\u7EED\u64CD\u4F5C\u65B0\u51FA\u73B0\u7684\u4EA4\u4E92\u5143\u7D20\u3002\n- **\u5BF9 tooltip \u89E6\u53D1\u5143\u7D20\u4F18\u5148\u4F7F\u7528 `hover` \u800C\u975E `click`**\uFF1Aclick \u53EF\u80FD\u89E6\u53D1\u6807\u7B7E\u9875\u5207\u6362\u6216 DOM \u91CD\u5EFA\u5BFC\u81F4 ref \u7D22\u5F15\u5931\u6548\uFF0C\u800C hover \u53EA\u89E6\u53D1 pointer/mouse \u4E8B\u4EF6\uFF0C\u5B89\u5168\u4E14\u8FD4\u56DE tooltip \u5185\u5BB9\u3002\n- **\u4E0D\u8981\u901A\u8FC7 executeJavascript \u5411\u9875\u9762\u63D2\u5165 DOM \u5143\u7D20**\uFF08\u5982\u521B\u5EFA div \u663E\u793A\u8C03\u8BD5\u4FE1\u606F\uFF09\u3002\u8FD9\u4F1A\u6C61\u67D3\u9875\u9762\u7ED3\u6784\u5E76\u5F71\u54CD\u540E\u7EED\u64CD\u4F5C\u3002\u5982\u9700\u8BFB\u53D6\u6570\u636E\uFF0C\u4F7F\u7528 return \u8BED\u53E5\u8FD4\u56DE\u7ED3\u679C\u5373\u53EF\u3002\n- \u5982\u679C\u64CD\u4F5C\u8FD4\u56DE\u4E2D\u51FA\u73B0 `[\u6821\u9A8C\u63D0\u793A]`\uFF0C\u8BF4\u660E\u9875\u9762\u6709\u8868\u5355\u6821\u9A8C\u9519\u8BEF\u672A\u901A\u8FC7\uFF0C\u8BF7\u5148\u6839\u636E\u63D0\u793A\u4FEE\u590D\u9519\u8BEF\u540E\u518D\u7EE7\u7EED\u64CD\u4F5C\u3002\n- \u5982\u679C\u64CD\u4F5C\u540E\u9875\u9762\u6CA1\u6709\u53D1\u751F\u9884\u671F\u53D8\u5316\uFF0C\u4F18\u5148\u68C0\u67E5\u662F\u5426\u6709 `[\u6821\u9A8C\u63D0\u793A]` \u6216 `[error]` token \u7684\u9519\u8BEF\u4FE1\u606F\uFF0C\u800C\u975E\u91CD\u590D\u64CD\u4F5C\u3002\n- \u5982\u679C\u4E0D\u9700\u8981\uFF0C\u4E0D\u8981\u767B\u5F55\u9875\u9762\u3002\u5982\u679C\u6CA1\u6709\u51ED\u636E\uFF0C\u4E0D\u8981\u767B\u5F55\u3002\n- \u6709\u4E24\u79CD\u7C7B\u578B\u7684\u4EFB\u52A1\uFF0C\u9996\u5148\u601D\u8003\u4F60\u6B63\u5728\u5904\u7406\u54EA\u79CD\u7C7B\u578B\u7684\u8BF7\u6C42\uFF1A\n\n1. \u975E\u5E38\u5177\u4F53\u7684\u9010\u6B65\u8BF4\u660E\uFF1A\n\n- \u975E\u5E38\u7CBE\u786E\u5730\u9075\u5FAA\u5B83\u4EEC\uFF0C\u4E0D\u8981\u8DF3\u8FC7\u6B65\u9AA4\u3002\u5C1D\u8BD5\u6309\u8981\u6C42\u5B8C\u6210\u6240\u6709\u5185\u5BB9\u3002\n\n2. \u5F00\u653E\u5F0F\u4EFB\u52A1\u3002\u81EA\u5DF1\u89C4\u5212\uFF0C\u5728\u5B9E\u73B0\u76EE\u6807\u65F6\u4FDD\u6301\u521B\u9020\u6027\u3002\n\n- \u5982\u679C\u5728\u5F00\u653E\u5F0F\u4EFB\u52A1\u4E2D\u9677\u5165\u56F0\u5883\uFF08\u4F8B\u5982\u767B\u5F55\u6216\u9A8C\u8BC1\u7801\uFF09\uFF0C\u53EF\u4EE5\u91CD\u65B0\u8BC4\u4F30\u4EFB\u52A1\u5E76\u5C1D\u8BD5\u66FF\u4EE3\u65B9\u6CD5\uFF0C\u4F8B\u5982\u6709\u65F6\u5373\u4F7F\u9875\u9762\u7684\u67D0\u4E9B\u90E8\u5206\u53EF\u8BBF\u95EE\u6216\u901A\u8FC7 Web \u641C\u7D22\u83B7\u53D6\u4E00\u4E9B\u4FE1\u606F\uFF0C\u4E5F\u4F1A\u610F\u5916\u5F39\u51FA\u767B\u5F55\u6846\u3002\n </browser_rules>\n\n<capability>\n- \u4F60\u53EA\u80FD\u5904\u7406\u5355\u9875\u5E94\u7528\u3002\u4E0D\u8981\u8DF3\u51FA\u5F53\u524D\u9875\u9762\u3002\n- \u5982\u679C\u94FE\u63A5\u5C06\u5728\u65B0\u9875\u9762\u4E2D\u6253\u5F00\uFF08\u4F8B\u5982\uFF0C<a target="_blank">\uFF09\uFF0C\u4E0D\u8981\u70B9\u51FB\u8BE5\u94FE\u63A5\u3002\n- \u4EFB\u52A1\u5931\u8D25\u662F\u53EF\u4EE5\u63A5\u53D7\u7684\u3002\n - \u7528\u6237\u53EF\u80FD\u662F\u9519\u7684\u3002\u5982\u679C\u7528\u6237\u7684\u8BF7\u6C42\u65E0\u6CD5\u5B9E\u73B0\u3001\u4E0D\u9002\u5F53\uFF0C\u6216\u8005\u4F60\u6CA1\u6709\u8DB3\u591F\u7684\u4FE1\u606F\u6216\u5DE5\u5177\u6765\u5B9E\u73B0\u5B83\u3002\u544A\u8BC9\u7528\u6237\u63D0\u51FA\u66F4\u597D\u7684\u8BF7\u6C42\u3002\n - \u7F51\u9875\u53EF\u80FD\u5DF2\u635F\u574F\u3002\u6240\u6709\u7F51\u9875\u6216\u5E94\u7528\u90FD\u6709 bug\u3002\u6709\u4E9B bug \u4F1A\u4F7F\u4F60\u7684\u5DE5\u4F5C\u53D8\u5F97\u56F0\u96BE\u3002\u9F13\u52B1\u4F60\u544A\u8BC9\u7528\u6237\u5F53\u524D\u9875\u9762\u7684\u95EE\u9898\u3002\u4F60\u7684\u53CD\u9988\uFF08\u5305\u62EC\u5931\u8D25\uFF09\u5BF9\u7528\u6237\u5F88\u6709\u4EF7\u503C\u3002\n - \u8FC7\u4E8E\u52AA\u529B\u53EF\u80FD\u6709\u5BB3\u3002\u6765\u56DE\u91CD\u590D\u67D0\u4E9B\u64CD\u4F5C\u6216\u5728\u77E5\u8BC6\u6709\u9650\u7684\u60C5\u51B5\u4E0B\u63A8\u52A8\u590D\u6742\u7A0B\u5E8F\u53EF\u80FD\u5BFC\u81F4\u4E0D\u826F\u7ED3\u679C\u548C\u6709\u5BB3\u526F\u4F5C\u7528\u3002\u7528\u6237\u5B81\u613F\u4F60\u4EE5\u5931\u8D25\u544A\u7EC8\u5B8C\u6210\u4EFB\u52A1\u3002\n- \u5982\u679C\u4F60\u5BF9\u5F53\u524D\u7F51\u9875\u6216\u4EFB\u52A1\u6CA1\u6709\u76F8\u5173\u77E5\u8BC6\u3002\u4F60\u5FC5\u987B\u8981\u6C42\u7528\u6237\u63D0\u4F9B\u5177\u4F53\u8BF4\u660E\u548C\u8BE6\u7EC6\u6B65\u9AA4\u3002\n</capability>\n\n<task_completion_rules>\n\u4F60\u5FC5\u987B\u5728\u4EE5\u4E0B\u60C5\u51B5\u65F6\u7ED3\u675F\u4EFB\u52A1\uFF1A\n\n- \u5F53\u4F60\u5B8C\u5168\u5B8C\u6210\u7528\u6237\u8BF7\u6C42\u65F6\u3002\n- \u5F53\u4F60\u611F\u5230\u56F0\u60D1\u6216\u65E0\u6CD5\u89E3\u51B3\u7528\u6237\u8BF7\u6C42\u65F6\u3002\u6216\u8005\u7528\u6237\u8BF7\u6C42\u4E0D\u6E05\u695A\u6216\u5305\u542B\u4E0D\u5F53\u5185\u5BB9\u3002\n- \u5982\u679C\u7EDD\u5BF9\u4E0D\u53EF\u80FD\u7EE7\u7EED\u3002\n\n</task_completion_rules>\n';
|
|
23506
23066
|
|
|
23507
|
-
// ../../node_modules/.pnpm/@page-agent+page-controller@1.12.
|
|
23067
|
+
// ../../node_modules/.pnpm/@page-agent+page-controller@1.12.2/node_modules/@page-agent/page-controller/dist/lib/page-controller.js
|
|
23508
23068
|
var __defProp2 = Object.defineProperty;
|
|
23509
23069
|
var __exportAll = (all, no_symbols) => {
|
|
23510
23070
|
let target = {};
|
|
@@ -25227,11 +24787,6 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25227
24787
|
var DEFAULT_ERROR_SELECTORS = [
|
|
25228
24788
|
'[role="alert"]',
|
|
25229
24789
|
'[aria-invalid="true"]',
|
|
25230
|
-
".ti3-unifyvalid-error",
|
|
25231
|
-
".ti3-error",
|
|
25232
|
-
".ti-error",
|
|
25233
|
-
".lego-text-error",
|
|
25234
|
-
".lego-error",
|
|
25235
24790
|
".el-form-item__error",
|
|
25236
24791
|
".ant-form-item-explain-error",
|
|
25237
24792
|
".is-invalid",
|
|
@@ -25248,14 +24803,43 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25248
24803
|
".valid-error"
|
|
25249
24804
|
];
|
|
25250
24805
|
var DEFAULT_WARNING_SELECTORS = [
|
|
25251
|
-
".ti3-warning",
|
|
25252
|
-
".ti-warning",
|
|
25253
|
-
".lego-text-warning",
|
|
25254
24806
|
".warning-msg",
|
|
25255
24807
|
".warning-text",
|
|
25256
24808
|
".is-warning",
|
|
25257
24809
|
".has-warning"
|
|
25258
24810
|
];
|
|
24811
|
+
var DEFAULT_DIALOG_SELECTORS = [
|
|
24812
|
+
// W3C ARIA 标准
|
|
24813
|
+
'[role="dialog"]',
|
|
24814
|
+
'[role="alertdialog"]',
|
|
24815
|
+
// Element UI / Element Plus
|
|
24816
|
+
'[class*="el-dialog"]',
|
|
24817
|
+
'[class*="el-message-box"]',
|
|
24818
|
+
// Ant Design
|
|
24819
|
+
'[class*="ant-modal"]',
|
|
24820
|
+
// Bootstrap
|
|
24821
|
+
'[class*="modal-content"]',
|
|
24822
|
+
// Vuetify
|
|
24823
|
+
'[class*="v-dialog"]',
|
|
24824
|
+
// Naive UI
|
|
24825
|
+
'[class*="n-modal"]'
|
|
24826
|
+
];
|
|
24827
|
+
var DEFAULT_TOOLTIP_SELECTORS = [
|
|
24828
|
+
// W3C ARIA 标准
|
|
24829
|
+
'[role="tooltip"]',
|
|
24830
|
+
// Element Plus
|
|
24831
|
+
'[class*="el-tooltip-popper"]',
|
|
24832
|
+
'[class*="el-popper"]',
|
|
24833
|
+
// Ant Design
|
|
24834
|
+
'[class*="ant-tooltip"]',
|
|
24835
|
+
'[class*="ant-popover"]',
|
|
24836
|
+
// Naive UI
|
|
24837
|
+
'[class*="n-tooltip"]',
|
|
24838
|
+
'[class*="n-popover"]',
|
|
24839
|
+
// Vuetify
|
|
24840
|
+
'[class*="v-tooltip"]',
|
|
24841
|
+
'[class*="v-menu"]'
|
|
24842
|
+
];
|
|
25259
24843
|
var TAG_ROLE_MAP = {
|
|
25260
24844
|
a: "link",
|
|
25261
24845
|
article: "article",
|
|
@@ -25319,6 +24903,7 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25319
24903
|
tr: "row",
|
|
25320
24904
|
ul: "list"
|
|
25321
24905
|
};
|
|
24906
|
+
var DEFAULT_ROLE_OVERRIDES = [];
|
|
25322
24907
|
var INPUT_TYPE_ROLE = {
|
|
25323
24908
|
button: "button",
|
|
25324
24909
|
checkbox: "checkbox",
|
|
@@ -25337,6 +24922,307 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25337
24922
|
url: "textbox"
|
|
25338
24923
|
};
|
|
25339
24924
|
|
|
24925
|
+
// ../next-sdk/page-tools/a11y/config.ts
|
|
24926
|
+
var RESOLVED_A11Y_BRAND = Symbol.for("@opentiny/next-sdk:ResolvedA11yConfig");
|
|
24927
|
+
function markResolved(config2) {
|
|
24928
|
+
return Object.assign(config2, { [RESOLVED_A11Y_BRAND]: true });
|
|
24929
|
+
}
|
|
24930
|
+
function isResolvedA11yConfig(config2) {
|
|
24931
|
+
return !!config2 && config2[RESOLVED_A11Y_BRAND] === true;
|
|
24932
|
+
}
|
|
24933
|
+
var STANDARD_STATE_NAMES = [
|
|
24934
|
+
"checked",
|
|
24935
|
+
"selected",
|
|
24936
|
+
"pressed",
|
|
24937
|
+
"current",
|
|
24938
|
+
"expanded",
|
|
24939
|
+
"hasPopup",
|
|
24940
|
+
"disabled",
|
|
24941
|
+
"readonly",
|
|
24942
|
+
"required",
|
|
24943
|
+
"invalid",
|
|
24944
|
+
"busy",
|
|
24945
|
+
"error",
|
|
24946
|
+
"warning"
|
|
24947
|
+
];
|
|
24948
|
+
var DEFAULT_SELECTED_CLASS_RE = /\b(is-active|isActive|is-selected|isSelected|is-current|isCurrent|active-item|activeItem|tab-active|tabActive|active|selected|current)\b/;
|
|
24949
|
+
function defaultSelectedMatch(el) {
|
|
24950
|
+
const cls = typeof el.className === "string" ? el.className : "";
|
|
24951
|
+
if (!cls || !DEFAULT_SELECTED_CLASS_RE.test(cls)) return false;
|
|
24952
|
+
const role = el.getAttribute("role") || el.tagName.toLowerCase();
|
|
24953
|
+
return ["button", "option", "a", "li", "generic"].includes(role) || role.startsWith("tab");
|
|
24954
|
+
}
|
|
24955
|
+
var DEFAULT_A11Y_CONFIG = markResolved({
|
|
24956
|
+
// 框架级 role 覆盖:Tiny3 Tabs、tp-helptip 等非标准 UI 组件(规则定义见 constants.ts)
|
|
24957
|
+
// + dialog/tooltip 选择器转为 role 规则,统一走 roles 通道做 role 推断与 DOM 检测
|
|
24958
|
+
roles: [
|
|
24959
|
+
...DEFAULT_ROLE_OVERRIDES,
|
|
24960
|
+
// Dialog:补齐缺失的 role="dialog"(如 Tiny3 ti3-modal、Element Plus el-dialog)
|
|
24961
|
+
...DEFAULT_DIALOG_SELECTORS.map((s) => ({ selector: s, role: "dialog" })),
|
|
24962
|
+
// Tooltip:补齐缺失的 role="tooltip"(如 Tiny3 ti3-tooltip、Element Plus el-tooltip-popper)
|
|
24963
|
+
...DEFAULT_TOOLTIP_SELECTORS.map((s) => ({ selector: s, role: "tooltip" }))
|
|
24964
|
+
],
|
|
24965
|
+
states: {
|
|
24966
|
+
selected: [
|
|
24967
|
+
{ match: defaultSelectedMatch },
|
|
24968
|
+
// Tiny3 按钮组/单选按钮组:选中 class 在容器上(.ti3-btn-item-container.ti3-active),
|
|
24969
|
+
// 内部 button 自身无 aria-selected / ti3-active,需靠 closest 命中
|
|
24970
|
+
{ selector: ".ti3-btn-item-container.ti3-active" }
|
|
24971
|
+
],
|
|
24972
|
+
error: [{ selector: DEFAULT_ERROR_SELECTORS }],
|
|
24973
|
+
warning: [{ selector: DEFAULT_WARNING_SELECTORS }]
|
|
24974
|
+
},
|
|
24975
|
+
whitelist: [],
|
|
24976
|
+
blacklist: [],
|
|
24977
|
+
exposedAttributes: []
|
|
24978
|
+
});
|
|
24979
|
+
function normalizeSelector(selector) {
|
|
24980
|
+
if (!selector) return void 0;
|
|
24981
|
+
const joined = Array.isArray(selector) ? selector.filter(Boolean).join(", ") : selector;
|
|
24982
|
+
return joined || void 0;
|
|
24983
|
+
}
|
|
24984
|
+
function getSelectorsForRole(roles, targetRole) {
|
|
24985
|
+
const selectors = [];
|
|
24986
|
+
for (const rule of roles) {
|
|
24987
|
+
if (rule.role !== targetRole || !rule.selector) continue;
|
|
24988
|
+
if (Array.isArray(rule.selector)) {
|
|
24989
|
+
selectors.push(...rule.selector.filter(Boolean));
|
|
24990
|
+
} else {
|
|
24991
|
+
selectors.push(rule.selector);
|
|
24992
|
+
}
|
|
24993
|
+
}
|
|
24994
|
+
return selectors;
|
|
24995
|
+
}
|
|
24996
|
+
function matchesRule(el, rule) {
|
|
24997
|
+
if (rule.match) {
|
|
24998
|
+
try {
|
|
24999
|
+
return !!rule.match(el);
|
|
25000
|
+
} catch {
|
|
25001
|
+
return false;
|
|
25002
|
+
}
|
|
25003
|
+
}
|
|
25004
|
+
const selector = normalizeSelector(rule.selector);
|
|
25005
|
+
if (selector) {
|
|
25006
|
+
try {
|
|
25007
|
+
return !!el.closest(selector);
|
|
25008
|
+
} catch {
|
|
25009
|
+
return false;
|
|
25010
|
+
}
|
|
25011
|
+
}
|
|
25012
|
+
return false;
|
|
25013
|
+
}
|
|
25014
|
+
function matchesRoleRule(el, rule) {
|
|
25015
|
+
if (rule.match) {
|
|
25016
|
+
try {
|
|
25017
|
+
return !!rule.match(el);
|
|
25018
|
+
} catch {
|
|
25019
|
+
return false;
|
|
25020
|
+
}
|
|
25021
|
+
}
|
|
25022
|
+
const selector = normalizeSelector(rule.selector);
|
|
25023
|
+
if (selector) {
|
|
25024
|
+
try {
|
|
25025
|
+
return !!el.matches(selector);
|
|
25026
|
+
} catch {
|
|
25027
|
+
return false;
|
|
25028
|
+
}
|
|
25029
|
+
}
|
|
25030
|
+
return false;
|
|
25031
|
+
}
|
|
25032
|
+
function matchesAnyRule(el, rules) {
|
|
25033
|
+
if (!rules) return false;
|
|
25034
|
+
const list = Array.isArray(rules) ? rules : [rules];
|
|
25035
|
+
return list.some((rule) => matchesRule(el, rule));
|
|
25036
|
+
}
|
|
25037
|
+
function extractSelectors(rules) {
|
|
25038
|
+
if (!rules) return [];
|
|
25039
|
+
const list = Array.isArray(rules) ? rules : [rules];
|
|
25040
|
+
return list.flatMap((r) => Array.isArray(r.selector) ? r.selector.filter(Boolean) : r.selector ? [r.selector] : []);
|
|
25041
|
+
}
|
|
25042
|
+
function concatArr(a, b) {
|
|
25043
|
+
return [...a ?? [], ...b ?? []];
|
|
25044
|
+
}
|
|
25045
|
+
function normalizeMatcherList(value) {
|
|
25046
|
+
if (!value) return [];
|
|
25047
|
+
return Array.isArray(value) ? value : [value];
|
|
25048
|
+
}
|
|
25049
|
+
function mergeStates(base, patch) {
|
|
25050
|
+
const result2 = {};
|
|
25051
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(base ?? {}), ...Object.keys(patch ?? {})]);
|
|
25052
|
+
for (const key of keys) {
|
|
25053
|
+
result2[key] = [...normalizeMatcherList(base?.[key]), ...normalizeMatcherList(patch?.[key])];
|
|
25054
|
+
}
|
|
25055
|
+
return result2;
|
|
25056
|
+
}
|
|
25057
|
+
function mergeA11yConfigs(base, patch) {
|
|
25058
|
+
return markResolved({
|
|
25059
|
+
roles: concatArr(base.roles, patch.roles),
|
|
25060
|
+
states: mergeStates(base.states, patch.states),
|
|
25061
|
+
whitelist: concatArr(base.whitelist, patch.whitelist),
|
|
25062
|
+
blacklist: concatArr(base.blacklist, patch.blacklist),
|
|
25063
|
+
exposedAttributes: concatArr(base.exposedAttributes, patch.exposedAttributes)
|
|
25064
|
+
});
|
|
25065
|
+
}
|
|
25066
|
+
function mergeA11yConfig(user) {
|
|
25067
|
+
if (isResolvedA11yConfig(user)) return user;
|
|
25068
|
+
return mergeA11yConfigs(DEFAULT_A11Y_CONFIG, user ?? {});
|
|
25069
|
+
}
|
|
25070
|
+
function ensureResolvedA11yConfig(config2) {
|
|
25071
|
+
if (isResolvedA11yConfig(config2)) return config2;
|
|
25072
|
+
return mergeA11yConfig(config2);
|
|
25073
|
+
}
|
|
25074
|
+
function defineA11yConfig(config2) {
|
|
25075
|
+
return config2;
|
|
25076
|
+
}
|
|
25077
|
+
function findMatchedRoleRule(el, resolved) {
|
|
25078
|
+
const explicit = el.getAttribute("role");
|
|
25079
|
+
const hasExplicit = !!explicit && explicit !== "presentation" && explicit !== "none";
|
|
25080
|
+
for (const rule of resolved.roles) {
|
|
25081
|
+
if (hasExplicit && !rule.force) continue;
|
|
25082
|
+
if (matchesRoleRule(el, rule)) return rule;
|
|
25083
|
+
}
|
|
25084
|
+
return null;
|
|
25085
|
+
}
|
|
25086
|
+
function computeRole(el, resolved, matched = findMatchedRoleRule(el, resolved)) {
|
|
25087
|
+
if (matched) return matched.role;
|
|
25088
|
+
const explicit = el.getAttribute("role");
|
|
25089
|
+
if (explicit && explicit !== "presentation" && explicit !== "none") return explicit;
|
|
25090
|
+
const tag = el.tagName.toLowerCase();
|
|
25091
|
+
if (tag === "input") {
|
|
25092
|
+
const inputType = el.type?.toLowerCase() ?? "text";
|
|
25093
|
+
return INPUT_TYPE_ROLE[inputType] ?? "textbox";
|
|
25094
|
+
}
|
|
25095
|
+
return TAG_ROLE_MAP[tag] ?? "generic";
|
|
25096
|
+
}
|
|
25097
|
+
function computeStates(el, resolved) {
|
|
25098
|
+
const tokens = [];
|
|
25099
|
+
const aria = (k) => el.getAttribute(k);
|
|
25100
|
+
const states = resolved.states;
|
|
25101
|
+
const has = (name) => matchesAnyRule(el, states[name]);
|
|
25102
|
+
const ariaChecked = aria("aria-checked");
|
|
25103
|
+
if (ariaChecked === "true") {
|
|
25104
|
+
tokens.push("checked");
|
|
25105
|
+
} else if (ariaChecked === "mixed") {
|
|
25106
|
+
tokens.push("checked=mixed");
|
|
25107
|
+
} else if (ariaChecked === "false") {
|
|
25108
|
+
tokens.push("unchecked");
|
|
25109
|
+
} else {
|
|
25110
|
+
const elTag = el.tagName.toLowerCase();
|
|
25111
|
+
let nativeChecked;
|
|
25112
|
+
if (elTag === "input" && (el.type === "checkbox" || el.type === "radio")) {
|
|
25113
|
+
nativeChecked = el.checked;
|
|
25114
|
+
} else if (elTag === "label" && el.hasAttribute("for")) {
|
|
25115
|
+
const target = document.getElementById(el.getAttribute("for"));
|
|
25116
|
+
if (target instanceof HTMLInputElement && (target.type === "checkbox" || target.type === "radio")) {
|
|
25117
|
+
nativeChecked = target.checked;
|
|
25118
|
+
}
|
|
25119
|
+
}
|
|
25120
|
+
if (nativeChecked !== void 0) {
|
|
25121
|
+
tokens.push(nativeChecked ? "checked" : "unchecked");
|
|
25122
|
+
} else if (has("checked")) {
|
|
25123
|
+
tokens.push("checked");
|
|
25124
|
+
}
|
|
25125
|
+
}
|
|
25126
|
+
if (aria("aria-selected") === "true" || has("selected")) {
|
|
25127
|
+
tokens.push("selected");
|
|
25128
|
+
}
|
|
25129
|
+
const ariaPressed = aria("aria-pressed");
|
|
25130
|
+
if (ariaPressed === "true") {
|
|
25131
|
+
tokens.push("pressed");
|
|
25132
|
+
} else if (ariaPressed === "mixed") {
|
|
25133
|
+
tokens.push("pressed=mixed");
|
|
25134
|
+
} else if (ariaPressed !== "false" && has("pressed")) {
|
|
25135
|
+
tokens.push("pressed");
|
|
25136
|
+
}
|
|
25137
|
+
const ariaCurrent = aria("aria-current");
|
|
25138
|
+
if (ariaCurrent && ariaCurrent !== "false") {
|
|
25139
|
+
tokens.push(ariaCurrent === "true" ? "current" : `current=${ariaCurrent}`);
|
|
25140
|
+
} else if (has("current")) {
|
|
25141
|
+
tokens.push("current");
|
|
25142
|
+
}
|
|
25143
|
+
if (aria("aria-disabled") === "true" || el.disabled || has("disabled")) {
|
|
25144
|
+
tokens.push("disabled");
|
|
25145
|
+
}
|
|
25146
|
+
const ariaHasPopup = aria("aria-haspopup");
|
|
25147
|
+
if (ariaHasPopup && ariaHasPopup !== "false" || has("hasPopup")) {
|
|
25148
|
+
tokens.push("hasPopup");
|
|
25149
|
+
}
|
|
25150
|
+
if (aria("aria-expanded") === "true" || has("expanded")) {
|
|
25151
|
+
tokens.push("expanded");
|
|
25152
|
+
}
|
|
25153
|
+
const ariaInvalid = aria("aria-invalid");
|
|
25154
|
+
if (ariaInvalid && ariaInvalid !== "false") {
|
|
25155
|
+
tokens.push(ariaInvalid === "true" ? "invalid" : `invalid=${ariaInvalid}`);
|
|
25156
|
+
} else if (has("invalid")) {
|
|
25157
|
+
tokens.push("invalid");
|
|
25158
|
+
}
|
|
25159
|
+
if (aria("aria-readonly") === "true" || el.readOnly || has("readonly")) {
|
|
25160
|
+
tokens.push("readonly");
|
|
25161
|
+
}
|
|
25162
|
+
if (aria("aria-required") === "true" || el.required || has("required")) {
|
|
25163
|
+
tokens.push("required");
|
|
25164
|
+
}
|
|
25165
|
+
if (aria("aria-busy") === "true" || has("busy")) {
|
|
25166
|
+
tokens.push("busy");
|
|
25167
|
+
}
|
|
25168
|
+
const orientation = aria("aria-orientation");
|
|
25169
|
+
if (orientation) tokens.push(`orientation=${orientation}`);
|
|
25170
|
+
const sort = aria("aria-sort");
|
|
25171
|
+
if (sort && sort !== "none") tokens.push(`sort=${sort}`);
|
|
25172
|
+
if (aria("aria-multiselectable") === "true") tokens.push("multiselectable");
|
|
25173
|
+
const headingMatch = el.tagName.match(/^H([1-6])$/);
|
|
25174
|
+
if (headingMatch) tokens.push(`level=${headingMatch[1]}`);
|
|
25175
|
+
const ariaLevel = aria("aria-level");
|
|
25176
|
+
if (ariaLevel && !headingMatch) tokens.push(`level=${ariaLevel}`);
|
|
25177
|
+
try {
|
|
25178
|
+
const style = window.getComputedStyle(el);
|
|
25179
|
+
if (style.cursor === "pointer") tokens.push("cursor=pointer");
|
|
25180
|
+
} catch {
|
|
25181
|
+
}
|
|
25182
|
+
const tag = el.tagName.toLowerCase();
|
|
25183
|
+
if (tag === "input" || tag === "textarea" || tag === "select") {
|
|
25184
|
+
const val = el.value;
|
|
25185
|
+
if (val !== void 0 && val !== "") {
|
|
25186
|
+
tokens.push(`value="${val}"`);
|
|
25187
|
+
}
|
|
25188
|
+
}
|
|
25189
|
+
const valuenow = aria("aria-valuenow");
|
|
25190
|
+
if (valuenow) tokens.push(`valuenow="${valuenow}"`);
|
|
25191
|
+
const valuetext = aria("aria-valuetext");
|
|
25192
|
+
if (valuetext) tokens.push(`valuetext="${valuetext}"`);
|
|
25193
|
+
if (tag === "a") {
|
|
25194
|
+
const target = aria("target");
|
|
25195
|
+
if (target) tokens.push(`target=${target}`);
|
|
25196
|
+
}
|
|
25197
|
+
if (has("error")) {
|
|
25198
|
+
tokens.push("error");
|
|
25199
|
+
} else if (has("warning")) {
|
|
25200
|
+
tokens.push("warning");
|
|
25201
|
+
}
|
|
25202
|
+
for (const key of Object.keys(states)) {
|
|
25203
|
+
if (STANDARD_STATE_NAMES.includes(key)) continue;
|
|
25204
|
+
if (matchesAnyRule(el, states[key])) tokens.push(key);
|
|
25205
|
+
}
|
|
25206
|
+
for (const attr of resolved.exposedAttributes) {
|
|
25207
|
+
const val = el.getAttribute(attr);
|
|
25208
|
+
if (val !== null) tokens.push(`${attr}="${val}"`);
|
|
25209
|
+
}
|
|
25210
|
+
return Array.from(new Set(tokens));
|
|
25211
|
+
}
|
|
25212
|
+
function resolveA11yRole(el, config2) {
|
|
25213
|
+
return computeRole(el, ensureResolvedA11yConfig(config2));
|
|
25214
|
+
}
|
|
25215
|
+
function resolveA11yInfo(el, config2) {
|
|
25216
|
+
const resolved = ensureResolvedA11yConfig(config2);
|
|
25217
|
+
const matched = findMatchedRoleRule(el, resolved);
|
|
25218
|
+
const ruleName = matched?.name?.trim();
|
|
25219
|
+
return {
|
|
25220
|
+
role: computeRole(el, resolved, matched),
|
|
25221
|
+
tokens: computeStates(el, resolved),
|
|
25222
|
+
...ruleName ? { name: ruleName } : {}
|
|
25223
|
+
};
|
|
25224
|
+
}
|
|
25225
|
+
|
|
25340
25226
|
// ../../node_modules/.pnpm/tabbable@6.5.0/node_modules/tabbable/dist/index.esm.js
|
|
25341
25227
|
var candidateSelectors = ["input:not([inert]):not([inert] *)", "select:not([inert]):not([inert] *)", "textarea:not([inert]):not([inert] *)", "a[href]:not([inert]):not([inert] *)", "area[href]:not([inert]):not([inert] *)", "button:not([inert]):not([inert] *)", "[tabindex]:not(slot):not([inert]):not([inert] *)", "audio[controls]:not([inert]):not([inert] *)", "video[controls]:not([inert]):not([inert] *)", '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)', "details>summary:first-of-type:not([inert]):not([inert] *)", "details:not([inert]):not([inert] *)"];
|
|
25342
25228
|
var candidateSelector = /* @__PURE__ */ candidateSelectors.join(",");
|
|
@@ -25538,131 +25424,247 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25538
25424
|
return isNodeMatchingSelectorTabbable(options, node);
|
|
25539
25425
|
};
|
|
25540
25426
|
|
|
25541
|
-
// ../next-sdk/page-tools/
|
|
25542
|
-
|
|
25543
|
-
|
|
25544
|
-
|
|
25545
|
-
|
|
25427
|
+
// ../next-sdk/page-tools/tool-config.ts
|
|
25428
|
+
var DEFAULT_PAGE_AGENT_TOOL_CONFIG = {
|
|
25429
|
+
enableHighlight: false,
|
|
25430
|
+
removeMaskAfterToolCall: true,
|
|
25431
|
+
a11yConfig: DEFAULT_A11Y_CONFIG
|
|
25432
|
+
};
|
|
25433
|
+
function getPageAgentToolConfig() {
|
|
25434
|
+
if (typeof window !== "undefined" && window.__webmcpcli_toolConfig) {
|
|
25435
|
+
return window.__webmcpcli_toolConfig;
|
|
25546
25436
|
}
|
|
25547
|
-
|
|
25548
|
-
|
|
25549
|
-
|
|
25550
|
-
|
|
25437
|
+
return {
|
|
25438
|
+
enableHighlight: DEFAULT_PAGE_AGENT_TOOL_CONFIG.enableHighlight,
|
|
25439
|
+
removeMaskAfterToolCall: DEFAULT_PAGE_AGENT_TOOL_CONFIG.removeMaskAfterToolCall,
|
|
25440
|
+
a11yConfig: mergeA11yConfig()
|
|
25441
|
+
};
|
|
25442
|
+
}
|
|
25443
|
+
function resolvePatch(patch, base) {
|
|
25444
|
+
return {
|
|
25445
|
+
enableHighlight: patch.enableHighlight ?? base.enableHighlight,
|
|
25446
|
+
removeMaskAfterToolCall: patch.removeMaskAfterToolCall ?? base.removeMaskAfterToolCall,
|
|
25447
|
+
a11yConfig: mergeA11yConfigs(base.a11yConfig, patch.a11yConfig ?? {})
|
|
25448
|
+
};
|
|
25449
|
+
}
|
|
25450
|
+
function setPageAgentToolConfig(patch, options) {
|
|
25451
|
+
const mode = options?.mode ?? "merge";
|
|
25452
|
+
const current = getPageAgentToolConfig();
|
|
25453
|
+
const next = typeof patch === "function" ? resolvePatch(patch(current), DEFAULT_PAGE_AGENT_TOOL_CONFIG) : resolvePatch(patch, mode === "replace" ? DEFAULT_PAGE_AGENT_TOOL_CONFIG : current);
|
|
25454
|
+
if (typeof window !== "undefined") {
|
|
25455
|
+
window.__webmcpcli_toolConfig = next;
|
|
25551
25456
|
}
|
|
25552
|
-
return
|
|
25457
|
+
return next;
|
|
25553
25458
|
}
|
|
25554
|
-
|
|
25555
|
-
|
|
25556
|
-
|
|
25557
|
-
|
|
25558
|
-
|
|
25559
|
-
|
|
25560
|
-
|
|
25561
|
-
|
|
25562
|
-
} else {
|
|
25563
|
-
const elTag = el.tagName.toLowerCase();
|
|
25564
|
-
let nativeChecked;
|
|
25565
|
-
if (elTag === "input" && (el.type === "checkbox" || el.type === "radio")) {
|
|
25566
|
-
nativeChecked = el.checked;
|
|
25567
|
-
} else if (elTag === "label" && el.hasAttribute("for")) {
|
|
25568
|
-
const target = document.getElementById(el.getAttribute("for"));
|
|
25569
|
-
if (target instanceof HTMLInputElement && (target.type === "checkbox" || target.type === "radio")) {
|
|
25570
|
-
nativeChecked = target.checked;
|
|
25571
|
-
}
|
|
25572
|
-
}
|
|
25573
|
-
if (nativeChecked !== void 0) {
|
|
25574
|
-
tokens.push(nativeChecked ? "checked" : "unchecked");
|
|
25575
|
-
}
|
|
25576
|
-
}
|
|
25577
|
-
if (aria("aria-selected") === "true") tokens.push("selected");
|
|
25578
|
-
const disabled = aria("aria-disabled") === "true" || el.disabled;
|
|
25579
|
-
if (disabled) tokens.push("disabled");
|
|
25580
|
-
const hasPopup = aria("aria-haspopup");
|
|
25581
|
-
if (hasPopup && hasPopup !== "false") tokens.push("hasPopup");
|
|
25582
|
-
if (aria("aria-expanded") === "true") tokens.push("expanded");
|
|
25583
|
-
const headingMatch = el.tagName.match(/^H([1-6])$/);
|
|
25584
|
-
if (headingMatch) tokens.push(`level=${headingMatch[1]}`);
|
|
25585
|
-
const ariaLevel = aria("aria-level");
|
|
25586
|
-
if (ariaLevel && !headingMatch) tokens.push(`level=${ariaLevel}`);
|
|
25587
|
-
try {
|
|
25588
|
-
const style = window.getComputedStyle(el);
|
|
25589
|
-
if (style.cursor === "pointer") tokens.push("cursor=pointer");
|
|
25590
|
-
} catch {
|
|
25459
|
+
|
|
25460
|
+
// ../next-sdk/page-tools/utils/dom.ts
|
|
25461
|
+
function isInShadowDom(el) {
|
|
25462
|
+
return el.getRootNode() instanceof ShadowRoot;
|
|
25463
|
+
}
|
|
25464
|
+
function dispatchComposedEvents(el, ...types) {
|
|
25465
|
+
for (const type of types) {
|
|
25466
|
+
el.dispatchEvent(new Event(type, { bubbles: true, composed: true }));
|
|
25591
25467
|
}
|
|
25592
|
-
|
|
25593
|
-
|
|
25594
|
-
|
|
25595
|
-
|
|
25596
|
-
|
|
25468
|
+
}
|
|
25469
|
+
function deepQuerySelectorAll(selector, root = document) {
|
|
25470
|
+
const elements = Array.from(root.querySelectorAll(selector));
|
|
25471
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null);
|
|
25472
|
+
let currentNode = walker.currentNode;
|
|
25473
|
+
while (currentNode) {
|
|
25474
|
+
if (currentNode.shadowRoot) {
|
|
25475
|
+
elements.push(...deepQuerySelectorAll(selector, currentNode.shadowRoot));
|
|
25597
25476
|
}
|
|
25477
|
+
currentNode = walker.nextNode();
|
|
25598
25478
|
}
|
|
25599
|
-
|
|
25600
|
-
|
|
25601
|
-
|
|
25479
|
+
return elements;
|
|
25480
|
+
}
|
|
25481
|
+
function waitForDomSettled(timeout = 600, settleTime = 150) {
|
|
25482
|
+
return new Promise((resolve) => {
|
|
25483
|
+
let settled = false;
|
|
25484
|
+
let settleTimer;
|
|
25485
|
+
const finish = () => {
|
|
25486
|
+
if (settled) return;
|
|
25487
|
+
settled = true;
|
|
25488
|
+
observer.disconnect();
|
|
25489
|
+
if (settleTimer) clearTimeout(settleTimer);
|
|
25490
|
+
resolve();
|
|
25491
|
+
};
|
|
25492
|
+
const observer = new MutationObserver(() => {
|
|
25493
|
+
if (settleTimer) clearTimeout(settleTimer);
|
|
25494
|
+
settleTimer = setTimeout(finish, settleTime);
|
|
25495
|
+
});
|
|
25496
|
+
settleTimer = setTimeout(finish, settleTime);
|
|
25497
|
+
setTimeout(finish, timeout);
|
|
25498
|
+
observer.observe(document.body, {
|
|
25499
|
+
childList: true,
|
|
25500
|
+
subtree: true,
|
|
25501
|
+
attributes: true,
|
|
25502
|
+
attributeFilter: ["class", "style", "hidden"]
|
|
25503
|
+
});
|
|
25504
|
+
});
|
|
25505
|
+
}
|
|
25506
|
+
function detectPageDialog() {
|
|
25507
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25508
|
+
const dialogs = [];
|
|
25509
|
+
const selectors = getSelectorsForRole(getPageAgentToolConfig().a11yConfig.roles, "dialog");
|
|
25510
|
+
for (const selector of selectors) {
|
|
25511
|
+
try {
|
|
25512
|
+
for (const el of deepQuerySelectorAll(selector)) {
|
|
25513
|
+
if (seen.has(el)) continue;
|
|
25514
|
+
if (el.id?.includes("page-agent-runtime")) continue;
|
|
25515
|
+
if (el.closest("#page-agent-runtime_simulator-mask")) continue;
|
|
25516
|
+
const rect = el.getBoundingClientRect();
|
|
25517
|
+
if (rect.width < 50 || rect.height < 50) continue;
|
|
25518
|
+
const style = window.getComputedStyle(el);
|
|
25519
|
+
if (style.display === "none" || style.visibility === "hidden") continue;
|
|
25520
|
+
const isFixed = style.position === "fixed" || style.position === "absolute";
|
|
25521
|
+
const zIndex = parseInt(style.zIndex || "0", 10);
|
|
25522
|
+
if (!isFixed || zIndex < 100) continue;
|
|
25523
|
+
const vw = window.innerWidth;
|
|
25524
|
+
const vh = window.innerHeight;
|
|
25525
|
+
const coversCenter = rect.left < vw * 0.6 && rect.right > vw * 0.4 && rect.top < vh * 0.6 && rect.bottom > vh * 0.4;
|
|
25526
|
+
if (!coversCenter) continue;
|
|
25527
|
+
seen.add(el);
|
|
25528
|
+
const text = (el.textContent || "").trim().replace(/\s+/g, " ");
|
|
25529
|
+
if (text.length > 5) {
|
|
25530
|
+
const btns = el.querySelectorAll('button, [role="button"], a');
|
|
25531
|
+
const buttons = Array.from(btns).map((b) => (b.textContent || "").trim()).filter((t) => t.length > 0 && t.length < 20).slice(0, 5);
|
|
25532
|
+
dialogs.push({ text: text.substring(0, 300), buttons });
|
|
25533
|
+
}
|
|
25534
|
+
}
|
|
25535
|
+
} catch {
|
|
25536
|
+
}
|
|
25602
25537
|
}
|
|
25603
|
-
|
|
25604
|
-
|
|
25538
|
+
return dialogs;
|
|
25539
|
+
}
|
|
25540
|
+
function detectValidationErrors() {
|
|
25541
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25542
|
+
const errors = [];
|
|
25543
|
+
const selectors = extractSelectors(getPageAgentToolConfig().a11yConfig.states.error);
|
|
25544
|
+
for (const selector of selectors) {
|
|
25545
|
+
try {
|
|
25546
|
+
for (const el of deepQuerySelectorAll(selector)) {
|
|
25547
|
+
if (seen.has(el)) continue;
|
|
25548
|
+
if (Array.from(seen).some((s) => s.contains(el))) continue;
|
|
25549
|
+
const rect = el.getBoundingClientRect();
|
|
25550
|
+
if (rect.width < 1 || rect.height < 1) continue;
|
|
25551
|
+
const style = window.getComputedStyle(el);
|
|
25552
|
+
if (style.display === "none" || style.visibility === "hidden") continue;
|
|
25553
|
+
const text = (el.textContent || "").trim().replace(/\s+/g, " ");
|
|
25554
|
+
if (text.length > 2 && text.length < 200) {
|
|
25555
|
+
seen.add(el);
|
|
25556
|
+
errors.push(text);
|
|
25557
|
+
}
|
|
25558
|
+
}
|
|
25559
|
+
} catch {
|
|
25560
|
+
}
|
|
25605
25561
|
}
|
|
25606
|
-
|
|
25607
|
-
|
|
25608
|
-
|
|
25609
|
-
|
|
25610
|
-
|
|
25611
|
-
|
|
25612
|
-
|
|
25613
|
-
"isCurrent",
|
|
25614
|
-
"active-item",
|
|
25615
|
-
"activeItem",
|
|
25616
|
-
"tab-active",
|
|
25617
|
-
"tabActive",
|
|
25618
|
-
// 仅当作为独立 class 词或有连字符前缀时匹配 "active",避免误匹配 "interactive" 等
|
|
25619
|
-
/\bactive\b/,
|
|
25620
|
-
/\bselected\b/,
|
|
25621
|
-
/\bcurrent\b/
|
|
25622
|
-
];
|
|
25623
|
-
const hasActiveClass = ACTIVE_CLASS_PATTERNS.some(
|
|
25624
|
-
(p) => typeof p === "string" ? cls.split(/\s+/).includes(p) : p.test(cls)
|
|
25625
|
-
);
|
|
25626
|
-
const roleForActive = el.getAttribute("role") || el.tagName.toLowerCase();
|
|
25627
|
-
const roles = roleForActive.split(/\s+/);
|
|
25628
|
-
const isTabLike = roles.some((r) => ["button", "option", "a", "li", "generic"].includes(r) || r.startsWith("tab"));
|
|
25629
|
-
if (hasActiveClass && isTabLike && !tokens.includes("checked") && !tokens.includes("selected")) {
|
|
25630
|
-
tokens.push("active");
|
|
25631
|
-
}
|
|
25632
|
-
const errorSelector = Array.isArray(errorSelectors) ? errorSelectors.join(", ") : errorSelectors || DEFAULT_ERROR_SELECTORS.join(", ");
|
|
25633
|
-
const warningSelector = Array.isArray(warningSelectors) ? warningSelectors.join(", ") : warningSelectors || DEFAULT_WARNING_SELECTORS.join(", ");
|
|
25634
|
-
let errorAncestor = null;
|
|
25635
|
-
if (errorSelector) {
|
|
25562
|
+
return errors;
|
|
25563
|
+
}
|
|
25564
|
+
function getVisibleTooltipElements() {
|
|
25565
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25566
|
+
const tooltips = [];
|
|
25567
|
+
const selectors = getSelectorsForRole(getPageAgentToolConfig().a11yConfig.roles, "tooltip");
|
|
25568
|
+
for (const selector of selectors) {
|
|
25636
25569
|
try {
|
|
25637
|
-
|
|
25570
|
+
for (const el of deepQuerySelectorAll(selector)) {
|
|
25571
|
+
if (seen.has(el)) continue;
|
|
25572
|
+
if (Array.from(seen).some((s) => s.contains(el))) continue;
|
|
25573
|
+
const rect = el.getBoundingClientRect();
|
|
25574
|
+
if (rect.width < 1 || rect.height < 1) continue;
|
|
25575
|
+
const style = window.getComputedStyle(el);
|
|
25576
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") continue;
|
|
25577
|
+
const text = (el.textContent || "").trim().replace(/\s+/g, " ");
|
|
25578
|
+
if (text.length > 1) {
|
|
25579
|
+
if (el.querySelector?.('[name="cloudx-action-help"]')) continue;
|
|
25580
|
+
seen.add(el);
|
|
25581
|
+
tooltips.push({ el, text });
|
|
25582
|
+
}
|
|
25583
|
+
}
|
|
25638
25584
|
} catch {
|
|
25639
25585
|
}
|
|
25640
25586
|
}
|
|
25641
|
-
|
|
25642
|
-
|
|
25643
|
-
|
|
25644
|
-
|
|
25645
|
-
|
|
25587
|
+
return tooltips;
|
|
25588
|
+
}
|
|
25589
|
+
function detectVisibleTooltips() {
|
|
25590
|
+
return getVisibleTooltipElements().map((t) => t.text);
|
|
25591
|
+
}
|
|
25592
|
+
|
|
25593
|
+
// ../next-sdk/page-tools/a11y/utils.ts
|
|
25594
|
+
var NON_CONTENT_TAGS = /* @__PURE__ */ new Set([
|
|
25595
|
+
"script",
|
|
25596
|
+
"style",
|
|
25597
|
+
"noscript",
|
|
25598
|
+
"template",
|
|
25599
|
+
"link",
|
|
25600
|
+
"meta",
|
|
25601
|
+
"head",
|
|
25602
|
+
"title"
|
|
25603
|
+
]);
|
|
25604
|
+
function isNonContentElement(el) {
|
|
25605
|
+
return NON_CONTENT_TAGS.has(el.tagName.toLowerCase());
|
|
25606
|
+
}
|
|
25607
|
+
function hasOwnPointerCursor(el) {
|
|
25608
|
+
try {
|
|
25609
|
+
if (window.getComputedStyle(el).cursor !== "pointer") return false;
|
|
25610
|
+
const parent = el.parentElement;
|
|
25611
|
+
if (!parent) return true;
|
|
25612
|
+
return window.getComputedStyle(parent).cursor !== "pointer";
|
|
25613
|
+
} catch {
|
|
25614
|
+
return false;
|
|
25615
|
+
}
|
|
25616
|
+
}
|
|
25617
|
+
var INTERACTION_PSEUDO_RE = /:(hover|focus|focus-visible|focus-within|active)\b/gi;
|
|
25618
|
+
function collectInteractivePointerSelectors(rules, out) {
|
|
25619
|
+
for (const rule of Array.from(rules)) {
|
|
25620
|
+
const styleRule = rule;
|
|
25621
|
+
const grouping = rule;
|
|
25622
|
+
if (!styleRule.selectorText && grouping.cssRules) {
|
|
25623
|
+
collectInteractivePointerSelectors(grouping.cssRules, out);
|
|
25624
|
+
continue;
|
|
25625
|
+
}
|
|
25626
|
+
const sel = styleRule.selectorText;
|
|
25627
|
+
if (!sel || !styleRule.style || styleRule.style.cursor !== "pointer") continue;
|
|
25628
|
+
if (!/:(hover|focus|focus-visible|focus-within|active)\b/i.test(sel)) continue;
|
|
25629
|
+
for (const part of sel.split(",")) {
|
|
25630
|
+
const base = part.replace(INTERACTION_PSEUDO_RE, "").trim();
|
|
25631
|
+
if (base && base !== "*") out.add(base);
|
|
25632
|
+
}
|
|
25633
|
+
}
|
|
25634
|
+
}
|
|
25635
|
+
function collectHoverPointerElements(root) {
|
|
25636
|
+
const set = /* @__PURE__ */ new Set();
|
|
25637
|
+
const selectorSet = /* @__PURE__ */ new Set();
|
|
25638
|
+
try {
|
|
25639
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
25640
|
+
let rules = null;
|
|
25646
25641
|
try {
|
|
25647
|
-
|
|
25642
|
+
rules = sheet.cssRules;
|
|
25648
25643
|
} catch {
|
|
25644
|
+
continue;
|
|
25649
25645
|
}
|
|
25646
|
+
if (rules) collectInteractivePointerSelectors(rules, selectorSet);
|
|
25650
25647
|
}
|
|
25651
|
-
|
|
25652
|
-
|
|
25653
|
-
}
|
|
25648
|
+
} catch {
|
|
25649
|
+
return set;
|
|
25654
25650
|
}
|
|
25655
|
-
if (
|
|
25656
|
-
|
|
25657
|
-
|
|
25658
|
-
|
|
25659
|
-
|
|
25651
|
+
if (selectorSet.size === 0) return set;
|
|
25652
|
+
const selectors = Array.from(selectorSet);
|
|
25653
|
+
try {
|
|
25654
|
+
for (const el of deepQuerySelectorAll(selectors.join(", "), root)) set.add(el);
|
|
25655
|
+
return set;
|
|
25656
|
+
} catch {
|
|
25657
|
+
for (const sel of selectors) {
|
|
25658
|
+
try {
|
|
25659
|
+
for (const el of deepQuerySelectorAll(sel, root)) set.add(el);
|
|
25660
|
+
} catch {
|
|
25660
25661
|
}
|
|
25661
25662
|
}
|
|
25662
25663
|
}
|
|
25663
|
-
return
|
|
25664
|
+
return set;
|
|
25664
25665
|
}
|
|
25665
25666
|
function isHidden3(el) {
|
|
25667
|
+
if (isNonContentElement(el)) return true;
|
|
25666
25668
|
if (el.getAttribute("aria-hidden") === "true") return true;
|
|
25667
25669
|
if (el.hidden) return true;
|
|
25668
25670
|
try {
|
|
@@ -25677,26 +25679,32 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25677
25679
|
}
|
|
25678
25680
|
return false;
|
|
25679
25681
|
}
|
|
25680
|
-
function
|
|
25682
|
+
function collectTitleLabel(el) {
|
|
25683
|
+
const selfTitle = el.getAttribute("title")?.trim();
|
|
25684
|
+
if (selfTitle) return selfTitle;
|
|
25685
|
+
const titled = el.querySelector("[title]");
|
|
25686
|
+
const childTitle = titled?.getAttribute("title")?.trim();
|
|
25687
|
+
if (childTitle) return childTitle;
|
|
25688
|
+
return "";
|
|
25689
|
+
}
|
|
25690
|
+
function collectDescendantText(el, config2) {
|
|
25681
25691
|
let text = "";
|
|
25682
25692
|
const walk = (node) => {
|
|
25683
25693
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
25684
25694
|
text += (node.textContent ?? "") + " ";
|
|
25685
25695
|
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
25686
25696
|
const element = node;
|
|
25687
|
-
if (
|
|
25697
|
+
if (element !== el && isNonContentElement(element)) return;
|
|
25698
|
+
if (isHidden3(element) && element !== el) return;
|
|
25699
|
+
if (element === el && isNonContentElement(element)) return;
|
|
25688
25700
|
if (element !== el) {
|
|
25689
25701
|
const tag = element.tagName.toLowerCase();
|
|
25690
|
-
const role =
|
|
25702
|
+
const role = resolveA11yRole(element, config2);
|
|
25691
25703
|
const isInteractiveTag = ["button", "a", "input", "select", "textarea", "li", "option"].includes(tag);
|
|
25692
25704
|
const isInteractiveRole = ["button", "link", "checkbox", "radio", "textbox", "listitem", "option", "combobox", "listbox"].includes(role);
|
|
25693
25705
|
const isTrulyInteractive = isTabbable(element);
|
|
25694
|
-
|
|
25695
|
-
|
|
25696
|
-
isCursorPointer = window.getComputedStyle(element).cursor === "pointer";
|
|
25697
|
-
} catch {
|
|
25698
|
-
}
|
|
25699
|
-
const isMeaningfullyInteractive = isTrulyInteractive && !(role === "generic" && !isCursorPointer);
|
|
25706
|
+
const isOwnPointer = hasOwnPointerCursor(element);
|
|
25707
|
+
const isMeaningfullyInteractive = isTrulyInteractive && !(role === "generic" && !isOwnPointer);
|
|
25700
25708
|
if (isMeaningfullyInteractive || isInteractiveTag || isInteractiveRole) {
|
|
25701
25709
|
return;
|
|
25702
25710
|
}
|
|
@@ -25722,6 +25730,46 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
25722
25730
|
}
|
|
25723
25731
|
return result2;
|
|
25724
25732
|
}
|
|
25733
|
+
function extractTooltipText(el) {
|
|
25734
|
+
const title = el.getAttribute("title");
|
|
25735
|
+
if (title && title.trim()) {
|
|
25736
|
+
return title.trim().replace(/"/g, '\\"').substring(0, 200);
|
|
25737
|
+
}
|
|
25738
|
+
const describedby = el.getAttribute("aria-describedby");
|
|
25739
|
+
if (describedby) {
|
|
25740
|
+
for (const id of describedby.split(/\s+/)) {
|
|
25741
|
+
const ref = document.getElementById(id);
|
|
25742
|
+
if (ref) {
|
|
25743
|
+
const text = (ref.textContent || "").trim().replace(/\s+/g, " ");
|
|
25744
|
+
if (text) {
|
|
25745
|
+
return text.replace(/"/g, '\\"').substring(0, 200);
|
|
25746
|
+
}
|
|
25747
|
+
}
|
|
25748
|
+
}
|
|
25749
|
+
}
|
|
25750
|
+
for (const attr of ["data-tooltip", "data-tips", "data-tip"]) {
|
|
25751
|
+
const val = el.getAttribute(attr);
|
|
25752
|
+
if (val && val.trim()) {
|
|
25753
|
+
return val.trim().replace(/"/g, '\\"').substring(0, 200);
|
|
25754
|
+
}
|
|
25755
|
+
}
|
|
25756
|
+
const tag = el.tagName.toLowerCase();
|
|
25757
|
+
if (tag === "tp-helptip" || el.closest("tp-helptip")) {
|
|
25758
|
+
const helptipRoot = tag === "tp-helptip" ? el : el.closest("tp-helptip");
|
|
25759
|
+
const label = helptipRoot.querySelector('.tp-helptip-label, [class*="tp-helptip-label"]');
|
|
25760
|
+
if (label) {
|
|
25761
|
+
const text = (label.textContent || "").trim();
|
|
25762
|
+
if (text) {
|
|
25763
|
+
return text.replace(/"/g, '\\"').substring(0, 200);
|
|
25764
|
+
}
|
|
25765
|
+
}
|
|
25766
|
+
}
|
|
25767
|
+
const matTooltip = el.getAttribute("mattooltip") || el.getAttribute("matTooltip");
|
|
25768
|
+
if (matTooltip && matTooltip.trim()) {
|
|
25769
|
+
return matTooltip.trim().replace(/"/g, '\\"').substring(0, 200);
|
|
25770
|
+
}
|
|
25771
|
+
return "";
|
|
25772
|
+
}
|
|
25725
25773
|
|
|
25726
25774
|
// ../../node_modules/.pnpm/dom-accessibility-api@0.6.3/node_modules/dom-accessibility-api/dist/polyfills/array.from.mjs
|
|
25727
25775
|
var toStr = Object.prototype.toString;
|
|
@@ -26512,43 +26560,95 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26512
26560
|
}
|
|
26513
26561
|
|
|
26514
26562
|
// ../next-sdk/page-tools/a11y/vnode.ts
|
|
26515
|
-
|
|
26516
|
-
|
|
26517
|
-
|
|
26518
|
-
|
|
26519
|
-
|
|
26563
|
+
var INTERACTIVE_ROLES = /* @__PURE__ */ new Set([
|
|
26564
|
+
"button",
|
|
26565
|
+
"link",
|
|
26566
|
+
"textbox",
|
|
26567
|
+
"searchbox",
|
|
26568
|
+
"combobox",
|
|
26569
|
+
"listbox",
|
|
26570
|
+
"checkbox",
|
|
26571
|
+
"radio",
|
|
26572
|
+
"switch",
|
|
26573
|
+
"slider",
|
|
26574
|
+
"spinbutton",
|
|
26575
|
+
"menuitem",
|
|
26576
|
+
"menuitemcheckbox",
|
|
26577
|
+
"menuitemradio",
|
|
26578
|
+
"tab",
|
|
26579
|
+
"treeitem"
|
|
26580
|
+
]);
|
|
26581
|
+
function buildVNode(el, refCounter, refMap, blacklistSet, whitelistSet, config2, hoverPointerSet = /* @__PURE__ */ new Set()) {
|
|
26582
|
+
if (isNonContentElement(el) || isHidden3(el) || blacklistSet.has(el)) return null;
|
|
26583
|
+
const { role, tokens, name: ruleName } = resolveA11yInfo(el, config2);
|
|
26584
|
+
const declaredName = typeof ruleName === "string" && ruleName.trim() || getOwnDeclaredName(el) || "";
|
|
26585
|
+
const tooltipText = extractTooltipText(el);
|
|
26586
|
+
if (tooltipText) {
|
|
26587
|
+
tokens.push(`tooltip="${tooltipText}"`);
|
|
26588
|
+
}
|
|
26589
|
+
const hasTooltip = tokens.some((t) => t.startsWith("tooltip="));
|
|
26590
|
+
let name = declaredName || computeAccessibleName(el);
|
|
26520
26591
|
const isTrulyInteractive = isTabbable(el);
|
|
26521
26592
|
const isVisuallyClickable = tokens.includes("cursor=pointer");
|
|
26522
|
-
const
|
|
26593
|
+
const hasClickableCursor = hasOwnPointerCursor(el) || hoverPointerSet.has(el);
|
|
26594
|
+
const isWhitelisted = whitelistSet.has(el);
|
|
26523
26595
|
const isLabelFor = el.tagName.toLowerCase() === "label" && el.hasAttribute("for");
|
|
26524
26596
|
if (!name.trim()) {
|
|
26525
26597
|
const tag = el.tagName.toLowerCase();
|
|
26526
26598
|
const isDropdown = tag === "select" || role === "combobox" || role === "listbox";
|
|
26527
26599
|
if (!isDropdown) {
|
|
26528
26600
|
const isInteractiveTag = ["button", "a", "input", "textarea", "li", "label"].includes(tag);
|
|
26529
|
-
if (isTrulyInteractive || isWhitelisted || isVisuallyClickable || isInteractiveTag || role === "listitem" || role === "option") {
|
|
26530
|
-
name = collectDescendantText(el);
|
|
26601
|
+
if (isTrulyInteractive || isWhitelisted || isVisuallyClickable || hasClickableCursor || isInteractiveTag || role === "listitem" || role === "option" || role === "button") {
|
|
26602
|
+
name = collectDescendantText(el, config2);
|
|
26531
26603
|
}
|
|
26532
26604
|
}
|
|
26533
26605
|
}
|
|
26606
|
+
if (!name.trim() && (isTrulyInteractive || isWhitelisted || isVisuallyClickable || hasClickableCursor || role === "button")) {
|
|
26607
|
+
name = collectTitleLabel(el);
|
|
26608
|
+
}
|
|
26609
|
+
if (!name.trim() && role === "button") {
|
|
26610
|
+
const iconName = el.getAttribute("name") || "";
|
|
26611
|
+
if (iconName.includes("help") || iconName.includes("tip") || iconName.includes("info")) {
|
|
26612
|
+
name = "\u5E2E\u52A9";
|
|
26613
|
+
}
|
|
26614
|
+
}
|
|
26615
|
+
if (!name.trim() && hasTooltip) {
|
|
26616
|
+
const tooltipToken = tokens.find((t) => t.startsWith("tooltip="));
|
|
26617
|
+
if (tooltipToken) {
|
|
26618
|
+
name = tooltipToken.replace(/^tooltip="/, "").replace(/"$/, "");
|
|
26619
|
+
}
|
|
26620
|
+
}
|
|
26621
|
+
if (!name.trim() && ["tab", "menuitem", "option", "treeitem", "button"].includes(role)) {
|
|
26622
|
+
name = collectVisiblePlainText(el);
|
|
26623
|
+
}
|
|
26534
26624
|
if (!name.trim()) {
|
|
26535
26625
|
const hasElementChildren = getComposedChildren(el).length > 0;
|
|
26536
26626
|
if (!hasElementChildren) {
|
|
26537
|
-
const text = collectDescendantText(el);
|
|
26627
|
+
const text = collectDescendantText(el, config2);
|
|
26538
26628
|
if (text) {
|
|
26539
26629
|
name = text;
|
|
26540
26630
|
}
|
|
26541
26631
|
}
|
|
26542
26632
|
}
|
|
26543
26633
|
const tagName = el.tagName.toLowerCase();
|
|
26544
|
-
const isSemanticInteractiveTag = tagName === "a" && el.hasAttribute("href") || ["button", "input", "select", "textarea"].includes(tagName) && !el.hasAttribute("disabled");
|
|
26545
|
-
const isMeaningfullyInteractive = isTrulyInteractive && !(role === "generic" && !
|
|
26546
|
-
const
|
|
26634
|
+
const isSemanticInteractiveTag = tagName === "a" && el.hasAttribute("href") || ["button", "input", "select", "textarea"].includes(tagName) && !el.hasAttribute("disabled") || role === "button" && isVisuallyClickable && !["button", "a", "input", "select", "textarea"].includes(tagName);
|
|
26635
|
+
const isMeaningfullyInteractive = isTrulyInteractive && !(role === "generic" && !hasClickableCursor);
|
|
26636
|
+
const isDisabled2 = tokens.includes("disabled");
|
|
26637
|
+
const interactive = !isDisabled2 && isMeaningfullyInteractive || isWhitelisted || isLabelFor || isSemanticInteractiveTag || !isDisabled2 && INTERACTIVE_ROLES.has(role) || // hasClickableCursor 已排除 CSS 继承(hasOwnPointerCursor)并覆盖 hover 态手势,
|
|
26638
|
+
// 无需再要求 role≠generic 或 name≠''——否则无文本的图标按钮(tp-icon.common-icon 等)
|
|
26639
|
+
// 虽是真正的可点击边界,仍会因 generic+空名被漏判。
|
|
26640
|
+
!isDisabled2 && hasClickableCursor || // 有 tooltip 的元素分配 ref,使 AI 能 hover 触发动态 tip
|
|
26641
|
+
hasTooltip;
|
|
26547
26642
|
let ref;
|
|
26548
26643
|
if (interactive) {
|
|
26549
26644
|
ref = refCounter.value;
|
|
26550
26645
|
refMap.set(ref, el);
|
|
26551
26646
|
refCounter.value++;
|
|
26647
|
+
const idVal = el.getAttribute("id");
|
|
26648
|
+
if (idVal) {
|
|
26649
|
+
const idToken = `id="${idVal}"`;
|
|
26650
|
+
if (!tokens.includes(idToken)) tokens.push(idToken);
|
|
26651
|
+
}
|
|
26552
26652
|
}
|
|
26553
26653
|
const children = [];
|
|
26554
26654
|
for (const child of getComposedChildren(el)) {
|
|
@@ -26558,15 +26658,113 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26558
26658
|
refMap,
|
|
26559
26659
|
blacklistSet,
|
|
26560
26660
|
whitelistSet,
|
|
26561
|
-
|
|
26562
|
-
|
|
26563
|
-
warningSelectors,
|
|
26564
|
-
// 将当前节点的交互性向下传递,子节点据此决定是否抑制 cursor=pointer
|
|
26565
|
-
interactive || ancestorIsInteractive
|
|
26661
|
+
config2,
|
|
26662
|
+
hoverPointerSet
|
|
26566
26663
|
);
|
|
26567
26664
|
if (childVNode) children.push(childVNode);
|
|
26568
26665
|
}
|
|
26569
|
-
|
|
26666
|
+
const vnode = {
|
|
26667
|
+
role,
|
|
26668
|
+
name,
|
|
26669
|
+
...declaredName ? { declaredName } : {},
|
|
26670
|
+
tokens,
|
|
26671
|
+
ref,
|
|
26672
|
+
el,
|
|
26673
|
+
children
|
|
26674
|
+
};
|
|
26675
|
+
if (hasInteractiveDescendant(vnode)) {
|
|
26676
|
+
vnode.name = declaredName || getOwnDeclaredName(el);
|
|
26677
|
+
}
|
|
26678
|
+
return vnode;
|
|
26679
|
+
}
|
|
26680
|
+
function resolveDeclaredName(vnode) {
|
|
26681
|
+
if (vnode.declaredName?.trim()) return vnode.declaredName.trim();
|
|
26682
|
+
return getOwnDeclaredName(vnode.el);
|
|
26683
|
+
}
|
|
26684
|
+
function getOwnDeclaredName(el) {
|
|
26685
|
+
if (el.hasAttribute("aria-label") || el.hasAttribute("aria-labelledby")) {
|
|
26686
|
+
return computeAccessibleName(el).trim();
|
|
26687
|
+
}
|
|
26688
|
+
return "";
|
|
26689
|
+
}
|
|
26690
|
+
function isStaticBranch(vnode) {
|
|
26691
|
+
return vnode.ref === void 0 && !hasInteractiveDescendant(vnode);
|
|
26692
|
+
}
|
|
26693
|
+
var LANDMARK_ROLES = /* @__PURE__ */ new Set([
|
|
26694
|
+
"banner",
|
|
26695
|
+
"complementary",
|
|
26696
|
+
"contentinfo",
|
|
26697
|
+
"form",
|
|
26698
|
+
"main",
|
|
26699
|
+
"navigation",
|
|
26700
|
+
"region",
|
|
26701
|
+
"search"
|
|
26702
|
+
]);
|
|
26703
|
+
function isStructuralNamedNode(vnode) {
|
|
26704
|
+
return !!vnode.declaredName?.trim() || LANDMARK_ROLES.has(vnode.role);
|
|
26705
|
+
}
|
|
26706
|
+
function isEmptyLandmarkShell(vnode, hasInteractive) {
|
|
26707
|
+
if (!isStructuralNamedNode(vnode) || vnode.ref !== void 0 || hasInteractive) return false;
|
|
26708
|
+
if (vnode.children.some(hasValue)) return false;
|
|
26709
|
+
if (collectDirectTextNodes(vnode.el).trim()) return false;
|
|
26710
|
+
const declared = resolveDeclaredName(vnode);
|
|
26711
|
+
const name = vnode.name.trim();
|
|
26712
|
+
if (name && declared && name !== declared) return false;
|
|
26713
|
+
if (name && !declared) return false;
|
|
26714
|
+
return true;
|
|
26715
|
+
}
|
|
26716
|
+
function containsStructuralNamed(vnode) {
|
|
26717
|
+
return vnode.children.some((c) => isStructuralNamedNode(c) || containsStructuralNamed(c));
|
|
26718
|
+
}
|
|
26719
|
+
function collectVisiblePlainText(el) {
|
|
26720
|
+
return collectDescendantText(el).replace(/\s+/g, " ").trim();
|
|
26721
|
+
}
|
|
26722
|
+
function collectDirectTextNodes(el) {
|
|
26723
|
+
let text = "";
|
|
26724
|
+
for (const node of Array.from(el.childNodes)) {
|
|
26725
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
26726
|
+
text += (node.textContent ?? "") + " ";
|
|
26727
|
+
}
|
|
26728
|
+
}
|
|
26729
|
+
return text.replace(/\s+/g, " ").trim();
|
|
26730
|
+
}
|
|
26731
|
+
function getStaticDisplayText(vnode) {
|
|
26732
|
+
if (isStructuralNamedNode(vnode)) {
|
|
26733
|
+
return "";
|
|
26734
|
+
}
|
|
26735
|
+
const childJoined = vnode.children.length > 0 ? vnode.children.filter((c) => !isStructuralNamedNode(c)).map(getStaticDisplayText).filter(Boolean).join(" ").replace(/\s+/g, " ").trim() : "";
|
|
26736
|
+
const plain = vnode.children.length === 0 ? collectVisiblePlainText(vnode.el) : "";
|
|
26737
|
+
const named = vnode.name.trim();
|
|
26738
|
+
const parts = [];
|
|
26739
|
+
if (named && !isNoiseAccessibleName(named)) parts.push(named);
|
|
26740
|
+
if (childJoined && !isNoiseAccessibleName(childJoined)) {
|
|
26741
|
+
const normNamed = named.replace(/\s+/g, " ").trim();
|
|
26742
|
+
const normChild = childJoined.replace(/\s+/g, " ").trim();
|
|
26743
|
+
if (!normNamed || normChild !== normNamed && !normNamed.includes(normChild)) {
|
|
26744
|
+
parts.push(childJoined);
|
|
26745
|
+
}
|
|
26746
|
+
}
|
|
26747
|
+
if (parts.length === 0 && plain && !isNoiseAccessibleName(plain)) parts.push(plain);
|
|
26748
|
+
return parts.join(" ").replace(/\s+/g, " ").trim();
|
|
26749
|
+
}
|
|
26750
|
+
function isNoiseAccessibleName(name) {
|
|
26751
|
+
const n = name.trim();
|
|
26752
|
+
if (!n) return false;
|
|
26753
|
+
if (/@font-face\b/i.test(n)) return true;
|
|
26754
|
+
if (/data:(?:font|application|image)\//i.test(n)) return true;
|
|
26755
|
+
if (/base64,[A-Za-z0-9+/=]{80,}/.test(n)) return true;
|
|
26756
|
+
return false;
|
|
26757
|
+
}
|
|
26758
|
+
function canOmitStaticChild(child, parentOutputName, parentUsesOwnDeclaredName) {
|
|
26759
|
+
if (isStructuralNamedNode(child)) return false;
|
|
26760
|
+
const text = getStaticDisplayText(child);
|
|
26761
|
+
if (!text || !parentOutputName.trim()) return false;
|
|
26762
|
+
const parentNorm = parentOutputName.replace(/\s+/g, " ").trim();
|
|
26763
|
+
const textNorm = text.replace(/\s+/g, " ").trim();
|
|
26764
|
+
if (parentUsesOwnDeclaredName) {
|
|
26765
|
+
return textNorm === parentNorm;
|
|
26766
|
+
}
|
|
26767
|
+
return parentNorm.includes(textNorm);
|
|
26570
26768
|
}
|
|
26571
26769
|
function hasValue(vnode) {
|
|
26572
26770
|
if (vnode.ref !== void 0 || vnode.name.trim() !== "") return true;
|
|
@@ -26592,31 +26790,68 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26592
26790
|
if (vnode.name.trim() !== "") return false;
|
|
26593
26791
|
return true;
|
|
26594
26792
|
}
|
|
26793
|
+
function formatNameAttr(name) {
|
|
26794
|
+
const safe = name.replace(/[\r\n]+/g, " ").replace(/"/g, '\\"').trim();
|
|
26795
|
+
return safe ? ` "${safe}"` : "";
|
|
26796
|
+
}
|
|
26595
26797
|
function serializeVNode(vnode, depth, opts) {
|
|
26596
|
-
|
|
26597
|
-
|
|
26598
|
-
}
|
|
26798
|
+
const hasInteractive = hasInteractiveDescendant(vnode);
|
|
26799
|
+
const forceKeepStructure = opts.preserveRoles.includes(vnode.role) || isStructuralNamedNode(vnode);
|
|
26599
26800
|
const indent = " ".repeat(depth);
|
|
26600
26801
|
const refStr = vnode.ref !== void 0 ? ` #${vnode.ref}` : "";
|
|
26601
26802
|
const safeTokens = vnode.tokens.map((t) => t.replace(/[\r\n]+/g, " ").replace(/"/g, '\\"'));
|
|
26602
26803
|
const tokenStr = safeTokens.length > 0 ? ` [${safeTokens.join(" ")}]` : "";
|
|
26603
|
-
if (vnode
|
|
26604
|
-
|
|
26605
|
-
|
|
26606
|
-
|
|
26607
|
-
|
|
26804
|
+
if (isEmptyLandmarkShell(vnode, hasInteractive)) {
|
|
26805
|
+
return [];
|
|
26806
|
+
}
|
|
26807
|
+
if (!hasInteractive && !forceKeepStructure) {
|
|
26808
|
+
if (shouldPassThrough(vnode, opts)) {
|
|
26809
|
+
return vnode.children.filter((c) => hasValue(c)).flatMap((c) => serializeVNode(c, depth, opts));
|
|
26608
26810
|
}
|
|
26811
|
+
let displayName = vnode.name.trim();
|
|
26812
|
+
if (!displayName && vnode.children.length > 0) {
|
|
26813
|
+
displayName = collectVisiblePlainText(vnode.el);
|
|
26814
|
+
}
|
|
26815
|
+
if (isNoiseAccessibleName(displayName)) displayName = "";
|
|
26816
|
+
return [`${indent}- ${vnode.role}${refStr}${tokenStr}${formatNameAttr(displayName)}`];
|
|
26817
|
+
}
|
|
26818
|
+
if (!hasInteractive && forceKeepStructure) {
|
|
26819
|
+
const outputName2 = resolveDeclaredName(vnode);
|
|
26820
|
+
const line2 = `${indent}- ${vnode.role}${refStr}${tokenStr}${formatNameAttr(outputName2)}`;
|
|
26821
|
+
const childLines2 = vnode.children.flatMap((c) => serializeVNode(c, depth + 1, opts));
|
|
26822
|
+
return [line2, ...childLines2];
|
|
26823
|
+
}
|
|
26824
|
+
const ownDeclaredName = resolveDeclaredName(vnode);
|
|
26825
|
+
const parentUsesOwnDeclaredName = ownDeclaredName !== "";
|
|
26826
|
+
const staticChildren = vnode.children.filter(
|
|
26827
|
+
(c) => isStaticBranch(c) && !isStructuralNamedNode(c) && !containsStructuralNamed(c)
|
|
26828
|
+
);
|
|
26829
|
+
const liftedStaticName = staticChildren.map(getStaticDisplayText).filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
|
|
26830
|
+
const liftedDirectText = collectDirectTextNodes(vnode.el);
|
|
26831
|
+
const effectiveLifted = [liftedStaticName, liftedDirectText].filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
|
|
26832
|
+
let outputName = parentUsesOwnDeclaredName ? ownDeclaredName : effectiveLifted;
|
|
26833
|
+
if (isNoiseAccessibleName(outputName)) outputName = "";
|
|
26834
|
+
if (!parentUsesOwnDeclaredName && isNoiseAccessibleName(vnode.name)) {
|
|
26835
|
+
outputName = effectiveLifted && !isNoiseAccessibleName(effectiveLifted) ? effectiveLifted : "";
|
|
26836
|
+
}
|
|
26837
|
+
const willEmitParent = vnode.ref !== void 0 || outputName !== "" || forceKeepStructure || !opts.pruneUnnamed;
|
|
26838
|
+
if (!willEmitParent) {
|
|
26839
|
+
return vnode.children.filter((c) => hasValue(c)).flatMap((c) => serializeVNode(c, depth, opts));
|
|
26840
|
+
}
|
|
26841
|
+
if (vnode.ref !== void 0) {
|
|
26609
26842
|
const singleChild = findSingleRefDescendant(vnode);
|
|
26610
|
-
if (singleChild && singleChild.role === "generic" && !hasInteractiveDescendant(singleChild)) {
|
|
26611
|
-
const mergedName =
|
|
26612
|
-
const
|
|
26613
|
-
return [`${indent}- ${vnode.role}${
|
|
26843
|
+
if (singleChild && singleChild.role === "generic" && !hasInteractiveDescendant(singleChild) && staticChildren.length === 0) {
|
|
26844
|
+
const mergedName = outputName.trim() || singleChild.name.trim();
|
|
26845
|
+
const mergedRefStr = singleChild.ref !== void 0 ? ` #${singleChild.ref}` : refStr;
|
|
26846
|
+
return [`${indent}- ${vnode.role}${mergedRefStr}${tokenStr}${formatNameAttr(mergedName)}`];
|
|
26614
26847
|
}
|
|
26615
26848
|
}
|
|
26616
|
-
const
|
|
26617
|
-
|
|
26618
|
-
|
|
26619
|
-
|
|
26849
|
+
const childrenToEmit = vnode.children.filter((c) => {
|
|
26850
|
+
if (!isStaticBranch(c)) return true;
|
|
26851
|
+
return !canOmitStaticChild(c, outputName, parentUsesOwnDeclaredName);
|
|
26852
|
+
});
|
|
26853
|
+
const line = `${indent}- ${vnode.role}${refStr}${tokenStr}${formatNameAttr(outputName)}`;
|
|
26854
|
+
const childLines = childrenToEmit.flatMap((c) => serializeVNode(c, depth + 1, opts));
|
|
26620
26855
|
return [line, ...childLines];
|
|
26621
26856
|
}
|
|
26622
26857
|
|
|
@@ -26666,9 +26901,40 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26666
26901
|
border-radius: 4px;
|
|
26667
26902
|
}
|
|
26668
26903
|
`;
|
|
26669
|
-
|
|
26670
|
-
|
|
26671
|
-
|
|
26904
|
+
var MAX_ICON_FALLBACK_SIZE = 48;
|
|
26905
|
+
function resolveHighlightRect(el) {
|
|
26906
|
+
const rect = el.getBoundingClientRect();
|
|
26907
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
26908
|
+
return { top: rect.top, left: rect.left, width: rect.width, height: rect.height };
|
|
26909
|
+
}
|
|
26910
|
+
let parent = el.parentElement;
|
|
26911
|
+
for (let depth = 0; depth < 3 && parent; depth++) {
|
|
26912
|
+
const pr = parent.getBoundingClientRect();
|
|
26913
|
+
if (pr.width > 0 && pr.height > 0 && pr.width <= MAX_ICON_FALLBACK_SIZE && pr.height <= MAX_ICON_FALLBACK_SIZE) {
|
|
26914
|
+
return { top: pr.top, left: pr.left, width: pr.width, height: pr.height };
|
|
26915
|
+
}
|
|
26916
|
+
parent = parent.parentElement;
|
|
26917
|
+
}
|
|
26918
|
+
if (rect.width > 0 || rect.height > 0) {
|
|
26919
|
+
try {
|
|
26920
|
+
const fs = parseFloat(getComputedStyle(el).fontSize) || 16;
|
|
26921
|
+
const width = rect.width > 0 ? rect.width : fs;
|
|
26922
|
+
const height = rect.height > 0 ? rect.height : fs;
|
|
26923
|
+
return {
|
|
26924
|
+
top: rect.height > 0 ? rect.top : rect.top - (height - rect.height) / 2,
|
|
26925
|
+
left: rect.width > 0 ? rect.left : rect.left - (width - rect.width) / 2,
|
|
26926
|
+
width,
|
|
26927
|
+
height
|
|
26928
|
+
};
|
|
26929
|
+
} catch {
|
|
26930
|
+
}
|
|
26931
|
+
}
|
|
26932
|
+
return null;
|
|
26933
|
+
}
|
|
26934
|
+
function isRectInViewport(rect) {
|
|
26935
|
+
const vh = window.innerHeight || document.documentElement.clientHeight;
|
|
26936
|
+
const vw = window.innerWidth || document.documentElement.clientWidth;
|
|
26937
|
+
return rect.top < vh && rect.top + rect.height > 0 && rect.left < vw && rect.left + rect.width > 0;
|
|
26672
26938
|
}
|
|
26673
26939
|
var doHighlight = (refMap, parentIframe = null) => {
|
|
26674
26940
|
if (!document.head.querySelector(`#${HIGHLIGHT_CONTAINER_STYLE_ID}`)) {
|
|
@@ -26692,29 +26958,29 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26692
26958
|
iframeOffset.y = iframeRect.top;
|
|
26693
26959
|
}
|
|
26694
26960
|
const fragment = document.createDocumentFragment();
|
|
26695
|
-
const overlays = [];
|
|
26696
26961
|
for (const [index, el] of refMap.entries()) {
|
|
26697
|
-
|
|
26962
|
+
const rect = resolveHighlightRect(el);
|
|
26963
|
+
if (!rect) continue;
|
|
26964
|
+
const top = rect.top + iframeOffset.y;
|
|
26965
|
+
const left = rect.left + iframeOffset.x;
|
|
26966
|
+
const viewportRect = { top, left, width: rect.width, height: rect.height };
|
|
26967
|
+
if (!isRectInViewport(viewportRect)) continue;
|
|
26698
26968
|
const color = colors[index % colors.length];
|
|
26699
26969
|
const textColor = color + opacity;
|
|
26700
|
-
const rect = el.getBoundingClientRect();
|
|
26701
|
-
if (rect.width === 0 || rect.height === 0) continue;
|
|
26702
26970
|
const overlay = document.createElement("div");
|
|
26703
26971
|
overlay.style.border = `2px solid ${textColor}`;
|
|
26704
|
-
|
|
26705
|
-
const left = rect.left + iframeOffset.x;
|
|
26972
|
+
overlay.dataset.refIndex = String(index);
|
|
26706
26973
|
overlay.style.top = `${top}px`;
|
|
26707
26974
|
overlay.style.left = `${left}px`;
|
|
26708
26975
|
overlay.style.width = `${rect.width}px`;
|
|
26709
26976
|
overlay.style.height = `${rect.height}px`;
|
|
26710
26977
|
const text = document.createElement("span");
|
|
26711
26978
|
text.style.backgroundColor = textColor;
|
|
26712
|
-
text.style.height = `${rect.height - 4}px`;
|
|
26713
|
-
text.style.lineHeight = `${rect.height - 4}px`;
|
|
26979
|
+
text.style.height = `${Math.max(rect.height - 4, 0)}px`;
|
|
26980
|
+
text.style.lineHeight = `${Math.max(rect.height - 4, 0)}px`;
|
|
26714
26981
|
text.textContent = index.toString();
|
|
26715
26982
|
overlay.appendChild(text);
|
|
26716
26983
|
fragment.appendChild(overlay);
|
|
26717
|
-
overlays.push({ element: overlay, initialRect: rect });
|
|
26718
26984
|
}
|
|
26719
26985
|
container.appendChild(fragment);
|
|
26720
26986
|
};
|
|
@@ -26780,34 +27046,36 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26780
27046
|
};
|
|
26781
27047
|
|
|
26782
27048
|
// ../next-sdk/page-tools/a11y/build.ts
|
|
26783
|
-
|
|
26784
|
-
|
|
26785
|
-
|
|
26786
|
-
|
|
26787
|
-
|
|
26788
|
-
|
|
26789
|
-
|
|
26790
|
-
|
|
26791
|
-
|
|
27049
|
+
function resolveElementList(list, root) {
|
|
27050
|
+
const set = /* @__PURE__ */ new Set();
|
|
27051
|
+
for (const item of list) {
|
|
27052
|
+
if (typeof item === "string") {
|
|
27053
|
+
try {
|
|
27054
|
+
for (const el of deepQuerySelectorAll(item, root)) set.add(el);
|
|
27055
|
+
} catch {
|
|
27056
|
+
}
|
|
27057
|
+
} else if (item) {
|
|
27058
|
+
set.add(item);
|
|
27059
|
+
}
|
|
27060
|
+
}
|
|
27061
|
+
return set;
|
|
27062
|
+
}
|
|
27063
|
+
function buildA11yTree(root = document.body, config2) {
|
|
27064
|
+
const { pruneUnnamed = true, preserveRoles = [], ...a11yConfig } = config2 ?? {};
|
|
27065
|
+
const resolved = ensureResolvedA11yConfig(a11yConfig);
|
|
27066
|
+
const shapeOpts = { pruneUnnamed, preserveRoles };
|
|
26792
27067
|
const refCounter = { value: 0 };
|
|
26793
27068
|
const refMap = /* @__PURE__ */ new Map();
|
|
26794
|
-
const blacklistSet =
|
|
26795
|
-
const whitelistSet =
|
|
27069
|
+
const blacklistSet = resolveElementList(resolved.blacklist, root);
|
|
27070
|
+
const whitelistSet = resolveElementList(resolved.whitelist, root);
|
|
26796
27071
|
const lines = [];
|
|
26797
|
-
|
|
27072
|
+
const highlightContainer = document.getElementById(HIGHLIGHT_CONTAINER_ID);
|
|
27073
|
+
if (highlightContainer) blacklistSet.add(highlightContainer);
|
|
27074
|
+
const hoverPointerSet = collectHoverPointerElements(root);
|
|
26798
27075
|
for (const child of getComposedChildren(root)) {
|
|
26799
|
-
const vnode = buildVNode(
|
|
26800
|
-
child,
|
|
26801
|
-
refCounter,
|
|
26802
|
-
refMap,
|
|
26803
|
-
blacklistSet,
|
|
26804
|
-
whitelistSet,
|
|
26805
|
-
opts.exposedAttributes,
|
|
26806
|
-
opts.errorSelectors,
|
|
26807
|
-
opts.warningSelectors
|
|
26808
|
-
);
|
|
27076
|
+
const vnode = buildVNode(child, refCounter, refMap, blacklistSet, whitelistSet, resolved, hoverPointerSet);
|
|
26809
27077
|
if (vnode) {
|
|
26810
|
-
lines.push(...serializeVNode(vnode, 0,
|
|
27078
|
+
lines.push(...serializeVNode(vnode, 0, shapeOpts));
|
|
26811
27079
|
}
|
|
26812
27080
|
}
|
|
26813
27081
|
const yaml = "```yaml\n" + lines.join("\n") + "\n```";
|
|
@@ -26820,7 +27088,7 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26820
27088
|
}
|
|
26821
27089
|
|
|
26822
27090
|
// ../next-sdk/page-tools/a11y/search.ts
|
|
26823
|
-
function searchA11yTree(query, root = document.body,
|
|
27091
|
+
function searchA11yTree(query, root = document.body, options) {
|
|
26824
27092
|
const {
|
|
26825
27093
|
contextLines = 2,
|
|
26826
27094
|
caseInsensitive = true,
|
|
@@ -26829,7 +27097,7 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
26829
27097
|
} = options ?? {};
|
|
26830
27098
|
const safeContextLines = Math.max(0, contextLines);
|
|
26831
27099
|
const safeMaxMatches = Math.max(1, maxMatches);
|
|
26832
|
-
const { lines, refMap, yaml } = buildA11yTree(root,
|
|
27100
|
+
const { lines, refMap, yaml } = buildA11yTree(root, treeOptions);
|
|
26833
27101
|
const needle = caseInsensitive ? query.toLowerCase() : query;
|
|
26834
27102
|
const totalLines = lines.length;
|
|
26835
27103
|
const isRefQuery = /^#\d+$/.test(query);
|
|
@@ -27619,36 +27887,20 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27619
27887
|
z-index: 10000;
|
|
27620
27888
|
}
|
|
27621
27889
|
|
|
27622
|
-
.webmcp-page-agent-
|
|
27890
|
+
.webmcp-page-agent-cursorFilling {
|
|
27623
27891
|
position: absolute;
|
|
27624
27892
|
width: 100%;
|
|
27625
27893
|
height: 100%;
|
|
27626
|
-
background:
|
|
27627
|
-
|
|
27628
|
-
|
|
27629
|
-
mask-repeat: no-repeat;
|
|
27894
|
+
background: url("data:image/svg+xml,%3Csvg%20viewBox%3D%270%200%2079.0834%2079.4553%27%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20%20width%3D%2779.083374%27%20height%3D%2779.455322%27%20fill%3D%27none%27%20%3E--%3Cdefs%3E%3Cfilter%20id%3D%27filter_0%27%20width%3D%2779.083374%27%20height%3D%2779.455322%27%20x%3D%270.000000%27%20y%3D%270.000000%27%20filterUnits%3D%27userSpaceOnUse%27%20%20color-interpolation-filters%3D%27sRGB%27%3E%3CfeFlood%20flood-opacity%3D%270%27%20result%3D%27BackgroundImageFix%27%20%2F%3E%3CfeOffset%20dx%3D%276.000000%27%20dy%3D%276.000000%27%20in%3D%27SourceAlpha%27%20%2F%3E%3CfeGaussianBlur%20stdDeviation%3D%276.66666651%27%20%2F%3E%3CfeColorMatrix%20type%3D%27matrix%27%20values%3D%270%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200%200.18%200%20%27%20%2F%3E%3CfeBlend%20result%3D%27effect_dropShadow_1%27%20in2%3D%27BackgroundImageFix%27%20mode%3D%27normal%27%20%2F%3E%3CfeBlend%20result%3D%27shape%27%20in%3D%27SourceGraphic%27%20in2%3D%27effect_dropShadow_1%27%20mode%3D%27normal%27%20%2F%3E%3C%2Ffilter%3E%3ClinearGradient%20id%3D%27paint_linear_0%27%20x1%3D%2718.4743214%27%20x2%3D%2718.4213886%27%20y1%3D%27-1.86264515e-09%27%20y2%3D%2734.9221306%27%20gradientUnits%3D%27userSpaceOnUse%27%3E%3Cstop%20stop-color%3D%27rgb%28255%2C181%2C96%29%27%20offset%3D%270%27%20stop-opacity%3D%271%27%20%2F%3E%3Cstop%20stop-color%3D%27rgb%28255%2C120%2C114%29%27%20offset%3D%270.5%27%20stop-opacity%3D%271%27%20%2F%3E%3Cstop%20stop-color%3D%27rgb%28241%2C109%2C237%29%27%20offset%3D%271%27%20stop-opacity%3D%271%27%20%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Cg%20filter%3D%27url%28%23filter_0%29%27%3E%3Cpath%20d%3D%27M20.2632%203.57771L34.6257%2032.3027C35.4444%2033.9402%2033.8152%2035.7258%2032.1097%2035.0603L19.2014%2030.0229C18.7339%2029.8404%2018.2148%2029.8404%2017.7472%2030.0229L4.83891%2035.0603C3.13343%2035.7258%201.50423%2033.9402%202.32297%2032.3027L16.6855%203.57771C17.4225%202.10361%2019.5261%202.10361%2020.2632%203.57771Z%27%20fill%3D%27url%28%23paint_linear_0%29%27%20fill-rule%3D%27evenodd%27%20transform%3D%27matrix%280.719908%2C-0.69407%2C0.69407%2C0.719908%2C2.00256%2C28.0095%29%27%20%2F%3E%3Cpath%20d%3D%27M37.2169%2032.6848C37.1578%2032.189%2037.0096%2031.7039%2036.7723%2031.2294L22.4098%202.5044C22.1973%202.07946%2021.9328%201.70554%2021.6163%201.38261C21.3524%201.11342%2021.0524%200.879671%2020.7162%200.681366C20.3925%200.490407%2020.0558%200.34434%2019.7061%200.243163C19.312%200.129145%2018.9014%200.0721366%2018.4743%200.0721366C18.0472%200.0721366%2017.6367%200.129145%2017.2426%200.243163C16.8929%200.34434%2016.5562%200.490407%2016.2324%200.681366C15.8962%200.879671%2015.5962%201.11342%2015.3323%201.38261C15.0158%201.70553%2014.7513%202.07946%2014.5388%202.5044L0.176342%2031.2294C-0.0609121%2031.7039%20-0.209128%2032.189%20-0.268305%2032.6848C-0.316251%2033.0865%20-0.305747%2033.4951%20-0.236792%2033.9108C-0.171059%2034.307%20-0.0570567%2034.6809%200.105216%2035.0326C0.292784%2035.4391%200.544845%2035.8158%200.861397%2036.1627C1.17794%2036.5097%201.53001%2036.7951%201.91761%2037.0191C2.25297%2037.2128%202.61492%2037.3606%203.00348%2037.4623C3.41106%2037.5689%203.81704%2037.6168%204.22142%2037.6058C4.72053%2037.5922%205.21719%2037.4889%205.71141%2037.2961L18.4743%2032.3154L31.2372%2037.2961C31.7315%2037.4889%2032.2281%2037.5922%2032.7272%2037.6058C33.1316%2037.6168%2033.5376%2037.5689%2033.9452%2037.4623C34.3337%2037.3606%2034.6957%2037.2128%2035.0311%2037.0191C35.4187%2036.7951%2035.7707%2036.5097%2036.0873%2036.1627C36.4038%2035.8158%2036.6558%2035.4391%2036.8434%2035.0327C37.0057%2034.681%2037.1197%2034.307%2037.1854%2033.9108C37.2544%2033.4951%2037.2649%2033.0865%2037.2169%2032.6848ZM34.6257%2032.3027L20.2632%203.57771C19.5261%202.10361%2017.4225%202.10361%2016.6855%203.57771L2.32297%2032.3027C1.50423%2033.9402%203.13343%2035.7258%204.83891%2035.0603L17.7472%2030.0229C18.2148%2029.8404%2018.7339%2029.8404%2019.2014%2030.0229L32.1097%2035.0603C33.8152%2035.7258%2035.4444%2033.9402%2034.6257%2032.3027Z%27%20fill%3D%27rgb%28255%2C255%2C255%29%27%20fill-rule%3D%27evenodd%27%20transform%3D%27matrix%280.719908%2C-0.69407%2C0.69407%2C0.719908%2C2.00256%2C28.0095%29%27%20%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
|
27895
|
+
background-size: 100% 100%;
|
|
27896
|
+
background-repeat: no-repeat;
|
|
27630
27897
|
|
|
27631
27898
|
transform-origin: center;
|
|
27632
|
-
transform: rotate(-90deg) scale(0.8);
|
|
27633
27899
|
margin-left: -10px;
|
|
27634
27900
|
margin-top: -18px;
|
|
27635
27901
|
}
|
|
27636
27902
|
|
|
27637
|
-
.webmcp-page-agent-
|
|
27638
|
-
position: absolute;
|
|
27639
|
-
width: 100%;
|
|
27640
|
-
height: 100%;
|
|
27641
|
-
background: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3e%3cdefs%3e%3c/defs%3e%3cg%20xmlns='http://www.w3.org/2000/svg'%20style='filter:%20drop-shadow(light-dark(rgba(0,%200,%200,%200.4),%20rgba(237,%20237,%20237,%200.4))%203px%204px%204px);'%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='%23ffffff'%20stroke='none'%20style='fill:%20%23ffffff;'/%3e%3c/g%3e%3c/svg%3e");
|
|
27642
|
-
background-size: 100% 100%;
|
|
27643
|
-
background-repeat: no-repeat;
|
|
27644
|
-
|
|
27645
|
-
transform-origin: center;
|
|
27646
|
-
transform: rotate(-90deg) scale(0.8);
|
|
27647
|
-
margin-left: -10px;
|
|
27648
|
-
margin-top: -18px;
|
|
27649
|
-
}
|
|
27650
|
-
|
|
27651
|
-
.webmcp-page-agent-cursorRipple {
|
|
27903
|
+
.webmcp-page-agent-cursorRipple {
|
|
27652
27904
|
position: absolute;
|
|
27653
27905
|
width: 100%;
|
|
27654
27906
|
height: 100%;
|
|
@@ -27685,9 +27937,9 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27685
27937
|
.webmcp-page-agent-wrapper {
|
|
27686
27938
|
position: fixed;
|
|
27687
27939
|
inset: 0;
|
|
27688
|
-
z-index: 2147483641;
|
|
27689
27940
|
/* \u786E\u4FDD\u5728\u6240\u6709\u5143\u7D20\u4E4B\u4E0A\uFF0C\u9664\u4E86 panel */
|
|
27690
|
-
|
|
27941
|
+
z-index: 2147483641;
|
|
27942
|
+
/*cursor: wait;*/
|
|
27691
27943
|
overflow: hidden;
|
|
27692
27944
|
|
|
27693
27945
|
display: none;
|
|
@@ -27717,7 +27969,10 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27717
27969
|
try {
|
|
27718
27970
|
const motion = new Motion({
|
|
27719
27971
|
mode: isPageDark2() ? "dark" : "light",
|
|
27720
|
-
styles: { position: "absolute", inset: "0" }
|
|
27972
|
+
styles: { position: "absolute", inset: "0" },
|
|
27973
|
+
glowWidth: 80,
|
|
27974
|
+
borderWidth: 8,
|
|
27975
|
+
colors: ["rgb(121, 216, 247)", "rgb(171, 219, 110)", "rgb(252, 188, 114)", "rgb(235, 117, 231)"]
|
|
27721
27976
|
});
|
|
27722
27977
|
this.motion = motion;
|
|
27723
27978
|
this.wrapper.appendChild(motion.element);
|
|
@@ -27746,7 +28001,7 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27746
28001
|
this.wrapper.style.pointerEvents = "none";
|
|
27747
28002
|
};
|
|
27748
28003
|
const disablePassThroughListener = () => {
|
|
27749
|
-
this.wrapper.style.pointerEvents = "
|
|
28004
|
+
this.wrapper.style.pointerEvents = "none";
|
|
27750
28005
|
};
|
|
27751
28006
|
window.addEventListener("PageAgent::MovePointerTo", movePointerToListener);
|
|
27752
28007
|
window.addEventListener("PageAgent::ClickPointer", clickPointerListener);
|
|
@@ -27773,9 +28028,6 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27773
28028
|
const fillingLayer = document.createElement("div");
|
|
27774
28029
|
fillingLayer.className = "webmcp-page-agent-cursorFilling";
|
|
27775
28030
|
this.#cursor.appendChild(fillingLayer);
|
|
27776
|
-
const borderLayer = document.createElement("div");
|
|
27777
|
-
borderLayer.className = "webmcp-page-agent-cursorBorder";
|
|
27778
|
-
this.#cursor.appendChild(borderLayer);
|
|
27779
28031
|
this.wrapper.appendChild(this.#cursor);
|
|
27780
28032
|
}
|
|
27781
28033
|
#moveCursorToTarget() {
|
|
@@ -27842,62 +28094,38 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27842
28094
|
this.wrapper.remove();
|
|
27843
28095
|
this.dispatchEvent(new Event("dispose"));
|
|
27844
28096
|
}
|
|
28097
|
+
// 根据目标元素大小,在 wrapper 添加绝对定位边框:2px 宽、与目标间距 2px,对角渐变 (0,0 → 1,1)
|
|
28098
|
+
borderElement(targetElement) {
|
|
28099
|
+
if (!targetElement) return;
|
|
28100
|
+
this.wrapper.querySelector(".webmcp-page-agent-border")?.remove();
|
|
28101
|
+
const rect = targetElement.getBoundingClientRect();
|
|
28102
|
+
const gap = 2;
|
|
28103
|
+
const borderWidth = 2;
|
|
28104
|
+
const offset = gap + borderWidth;
|
|
28105
|
+
const el = document.createElement("div");
|
|
28106
|
+
el.className = "webmcp-page-agent-border";
|
|
28107
|
+
el.style.position = "absolute";
|
|
28108
|
+
el.style.left = `${rect.left - offset}px`;
|
|
28109
|
+
el.style.top = `${rect.top - offset}px`;
|
|
28110
|
+
el.style.width = `${rect.width + offset * 2}px`;
|
|
28111
|
+
el.style.height = `${rect.height + offset * 2}px`;
|
|
28112
|
+
el.style.boxSizing = "border-box";
|
|
28113
|
+
el.style.pointerEvents = "none";
|
|
28114
|
+
el.style.zIndex = "10000";
|
|
28115
|
+
el.style.border = `${borderWidth}px solid transparent`;
|
|
28116
|
+
el.style.borderImageSource = "linear-gradient(to bottom right, #79D8F7, #ABDB6E, #FCBC72, #FA8682, #EB75E7)";
|
|
28117
|
+
el.style.borderImageSlice = "1";
|
|
28118
|
+
el.style.borderImageWidth = `${borderWidth}px`;
|
|
28119
|
+
this.wrapper.appendChild(el);
|
|
28120
|
+
}
|
|
28121
|
+
removeBorderElement() {
|
|
28122
|
+
this.wrapper.querySelector(".webmcp-page-agent-border")?.remove();
|
|
28123
|
+
}
|
|
27845
28124
|
};
|
|
27846
28125
|
|
|
27847
|
-
// ../next-sdk/page-tools/constants.ts
|
|
27848
|
-
var DEFAULT_ERROR_SELECTORS2 = [
|
|
27849
|
-
// W3C ARIA 标准(最可靠,框架无关)
|
|
27850
|
-
'[role="alert"]',
|
|
27851
|
-
'[aria-invalid="true"]',
|
|
27852
|
-
// Tiny3 / Lego(华为云)
|
|
27853
|
-
".ti3-unifyvalid-error",
|
|
27854
|
-
".ti3-error",
|
|
27855
|
-
".ti-error",
|
|
27856
|
-
".lego-text-error",
|
|
27857
|
-
".lego-error",
|
|
27858
|
-
// Element UI / Element Plus
|
|
27859
|
-
".el-form-item__error",
|
|
27860
|
-
// Ant Design
|
|
27861
|
-
".ant-form-item-explain-error",
|
|
27862
|
-
// Bootstrap
|
|
27863
|
-
".is-invalid",
|
|
27864
|
-
".invalid-feedback",
|
|
27865
|
-
// Angular
|
|
27866
|
-
".ng-invalid",
|
|
27867
|
-
// 通用命名约定
|
|
27868
|
-
".error-msg",
|
|
27869
|
-
".error-message",
|
|
27870
|
-
".error-text",
|
|
27871
|
-
".field-error",
|
|
27872
|
-
".form-error",
|
|
27873
|
-
".is-error",
|
|
27874
|
-
".has-error",
|
|
27875
|
-
".validate-error",
|
|
27876
|
-
".valid-error"
|
|
27877
|
-
];
|
|
27878
|
-
var DEFAULT_DIALOG_SELECTORS = [
|
|
27879
|
-
// W3C ARIA 标准
|
|
27880
|
-
'[role="dialog"]',
|
|
27881
|
-
'[role="alertdialog"]',
|
|
27882
|
-
// Tiny3 / Lego(华为云)
|
|
27883
|
-
'[class*="ti3-modal"]',
|
|
27884
|
-
'[class*="ti3-message-box"]',
|
|
27885
|
-
// Element UI / Element Plus
|
|
27886
|
-
'[class*="el-dialog"]',
|
|
27887
|
-
'[class*="el-message-box"]',
|
|
27888
|
-
// Ant Design
|
|
27889
|
-
'[class*="ant-modal"]',
|
|
27890
|
-
// Bootstrap
|
|
27891
|
-
'[class*="modal-content"]',
|
|
27892
|
-
// Vuetify
|
|
27893
|
-
'[class*="v-dialog"]',
|
|
27894
|
-
// Naive UI
|
|
27895
|
-
'[class*="n-modal"]'
|
|
27896
|
-
];
|
|
27897
|
-
|
|
27898
28126
|
// ../next-sdk/page-tools/schema.ts
|
|
27899
28127
|
var inputSchema = external_exports.object({
|
|
27900
|
-
action: external_exports.enum(["browserState", "click", "fill", "select", "scroll", "executeJavascript", "searchTree"]).describe(`\u6267\u884C\u7684\u52A8\u4F5C\u540D\u79F0, \u6BCF\u4E00\u6B21\u6267\u884C 'click', 'fill', 'select'\u52A8\u4F5C\u4E4B\u524D\uFF0C**\u5FC5\u987B**\u8981\u5148\u8C03\u7528 'browserState' \u53BB\u83B7\u53D6\u9875\u9762\u7684\u6700\u65B0\u72B6\u6001\u3002
|
|
28128
|
+
action: external_exports.enum(["browserState", "click", "fill", "select", "scroll", "executeJavascript", "searchTree", "hover"]).describe(`\u6267\u884C\u7684\u52A8\u4F5C\u540D\u79F0, \u6BCF\u4E00\u6B21\u6267\u884C 'click', 'fill', 'select', 'hover'\u52A8\u4F5C\u4E4B\u524D\uFF0C**\u5FC5\u987B**\u8981\u5148\u8C03\u7528 'browserState' \u53BB\u83B7\u53D6\u9875\u9762\u7684\u6700\u65B0\u72B6\u6001\u3002
|
|
27901
28129
|
browserState: '\u67E5\u8BE2\u6574\u4E2A\u9875\u9762\u7684\u6D4F\u89C8\u5668\u72B6\u6001;\u8FD4\u56DE\u9875\u9762\u7684\u6807\u9898\u3001URL\u3001YAML\u683C\u5F0F\u7684\u8BED\u4E49\u5316\u9875\u9762\u6811',
|
|
27902
28130
|
click: '\u6839\u636E\u5143\u7D20\u7D22\u5F15\u70B9\u51FB;',
|
|
27903
28131
|
fill: '\u6839\u636E\u5143\u7D20\u7D22\u5F15\u586B\u5199\u6587\u672C;';
|
|
@@ -27905,8 +28133,9 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27905
28133
|
scroll: '\u6EDA\u52A8\u9875\u9762\u7684\u52A8\u4F5C\uFF0C\u53EF\u4EE5\u6307\u5B9A\u6C34\u5E73\u6EDA\u52A8\u8FD8\u662F\u4E0A\u4E0B\u6EDA\u52A8; \u4E0D\u5E26\u5143\u7D20\u7D22\u5F15\u65F6\uFF1A\u6EDA\u52A8\u6574\u4E2A\u6587\u6863\u3002\u5E26\u5143\u7D20\u7D22\u5F15\u65F6\uFF1A\u6EDA\u52A8\u8BE5\u7D22\u5F15\u5904\u7684\u5BB9\u5668\uFF08\u6216\u5176\u6700\u8FD1\u7684\u53EF\u6EDA\u52A8\u7956\u5148\u5143\u7D20\uFF09'
|
|
27906
28134
|
executeJavascript: '\u6267\u884Cjavascript\u4EE3\u7801'
|
|
27907
28135
|
searchTree: '\u6309\u5173\u952E\u8BCD\u641C\u7D22\u65E0\u969C\u788D\u6811\uFF0C\u8FD4\u56DE\u5E26\u884C\u53F7\u7684\u5339\u914D\u8282\u70B9\u53CA\u4E0A\u4E0B\u6587\uFF0C\u65E0\u9700\u83B7\u53D6\u5168\u91CF\u6811\u3002\u9002\u5408\u5FEB\u901F\u5B9A\u4F4D\u7279\u5B9A\u5143\u7D20\uFF08\u5982\u6240\u6709\u6309\u94AE\u3001\u7279\u5B9A\u540D\u79F0\u7684\u94FE\u63A5\u7B49\uFF09\uFF0C\u663E\u8457\u51CF\u5C11\u4E0A\u4E0B\u6587\u6D88\u8017\u3002\u5FC5\u987B\u63D0\u4F9B query \u53C2\u6570\u3002'
|
|
28136
|
+
hover: '\u6839\u636E\u5143\u7D20\u7D22\u5F15\u60AC\u6D6E\uFF08hover\uFF09\u76EE\u6807\u5143\u7D20; \u89E6\u53D1 mouseover/mouseenter \u7B49\u4E8B\u4EF6\uFF0C\u7528\u4E8E\u663E\u793A tooltip\u3001\u5C55\u5F00\u60AC\u6D6E\u83DC\u5355\u7B49\u4EA4\u4E92; \u64CD\u4F5C\u540E\u81EA\u52A8\u8FD4\u56DE\u6700\u65B0\u9875\u9762\u72B6\u6001\u3002'
|
|
27908
28137
|
`),
|
|
27909
|
-
index: external_exports.number().min(0).optional().describe("\u6267\u884C\u52A8\u4F5C of the element index, \u52A8\u4F5C\u4E3A click,fill,select\u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B\u5143\u7D20\u7D22\u5F15"),
|
|
28138
|
+
index: external_exports.number().min(0).optional().describe("\u6267\u884C\u52A8\u4F5C of the element index, \u52A8\u4F5C\u4E3A click,fill,select,hover\u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B\u5143\u7D20\u7D22\u5F15"),
|
|
27910
28139
|
text: external_exports.string().optional().describe("\u6267\u884C\u52A8\u4F5C\u7684\u6587\u672C\u5185\u5BB9, \u52A8\u4F5C\u4E3A fill,select \u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9B\u6587\u672C\u5185\u5BB9"),
|
|
27911
28140
|
down: external_exports.boolean().optional().describe("\u6267\u884C\u4E0A\u4E0B\u6EDA\u52A8\u65F6\uFF0C\u5FC5\u987B\u63D0\u4F9Bdown\u53C2\u6570"),
|
|
27912
28141
|
right: external_exports.boolean().optional().describe("\u6267\u884C\u6C34\u5E73\u6EDA\u52A8\u65B9\u5411, \u5FC5\u987B\u63D0\u4F9Bright\u53C2\u6570"),
|
|
@@ -27923,118 +28152,126 @@ ${pi.pixels_above > 4 && viewportExpansion !== -1 ? `... ${pi.pixels_above} pixe
|
|
|
27923
28152
|
)
|
|
27924
28153
|
});
|
|
27925
28154
|
|
|
27926
|
-
// ../next-sdk/page-tools/
|
|
27927
|
-
|
|
27928
|
-
|
|
27929
|
-
|
|
27930
|
-
|
|
27931
|
-
|
|
27932
|
-
|
|
27933
|
-
|
|
27934
|
-
|
|
27935
|
-
|
|
27936
|
-
|
|
27937
|
-
|
|
27938
|
-
|
|
27939
|
-
|
|
27940
|
-
|
|
27941
|
-
|
|
28155
|
+
// ../next-sdk/page-tools/page-agent-tool-event.ts
|
|
28156
|
+
var PAGE_AGENT_TOOL_CALL_EVENT = "page-agent-tool-call";
|
|
28157
|
+
var PAGE_AGENT_TOOL_RESULT_EVENT = "page-agent-tool-result";
|
|
28158
|
+
var PAGE_AGENT_CHAT_END_EVENT = "page-agent-chat-end";
|
|
28159
|
+
var PAGE_AGENT_USER_DO_ACTION_EVENT = "page-agent-user-do-action";
|
|
28160
|
+
function isPageAgentToolErrorResult(result2) {
|
|
28161
|
+
return typeof result2 === "object" && result2 !== null && "isError" in result2 && result2.isError === true && "error" in result2 && typeof result2.error === "string";
|
|
28162
|
+
}
|
|
28163
|
+
function dispatchPageAgentToolResult(detail) {
|
|
28164
|
+
window.dispatchEvent(new CustomEvent(PAGE_AGENT_TOOL_RESULT_EVENT, { detail }));
|
|
28165
|
+
}
|
|
28166
|
+
function setupPageAgentToolEventBridge(executePageAgentTool, pageController, actionContext) {
|
|
28167
|
+
window.__nextSdkPageAgentToolEventCleanup?.();
|
|
28168
|
+
const handleToolCall = async (event) => {
|
|
28169
|
+
const detail = event.detail;
|
|
28170
|
+
const requestId = detail?.requestId;
|
|
28171
|
+
if (!requestId) {
|
|
28172
|
+
dispatchPageAgentToolResult({
|
|
28173
|
+
requestId: "",
|
|
28174
|
+
data: {
|
|
28175
|
+
success: false,
|
|
28176
|
+
error: "\u7F3A\u5C11 requestId"
|
|
28177
|
+
}
|
|
28178
|
+
});
|
|
28179
|
+
return;
|
|
27942
28180
|
}
|
|
27943
|
-
currentNode = walker.nextNode();
|
|
27944
|
-
}
|
|
27945
|
-
return elements;
|
|
27946
|
-
}
|
|
27947
|
-
function waitForDomSettled(timeout = 600, settleTime = 150) {
|
|
27948
|
-
return new Promise((resolve) => {
|
|
27949
|
-
let settled = false;
|
|
27950
|
-
let settleTimer;
|
|
27951
|
-
const finish = () => {
|
|
27952
|
-
if (settled) return;
|
|
27953
|
-
settled = true;
|
|
27954
|
-
observer.disconnect();
|
|
27955
|
-
if (settleTimer) clearTimeout(settleTimer);
|
|
27956
|
-
resolve();
|
|
27957
|
-
};
|
|
27958
|
-
const observer = new MutationObserver(() => {
|
|
27959
|
-
if (settleTimer) clearTimeout(settleTimer);
|
|
27960
|
-
settleTimer = setTimeout(finish, settleTime);
|
|
27961
|
-
});
|
|
27962
|
-
settleTimer = setTimeout(finish, settleTime);
|
|
27963
|
-
setTimeout(finish, timeout);
|
|
27964
|
-
observer.observe(document.body, {
|
|
27965
|
-
childList: true,
|
|
27966
|
-
subtree: true,
|
|
27967
|
-
attributes: true,
|
|
27968
|
-
attributeFilter: ["class", "style", "hidden"]
|
|
27969
|
-
});
|
|
27970
|
-
});
|
|
27971
|
-
}
|
|
27972
|
-
function detectPageDialog() {
|
|
27973
|
-
const seen = /* @__PURE__ */ new Set();
|
|
27974
|
-
const dialogs = [];
|
|
27975
|
-
const selectors = window.__webmcpcli_dialogSelectors ?? DEFAULT_DIALOG_SELECTORS;
|
|
27976
|
-
for (const selector of selectors) {
|
|
27977
28181
|
try {
|
|
27978
|
-
|
|
27979
|
-
|
|
27980
|
-
|
|
27981
|
-
|
|
27982
|
-
|
|
27983
|
-
|
|
27984
|
-
|
|
27985
|
-
|
|
27986
|
-
|
|
27987
|
-
|
|
27988
|
-
|
|
27989
|
-
|
|
27990
|
-
|
|
27991
|
-
|
|
27992
|
-
|
|
27993
|
-
|
|
27994
|
-
|
|
27995
|
-
|
|
27996
|
-
const btns = el.querySelectorAll('button, [role="button"], a');
|
|
27997
|
-
const btnTexts = Array.from(btns).map((b) => (b.textContent || "").trim()).filter((t) => t.length > 0 && t.length < 20).slice(0, 5);
|
|
27998
|
-
const btnInfo = btnTexts.length ? ` [\u53EF\u64CD\u4F5C\u6309\u94AE: ${btnTexts.join(" / ")}]` : "";
|
|
27999
|
-
dialogs.push(`${text.substring(0, 300)}${btnInfo}`);
|
|
28182
|
+
const data = inputSchema.parse(detail.data);
|
|
28183
|
+
const result2 = await executePageAgentTool(data);
|
|
28184
|
+
if (isPageAgentToolErrorResult(result2)) {
|
|
28185
|
+
dispatchPageAgentToolResult({
|
|
28186
|
+
requestId,
|
|
28187
|
+
data: {
|
|
28188
|
+
success: false,
|
|
28189
|
+
error: result2.error,
|
|
28190
|
+
result: result2
|
|
28191
|
+
}
|
|
28192
|
+
});
|
|
28193
|
+
return;
|
|
28194
|
+
}
|
|
28195
|
+
dispatchPageAgentToolResult({
|
|
28196
|
+
requestId,
|
|
28197
|
+
data: {
|
|
28198
|
+
success: true,
|
|
28199
|
+
result: result2
|
|
28000
28200
|
}
|
|
28201
|
+
});
|
|
28202
|
+
} catch (error2) {
|
|
28203
|
+
dispatchPageAgentToolResult({
|
|
28204
|
+
requestId,
|
|
28205
|
+
data: {
|
|
28206
|
+
success: false,
|
|
28207
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
28208
|
+
}
|
|
28209
|
+
});
|
|
28210
|
+
}
|
|
28211
|
+
};
|
|
28212
|
+
const handleChatEnd = async () => {
|
|
28213
|
+
try {
|
|
28214
|
+
await pageController.hideMask();
|
|
28215
|
+
} catch (error2) {
|
|
28216
|
+
}
|
|
28217
|
+
};
|
|
28218
|
+
const handleUserDoAction = async (ev) => {
|
|
28219
|
+
if (ev.isTrusted && pageController.mask.shown) {
|
|
28220
|
+
const target = ev.target;
|
|
28221
|
+
const refMap = actionContext.getRefMap();
|
|
28222
|
+
const targetParent = Array.from(refMap.values()).find((el) => el.contains(target));
|
|
28223
|
+
if (targetParent) {
|
|
28224
|
+
const detail = {
|
|
28225
|
+
action: "click",
|
|
28226
|
+
dom: targetParent
|
|
28227
|
+
};
|
|
28228
|
+
window.dispatchEvent(new CustomEvent(PAGE_AGENT_USER_DO_ACTION_EVENT, { detail }));
|
|
28001
28229
|
}
|
|
28002
|
-
} catch {
|
|
28003
28230
|
}
|
|
28231
|
+
};
|
|
28232
|
+
window.addEventListener(PAGE_AGENT_TOOL_CALL_EVENT, handleToolCall);
|
|
28233
|
+
window.addEventListener(PAGE_AGENT_CHAT_END_EVENT, handleChatEnd);
|
|
28234
|
+
window.addEventListener("click", handleUserDoAction, true);
|
|
28235
|
+
window.__nextSdkPageAgentToolEventCleanup = () => {
|
|
28236
|
+
window.removeEventListener(PAGE_AGENT_TOOL_CALL_EVENT, handleToolCall);
|
|
28237
|
+
window.removeEventListener(PAGE_AGENT_CHAT_END_EVENT, handleChatEnd);
|
|
28238
|
+
window.removeEventListener("click", handleUserDoAction, true);
|
|
28239
|
+
window.__nextSdkPageAgentToolEventCleanup = void 0;
|
|
28240
|
+
};
|
|
28241
|
+
}
|
|
28242
|
+
|
|
28243
|
+
// ../next-sdk/page-tools/context.ts
|
|
28244
|
+
function withStateFields(stateText, extra) {
|
|
28245
|
+
try {
|
|
28246
|
+
const state = JSON.parse(stateText);
|
|
28247
|
+
return JSON.stringify({ ...state, ...extra });
|
|
28248
|
+
} catch {
|
|
28249
|
+
return JSON.stringify({ ...extra, raw: stateText });
|
|
28004
28250
|
}
|
|
28005
|
-
if (dialogs.length === 0) return "";
|
|
28006
|
-
return `
|
|
28007
|
-
[\u9875\u9762\u5F39\u7A97\u68C0\u6D4B] \u68C0\u6D4B\u5230 ${dialogs.length} \u4E2A\u6A21\u6001\u5F39\u7A97\uFF0C\u8BF7\u4F18\u5148\u5904\u7406:
|
|
28008
|
-
${dialogs.map((d, i) => `${i + 1}. ${d}`).join("\n")}
|
|
28009
|
-
`;
|
|
28010
28251
|
}
|
|
28011
|
-
function
|
|
28012
|
-
|
|
28013
|
-
|
|
28014
|
-
|
|
28015
|
-
|
|
28016
|
-
|
|
28017
|
-
|
|
28018
|
-
|
|
28019
|
-
|
|
28020
|
-
|
|
28021
|
-
|
|
28022
|
-
|
|
28023
|
-
|
|
28024
|
-
|
|
28025
|
-
|
|
28026
|
-
|
|
28027
|
-
|
|
28252
|
+
async function createActionErrorResult(message, buildBrowserStateResponse) {
|
|
28253
|
+
try {
|
|
28254
|
+
const browserState = await buildBrowserStateResponse("full");
|
|
28255
|
+
return {
|
|
28256
|
+
isError: true,
|
|
28257
|
+
error: message,
|
|
28258
|
+
content: [{ type: "text", text: withStateFields(browserState.content[0].text, { error: message }) }]
|
|
28259
|
+
};
|
|
28260
|
+
} catch (error2) {
|
|
28261
|
+
return {
|
|
28262
|
+
isError: true,
|
|
28263
|
+
error: message,
|
|
28264
|
+
content: [
|
|
28265
|
+
{
|
|
28266
|
+
type: "text",
|
|
28267
|
+
text: JSON.stringify({
|
|
28268
|
+
error: message,
|
|
28269
|
+
stateError: error2 instanceof Error ? error2.message : String(error2)
|
|
28270
|
+
})
|
|
28028
28271
|
}
|
|
28029
|
-
|
|
28030
|
-
}
|
|
28031
|
-
}
|
|
28272
|
+
]
|
|
28273
|
+
};
|
|
28032
28274
|
}
|
|
28033
|
-
if (errors.length === 0) return "";
|
|
28034
|
-
return `
|
|
28035
|
-
[\u6821\u9A8C\u63D0\u793A] \u68C0\u6D4B\u5230 ${errors.length} \u4E2A\u8868\u5355\u6821\u9A8C\u9519\u8BEF\uFF0C\u8BF7\u5148\u4FEE\u590D\u540E\u518D\u7EE7\u7EED:
|
|
28036
|
-
${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
28037
|
-
`;
|
|
28038
28275
|
}
|
|
28039
28276
|
|
|
28040
28277
|
// ../next-sdk/page-tools/handlers/browserState.ts
|
|
@@ -28052,9 +28289,13 @@ ${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
|
28052
28289
|
// ../next-sdk/page-tools/handlers/click.ts
|
|
28053
28290
|
async function handleClick(args, ctx) {
|
|
28054
28291
|
const mode = args.responseMode ?? "diff";
|
|
28055
|
-
if (args.index === void 0) return ctx.
|
|
28292
|
+
if (args.index === void 0) return ctx.actionError("\u70B9\u51FB\u7ED3\u679C: \u7F3A\u5C11\u5143\u7D20\u7D22\u5F15");
|
|
28056
28293
|
const el = ctx.getRefMap().get(args.index);
|
|
28057
|
-
if (!el)
|
|
28294
|
+
if (!el) {
|
|
28295
|
+
return ctx.actionError(
|
|
28296
|
+
`\u70B9\u51FB\u5931\u8D25: ref \u7D22\u5F15 ${args.index} \u5DF2\u5931\u6548\uFF08\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\uFF09\uFF0C\u5DF2\u81EA\u52A8\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u72B6\u6001\uFF0C\u8BF7\u4F7F\u7528\u65B0\u7684 ref \u7D22\u5F15\u91CD\u8BD5\u3002`
|
|
28297
|
+
);
|
|
28298
|
+
}
|
|
28058
28299
|
let targetEl = el;
|
|
28059
28300
|
if (el.shadowRoot && !(el instanceof HTMLButtonElement) && !(el instanceof HTMLAnchorElement)) {
|
|
28060
28301
|
const innerClickable = el.shadowRoot.querySelector(
|
|
@@ -28072,9 +28313,14 @@ ${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
|
28072
28313
|
// ../next-sdk/page-tools/handlers/fill.ts
|
|
28073
28314
|
async function handleFill(args, ctx) {
|
|
28074
28315
|
const mode = args.responseMode ?? "diff";
|
|
28075
|
-
if (args.index === void 0 || typeof args.text !== "string")
|
|
28316
|
+
if (args.index === void 0 || typeof args.text !== "string")
|
|
28317
|
+
return ctx.actionError("\u586B\u5199\u7ED3\u679C: \u7F3A\u5C11\u5143\u7D20\u7D22\u5F15\u6216\u6587\u672C\u5185\u5BB9");
|
|
28076
28318
|
const el = ctx.getRefMap().get(args.index);
|
|
28077
|
-
if (!el)
|
|
28319
|
+
if (!el) {
|
|
28320
|
+
return ctx.actionError(
|
|
28321
|
+
`\u586B\u5199\u5931\u8D25: ref \u7D22\u5F15 ${args.index} \u5DF2\u5931\u6548\uFF08\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\uFF09\uFF0C\u5DF2\u81EA\u52A8\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u72B6\u6001\uFF0C\u8BF7\u4F7F\u7528\u65B0\u7684 ref \u7D22\u5F15\u91CD\u8BD5\u3002`
|
|
28322
|
+
);
|
|
28323
|
+
}
|
|
28078
28324
|
let targetEl = el;
|
|
28079
28325
|
if (!(targetEl instanceof HTMLInputElement) && !(targetEl instanceof HTMLTextAreaElement)) {
|
|
28080
28326
|
const innerInput = el.querySelector("input, textarea") ?? el.shadowRoot?.querySelector("input, textarea");
|
|
@@ -28105,7 +28351,7 @@ ${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
|
28105
28351
|
}
|
|
28106
28352
|
}
|
|
28107
28353
|
if (!fillSuccess) {
|
|
28108
|
-
return ctx.
|
|
28354
|
+
return ctx.actionError(`\u586B\u5199\u7ED3\u679C: \u65E0\u6CD5\u586B\u5199\u5143\u7D20 ${args.index}\uFF0C\u5143\u7D20\u4E0D\u662F input\u3001textarea \u6216 contenteditable`);
|
|
28109
28355
|
}
|
|
28110
28356
|
if (isInShadowDom(targetEl)) {
|
|
28111
28357
|
dispatchComposedEvents(targetEl, "input", "change");
|
|
@@ -28118,9 +28364,14 @@ ${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
|
28118
28364
|
// ../next-sdk/page-tools/handlers/select.ts
|
|
28119
28365
|
async function handleSelect(args, ctx) {
|
|
28120
28366
|
const mode = args.responseMode ?? "diff";
|
|
28121
|
-
if (args.index === void 0 || typeof args.text !== "string")
|
|
28367
|
+
if (args.index === void 0 || typeof args.text !== "string")
|
|
28368
|
+
return ctx.actionError("\u9009\u62E9\u7ED3\u679C: \u7F3A\u5C11\u5143\u7D20\u7D22\u5F15\u6216\u6587\u672C\u5185\u5BB9");
|
|
28122
28369
|
let el = ctx.getRefMap().get(args.index);
|
|
28123
|
-
if (!el)
|
|
28370
|
+
if (!el) {
|
|
28371
|
+
return ctx.actionError(
|
|
28372
|
+
`\u9009\u62E9\u5931\u8D25: ref \u7D22\u5F15 ${args.index} \u5DF2\u5931\u6548\uFF08\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\uFF09\uFF0C\u5DF2\u81EA\u52A8\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u72B6\u6001\uFF0C\u8BF7\u4F7F\u7528\u65B0\u7684 ref \u7D22\u5F15\u91CD\u8BD5\u3002`
|
|
28373
|
+
);
|
|
28374
|
+
}
|
|
28124
28375
|
let targetSelect = null;
|
|
28125
28376
|
if (el instanceof HTMLSelectElement) {
|
|
28126
28377
|
targetSelect = el;
|
|
@@ -28131,7 +28382,7 @@ ${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
|
28131
28382
|
}
|
|
28132
28383
|
}
|
|
28133
28384
|
if (!targetSelect) {
|
|
28134
|
-
return ctx.
|
|
28385
|
+
return ctx.actionError(`\u9009\u62E9\u7ED3\u679C: \u65E0\u6CD5\u9009\u62E9\u5143\u7D20 ${args.index}\uFF0C\u672A\u627E\u5230\u5BF9\u5E94\u7684 <select> \u5143\u7D20`);
|
|
28135
28386
|
}
|
|
28136
28387
|
await selectOptionElement(targetSelect, args.text);
|
|
28137
28388
|
if (isInShadowDom(targetSelect)) {
|
|
@@ -28249,9 +28500,7 @@ ${errors.map((e, i) => `${i + 1}. ${e}`).join("\n")}
|
|
|
28249
28500
|
const scrollResult = `[\u6EDA\u52A8\u7ED3\u679C] ${scrollMsg}
|
|
28250
28501
|
${posInfo}`;
|
|
28251
28502
|
const stateResult = await ctx.buildBrowserStateResponse(mode);
|
|
28252
|
-
stateResult.content[0].text =
|
|
28253
|
-
|
|
28254
|
-
${stateResult.content[0].text}`;
|
|
28503
|
+
stateResult.content[0].text = withStateFields(stateResult.content[0].text, { scrollResult });
|
|
28255
28504
|
return stateResult;
|
|
28256
28505
|
}
|
|
28257
28506
|
|
|
@@ -28274,76 +28523,114 @@ ${stateResult.content[0].text}`;
|
|
|
28274
28523
|
// ../next-sdk/page-tools/handlers/searchTree.ts
|
|
28275
28524
|
async function handleSearchTree(args, ctx) {
|
|
28276
28525
|
if (!args.query) return ctx.errContent("\u641C\u7D22\u5931\u8D25: \u7F3A\u5C11 query \u53C2\u6570");
|
|
28277
|
-
const
|
|
28278
|
-
|
|
28279
|
-
const exposedAttributes = window.__webmcpcli_exposedAttributes ?? [];
|
|
28280
|
-
const result2 = searchA11yTree(args.query, document.body, blacklist, whitelist, {
|
|
28526
|
+
const result2 = searchA11yTree(args.query, document.body, {
|
|
28527
|
+
...getPageAgentToolConfig().a11yConfig,
|
|
28281
28528
|
contextLines: args.contextLines,
|
|
28282
|
-
maxMatches: args.maxMatches
|
|
28283
|
-
exposedAttributes,
|
|
28284
|
-
errorSelectors: (window.__webmcpcli_errorSelectors ?? DEFAULT_ERROR_SELECTORS2).join(", ")
|
|
28529
|
+
maxMatches: args.maxMatches
|
|
28285
28530
|
});
|
|
28286
28531
|
ctx.setRefMap(result2.refMap);
|
|
28287
28532
|
ctx.stateCache.update(window.location.href, result2.yaml);
|
|
28288
28533
|
await ctx.pageController.hideMask();
|
|
28289
|
-
const
|
|
28534
|
+
const dialogs = detectPageDialog();
|
|
28290
28535
|
const validationErrors = detectValidationErrors();
|
|
28291
|
-
|
|
28536
|
+
if (dialogs.length === 0 && validationErrors.length === 0) {
|
|
28537
|
+
return { content: [{ type: "text", text: result2.text }] };
|
|
28538
|
+
}
|
|
28539
|
+
const alerts = {
|
|
28540
|
+
...dialogs.length > 0 ? { dialogs } : {},
|
|
28541
|
+
...validationErrors.length > 0 ? { validationErrors } : {}
|
|
28542
|
+
};
|
|
28292
28543
|
return {
|
|
28293
|
-
content: [{ type: "text", text:
|
|
28294
|
-
${result2.text}`
|
|
28544
|
+
content: [{ type: "text", text: `${JSON.stringify(alerts)}
|
|
28545
|
+
${result2.text}` }]
|
|
28295
28546
|
};
|
|
28296
28547
|
}
|
|
28297
28548
|
|
|
28549
|
+
// ../next-sdk/page-tools/handlers/hover.ts
|
|
28550
|
+
async function handleHover(args, ctx) {
|
|
28551
|
+
if (args.index === void 0) return ctx.errContent("\u60AC\u6D6E\u7ED3\u679C: \u7F3A\u5C11\u5143\u7D20\u7D22\u5F15");
|
|
28552
|
+
const el = ctx.getRefMap().get(args.index);
|
|
28553
|
+
if (!el) return ctx.refreshOnStaleRef("\u60AC\u6D6E", args.index);
|
|
28554
|
+
let targetEl = el;
|
|
28555
|
+
if (el.shadowRoot && !(el instanceof HTMLButtonElement) && !(el instanceof HTMLAnchorElement)) {
|
|
28556
|
+
const innerClickable = el.shadowRoot.querySelector(
|
|
28557
|
+
'button, a, [role="button"], [role="link"]'
|
|
28558
|
+
);
|
|
28559
|
+
if (innerClickable) {
|
|
28560
|
+
targetEl = innerClickable;
|
|
28561
|
+
}
|
|
28562
|
+
}
|
|
28563
|
+
const rect = targetEl.getBoundingClientRect();
|
|
28564
|
+
const cx = rect.left + rect.width / 2;
|
|
28565
|
+
const cy = rect.top + rect.height / 2;
|
|
28566
|
+
const eventSequence = [
|
|
28567
|
+
{ type: "pointerenter", bubbles: false, usePointer: true },
|
|
28568
|
+
{ type: "pointerover", bubbles: true, usePointer: true },
|
|
28569
|
+
{ type: "pointermove", bubbles: true, usePointer: true },
|
|
28570
|
+
{ type: "mouseenter", bubbles: false, usePointer: false },
|
|
28571
|
+
{ type: "mouseover", bubbles: true, usePointer: false },
|
|
28572
|
+
{ type: "mousemove", bubbles: true, usePointer: false }
|
|
28573
|
+
];
|
|
28574
|
+
for (const { type, bubbles, usePointer } of eventSequence) {
|
|
28575
|
+
const EventClass = usePointer ? PointerEvent : MouseEvent;
|
|
28576
|
+
targetEl.dispatchEvent(new EventClass(type, {
|
|
28577
|
+
bubbles,
|
|
28578
|
+
cancelable: true,
|
|
28579
|
+
view: window,
|
|
28580
|
+
clientX: cx,
|
|
28581
|
+
clientY: cy
|
|
28582
|
+
}));
|
|
28583
|
+
}
|
|
28584
|
+
await waitForDomSettled();
|
|
28585
|
+
const mode = args.responseMode ?? "diff";
|
|
28586
|
+
return ctx.buildBrowserStateResponse(mode);
|
|
28587
|
+
}
|
|
28588
|
+
|
|
28298
28589
|
// ../next-sdk/page-tools/page-agent-tool.ts
|
|
28299
28590
|
function registerPageAgentTool(options = {}) {
|
|
28300
28591
|
initializeBuiltinWebMCP();
|
|
28301
|
-
|
|
28302
|
-
options.enableHighlight = true;
|
|
28303
|
-
}
|
|
28304
|
-
window.__webmcpcli_interactiveWhitelist = window.__webmcpcli_interactiveWhitelist || [];
|
|
28305
|
-
window.__webmcpcli_interactiveBlacklist = window.__webmcpcli_interactiveBlacklist || [];
|
|
28306
|
-
window.__webmcpcli_exposedAttributes = window.__webmcpcli_exposedAttributes || options?.exposedAttributes || [];
|
|
28592
|
+
setPageAgentToolConfig(options, { mode: "replace" });
|
|
28307
28593
|
window.__webmcpcli_beforeGetBrowserState = window.__webmcpcli_beforeGetBrowserState || null;
|
|
28308
|
-
window.__webmcpcli_errorSelectors = window.__webmcpcli_errorSelectors || DEFAULT_ERROR_SELECTORS2;
|
|
28309
|
-
window.__webmcpcli_dialogSelectors = window.__webmcpcli_dialogSelectors || DEFAULT_DIALOG_SELECTORS;
|
|
28310
28594
|
const pageController = new PageController({ enableMask: false });
|
|
28595
|
+
const simulatorMask = new SimulatorMask2();
|
|
28311
28596
|
pageController.maskReady = (async () => {
|
|
28312
|
-
pageController.mask =
|
|
28597
|
+
pageController.mask = simulatorMask;
|
|
28313
28598
|
})();
|
|
28314
28599
|
const stateCache = new PageStateCache();
|
|
28315
28600
|
let currentRefMap = /* @__PURE__ */ new Map();
|
|
28316
28601
|
async function errContent(msg) {
|
|
28317
|
-
await pageController.hideMask();
|
|
28318
28602
|
return { content: [{ type: "text", text: msg }] };
|
|
28319
28603
|
}
|
|
28604
|
+
async function actionError(msg) {
|
|
28605
|
+
const result2 = await createActionErrorResult(msg, buildBrowserStateResponse);
|
|
28606
|
+
options.removeMaskAfterToolCall && await pageController.hideMask();
|
|
28607
|
+
return result2;
|
|
28608
|
+
}
|
|
28320
28609
|
async function refreshOnStaleRef(action, index) {
|
|
28321
28610
|
const refreshResult = await buildBrowserStateResponse("full");
|
|
28322
|
-
const warning = `\u26A0\uFE0F ${action}\u5931\u8D25: ref \u7D22\u5F15 ${index} \u5DF2\u5931\u6548\uFF08\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\uFF09\uFF0C\u5DF2\u81EA\u52A8\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u72B6\u6001\uFF0C\u8BF7\u4F7F\u7528\u65B0\u7684 ref \u7D22\u5F15\u91CD\u8BD5\u3002
|
|
28323
|
-
`;
|
|
28611
|
+
const warning = `\u26A0\uFE0F ${action}\u5931\u8D25: ref \u7D22\u5F15 ${index} \u5DF2\u5931\u6548\uFF08\u9875\u9762\u53EF\u80FD\u5DF2\u5237\u65B0\uFF09\uFF0C\u5DF2\u81EA\u52A8\u91CD\u65B0\u52A0\u8F7D\u9875\u9762\u72B6\u6001\uFF0C\u8BF7\u4F7F\u7528\u65B0\u7684 ref \u7D22\u5F15\u91CD\u8BD5\u3002`;
|
|
28324
28612
|
return {
|
|
28325
|
-
content: [
|
|
28613
|
+
content: [
|
|
28614
|
+
{
|
|
28615
|
+
type: "text",
|
|
28616
|
+
text: withStateFields(refreshResult.content[0].text, { warning })
|
|
28617
|
+
}
|
|
28618
|
+
]
|
|
28326
28619
|
};
|
|
28327
28620
|
}
|
|
28328
28621
|
async function buildBrowserStateResponse(responseMode = "diff") {
|
|
28329
28622
|
const url2 = window.location.href;
|
|
28330
28623
|
const title = document.title;
|
|
28331
|
-
const
|
|
28332
|
-
const whitelist = window.__webmcpcli_interactiveWhitelist ?? [];
|
|
28333
|
-
const exposedAttributes = window.__webmcpcli_exposedAttributes ?? [];
|
|
28334
|
-
const { yaml, refMap } = buildA11yTree(document.body, blacklist, whitelist, {
|
|
28335
|
-
exposedAttributes,
|
|
28336
|
-
errorSelectors: (window.__webmcpcli_errorSelectors ?? DEFAULT_ERROR_SELECTORS2).join(", ")
|
|
28337
|
-
});
|
|
28624
|
+
const { yaml, refMap } = buildA11yTree(document.body, getPageAgentToolConfig().a11yConfig);
|
|
28338
28625
|
currentRefMap = refMap;
|
|
28339
|
-
if (
|
|
28626
|
+
if (getPageAgentToolConfig().enableHighlight) {
|
|
28340
28627
|
highlight(refMap);
|
|
28341
28628
|
globalRemoveListener();
|
|
28342
28629
|
}
|
|
28343
28630
|
const diff2 = stateCache.update(url2, yaml);
|
|
28344
|
-
|
|
28345
|
-
const dialogAlert = detectPageDialog();
|
|
28631
|
+
const dialogs = detectPageDialog();
|
|
28346
28632
|
const validationErrors = detectValidationErrors();
|
|
28633
|
+
const tooltips = detectVisibleTooltips();
|
|
28347
28634
|
let displayContent = "";
|
|
28348
28635
|
if (responseMode === "full") {
|
|
28349
28636
|
displayContent = yaml;
|
|
@@ -28359,10 +28646,12 @@ ${diff2.isFullRefresh ? "\uFF08\u9996\u6B21/\u5237\u65B0\uFF0C\u65E0\u589E\u91CF
|
|
|
28359
28646
|
const stateObj = {
|
|
28360
28647
|
url: url2,
|
|
28361
28648
|
title,
|
|
28362
|
-
content: displayContent
|
|
28649
|
+
content: displayContent,
|
|
28650
|
+
...dialogs.length > 0 ? { dialogs } : {},
|
|
28651
|
+
...validationErrors.length > 0 ? { validationErrors } : {},
|
|
28652
|
+
...tooltips.length > 0 ? { tooltips } : {}
|
|
28363
28653
|
};
|
|
28364
|
-
|
|
28365
|
-
return { content: [{ type: "text", text }] };
|
|
28654
|
+
return { content: [{ type: "text", text: JSON.stringify(stateObj) }] };
|
|
28366
28655
|
}
|
|
28367
28656
|
const actionContext = {
|
|
28368
28657
|
pageController,
|
|
@@ -28373,41 +28662,287 @@ ${diff2.isFullRefresh ? "\uFF08\u9996\u6B21/\u5237\u65B0\uFF0C\u65E0\u589E\u91CF
|
|
|
28373
28662
|
},
|
|
28374
28663
|
buildBrowserStateResponse,
|
|
28375
28664
|
refreshOnStaleRef,
|
|
28376
|
-
errContent
|
|
28665
|
+
errContent,
|
|
28666
|
+
actionError
|
|
28377
28667
|
};
|
|
28378
|
-
|
|
28668
|
+
function borderTargetElement(index) {
|
|
28669
|
+
if (index === void 0) return;
|
|
28670
|
+
const el = currentRefMap.get(index);
|
|
28671
|
+
if (el) simulatorMask.borderElement(el);
|
|
28672
|
+
}
|
|
28673
|
+
async function executePageAgentTool(args) {
|
|
28674
|
+
try {
|
|
28675
|
+
let ret;
|
|
28676
|
+
switch (args.action) {
|
|
28677
|
+
case "browserState":
|
|
28678
|
+
ret = await handleBrowserState(args, actionContext);
|
|
28679
|
+
break;
|
|
28680
|
+
case "click":
|
|
28681
|
+
await pageController.showMask();
|
|
28682
|
+
borderTargetElement(args.index);
|
|
28683
|
+
ret = await handleClick(args, actionContext);
|
|
28684
|
+
options.removeMaskAfterToolCall && await pageController.hideMask();
|
|
28685
|
+
break;
|
|
28686
|
+
case "fill":
|
|
28687
|
+
await pageController.showMask();
|
|
28688
|
+
borderTargetElement(args.index);
|
|
28689
|
+
ret = await handleFill(args, actionContext);
|
|
28690
|
+
options.removeMaskAfterToolCall && await pageController.hideMask();
|
|
28691
|
+
break;
|
|
28692
|
+
case "select":
|
|
28693
|
+
await pageController.showMask();
|
|
28694
|
+
borderTargetElement(args.index);
|
|
28695
|
+
ret = await handleSelect(args, actionContext);
|
|
28696
|
+
options.removeMaskAfterToolCall && await pageController.hideMask();
|
|
28697
|
+
break;
|
|
28698
|
+
case "scroll":
|
|
28699
|
+
await pageController.showMask();
|
|
28700
|
+
ret = await handleScroll(args, actionContext);
|
|
28701
|
+
options.removeMaskAfterToolCall && await pageController.hideMask();
|
|
28702
|
+
break;
|
|
28703
|
+
case "executeJavascript":
|
|
28704
|
+
ret = await handleExecuteJavascript(args, actionContext);
|
|
28705
|
+
break;
|
|
28706
|
+
case "searchTree":
|
|
28707
|
+
ret = await handleSearchTree(args, actionContext);
|
|
28708
|
+
break;
|
|
28709
|
+
case "hover":
|
|
28710
|
+
ret = await handleHover(args, actionContext);
|
|
28711
|
+
break;
|
|
28712
|
+
default:
|
|
28713
|
+
ret = { content: [{ type: "text", text: `\u672A\u77E5\u64CD\u4F5C: ${args.action}` }] };
|
|
28714
|
+
}
|
|
28715
|
+
return ret;
|
|
28716
|
+
} catch (error2) {
|
|
28717
|
+
const actionNames = {
|
|
28718
|
+
click: "\u70B9\u51FB",
|
|
28719
|
+
fill: "\u586B\u5199",
|
|
28720
|
+
select: "\u9009\u62E9"
|
|
28721
|
+
};
|
|
28722
|
+
if (args.action in actionNames) {
|
|
28723
|
+
return actionError(
|
|
28724
|
+
`${actionNames[args.action]}\u6267\u884C\u5F02\u5E38: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
28725
|
+
);
|
|
28726
|
+
}
|
|
28727
|
+
options.removeMaskAfterToolCall && await pageController.hideMask();
|
|
28728
|
+
throw error2;
|
|
28729
|
+
} finally {
|
|
28730
|
+
simulatorMask.removeBorderElement();
|
|
28731
|
+
}
|
|
28732
|
+
}
|
|
28733
|
+
const modelContext = document.modelContext;
|
|
28734
|
+
if (!modelContext) {
|
|
28735
|
+
console.warn("[next-sdk] modelContext is not available, skipping page-agent-tool registration.");
|
|
28736
|
+
return {
|
|
28737
|
+
showMask: () => pageController.showMask(),
|
|
28738
|
+
hideMask: () => pageController.hideMask()
|
|
28739
|
+
};
|
|
28740
|
+
}
|
|
28741
|
+
try {
|
|
28742
|
+
modelContext.unregisterTool?.("page-agent-tool");
|
|
28743
|
+
} catch {
|
|
28744
|
+
}
|
|
28745
|
+
modelContext.registerTool({
|
|
28379
28746
|
name: "page-agent-tool",
|
|
28380
28747
|
description: page_agent_prompt_default,
|
|
28381
28748
|
// @ts-ignore
|
|
28382
28749
|
inputSchema: zodToJsonSchema(inputSchema),
|
|
28383
28750
|
async execute(args) {
|
|
28384
|
-
await pageController.showMask();
|
|
28385
28751
|
try {
|
|
28386
|
-
|
|
28387
|
-
case "browserState":
|
|
28388
|
-
return await handleBrowserState(args, actionContext);
|
|
28389
|
-
case "click":
|
|
28390
|
-
return await handleClick(args, actionContext);
|
|
28391
|
-
case "fill":
|
|
28392
|
-
return await handleFill(args, actionContext);
|
|
28393
|
-
case "select":
|
|
28394
|
-
return await handleSelect(args, actionContext);
|
|
28395
|
-
case "scroll":
|
|
28396
|
-
return await handleScroll(args, actionContext);
|
|
28397
|
-
case "executeJavascript":
|
|
28398
|
-
return await handleExecuteJavascript(args, actionContext);
|
|
28399
|
-
case "searchTree":
|
|
28400
|
-
return await handleSearchTree(args, actionContext);
|
|
28401
|
-
default:
|
|
28402
|
-
await pageController.hideMask();
|
|
28403
|
-
return { content: [{ type: "text", text: `\u672A\u77E5\u64CD\u4F5C: ${args.action}` }] };
|
|
28404
|
-
}
|
|
28752
|
+
return executePageAgentTool(args);
|
|
28405
28753
|
} catch (error2) {
|
|
28406
|
-
await pageController.hideMask();
|
|
28407
28754
|
return { content: [{ type: "text", text: `\u5F02\u5E38: ${String(error2)}` }] };
|
|
28408
28755
|
}
|
|
28409
28756
|
}
|
|
28410
28757
|
});
|
|
28758
|
+
setupPageAgentToolEventBridge(executePageAgentTool, pageController, actionContext);
|
|
28759
|
+
return {
|
|
28760
|
+
showMask: () => pageController.showMask(),
|
|
28761
|
+
hideMask: () => pageController.hideMask()
|
|
28762
|
+
};
|
|
28763
|
+
}
|
|
28764
|
+
|
|
28765
|
+
// ../next-sdk/page-tools/configs/console-cloud.ts
|
|
28766
|
+
var consoleCloudPageAgentToolOptions = {
|
|
28767
|
+
enableHighlight: false,
|
|
28768
|
+
a11yConfig: defineA11yConfig({
|
|
28769
|
+
roles: [
|
|
28770
|
+
// Tiny3 App Layout / Content Layout:补齐 landmark,帮助 AI 理解分区结构
|
|
28771
|
+
{ role: "navigation", selector: "ti-app-layout-left", name: "\u4FA7\u8FB9\u5BFC\u822A" },
|
|
28772
|
+
{ role: "main", selector: "ti-app-layout-main", name: "\u4E3B\u5185\u5BB9\u533A" },
|
|
28773
|
+
{
|
|
28774
|
+
role: "banner",
|
|
28775
|
+
selector: ["ti-app-layout-main-header", "tp-layout-content-header"],
|
|
28776
|
+
name: "\u9875\u9762\u5934\u90E8"
|
|
28777
|
+
},
|
|
28778
|
+
{ role: "region", selector: "ti-app-layout-main-content", name: "\u9875\u9762\u5185\u5BB9" },
|
|
28779
|
+
{ role: "region", selector: "tp-layout-content-body", name: "\u9875\u9762\u6B63\u6587" },
|
|
28780
|
+
{ role: "complementary", selector: "ti-app-layout-right", name: "\u53F3\u4FA7\u9762\u677F" },
|
|
28781
|
+
// Tiny3 Tabs:真正可聚焦/可点击的是内部 .ti3-tabs-text(tabindex=0)
|
|
28782
|
+
{ role: "tablist", selector: "ul.ti3-tabs" },
|
|
28783
|
+
{ role: "tab", selector: ".ti3-tabs-text" },
|
|
28784
|
+
{ role: "tabpanel", selector: ["ti-tab.ti3-tab-pane", ".ti3-tab-pane"] },
|
|
28785
|
+
// 自定义下拉 / 区域选择触发器
|
|
28786
|
+
{
|
|
28787
|
+
role: "combobox",
|
|
28788
|
+
selector: [
|
|
28789
|
+
".ti3-select-dominator-container",
|
|
28790
|
+
".selected-label",
|
|
28791
|
+
".sort-select",
|
|
28792
|
+
".service-select",
|
|
28793
|
+
".region-select",
|
|
28794
|
+
'[cf-uba="searchableRegion..open"]'
|
|
28795
|
+
]
|
|
28796
|
+
},
|
|
28797
|
+
// 图标型 / 无语义按钮
|
|
28798
|
+
{
|
|
28799
|
+
role: "button",
|
|
28800
|
+
selector: [
|
|
28801
|
+
".modules-service-list-menu-service-icon-container",
|
|
28802
|
+
".ti3-btn-only-icon-noborder",
|
|
28803
|
+
".ti3-select-dominator-dropdown-btn",
|
|
28804
|
+
".modules-right-sidebar-icon-item-wrapper",
|
|
28805
|
+
".modules-right-sidebar-hide-state-plugin",
|
|
28806
|
+
".components-service-list-container-service-list-input-service-close",
|
|
28807
|
+
".modules-searchable-region-region-panel-close",
|
|
28808
|
+
".modules-searchable-region-region-panel-search-btn",
|
|
28809
|
+
'[cf-uba="rightSidebar..hideBtn"]',
|
|
28810
|
+
// Tiny3 图标组件:帮助中心固定/全屏/关闭等(ti-icon / tp-icon 无原生 button 语义)
|
|
28811
|
+
".ti-global-help-panel-header-icon",
|
|
28812
|
+
"ti-icon[name]",
|
|
28813
|
+
"tp-icon[name]",
|
|
28814
|
+
// 无 name 的箭头/操作图标(如 latest news 区 common-icon 展开箭头)
|
|
28815
|
+
"tp-icon.common-icon",
|
|
28816
|
+
"ti-icon.common-icon",
|
|
28817
|
+
"ti-icon.ti3-icon-full-screen",
|
|
28818
|
+
"ti-icon.ti3-icon-close",
|
|
28819
|
+
"tp-icon.ti3-icon-full-screen",
|
|
28820
|
+
"tp-icon.ti3-icon-close"
|
|
28821
|
+
]
|
|
28822
|
+
},
|
|
28823
|
+
// 服务列表侧栏分类 / 顶栏菜单项
|
|
28824
|
+
{
|
|
28825
|
+
role: "menuitem",
|
|
28826
|
+
selector: [
|
|
28827
|
+
".components-service-list-left-box-sidebar-visit-panel > li",
|
|
28828
|
+
".modules-menus-menu-item",
|
|
28829
|
+
".components-menu-wrapper-menu-text"
|
|
28830
|
+
]
|
|
28831
|
+
},
|
|
28832
|
+
// 区域筛选项 / 下拉选项
|
|
28833
|
+
{
|
|
28834
|
+
role: "option",
|
|
28835
|
+
selector: [
|
|
28836
|
+
".region-selector-item",
|
|
28837
|
+
".modules-searchable-region-project-item-region-item",
|
|
28838
|
+
".modules-searchable-region-region-panel-recent-region-item",
|
|
28839
|
+
".ti3-multiselect-box-cell"
|
|
28840
|
+
]
|
|
28841
|
+
},
|
|
28842
|
+
// 模态弹窗:补齐缺失的 role="dialog"(Tiny3 modal/message-box/drawer/侧栏面板)
|
|
28843
|
+
{
|
|
28844
|
+
role: "dialog",
|
|
28845
|
+
selector: [
|
|
28846
|
+
'[class*="ti3-modal"]',
|
|
28847
|
+
'[class*="ti3-message-box"]',
|
|
28848
|
+
'[class*="drawer"]',
|
|
28849
|
+
".modules-layout-module-sidebar-panel"
|
|
28850
|
+
]
|
|
28851
|
+
},
|
|
28852
|
+
// Tiny3 tooltip / 帮助提示:补齐缺失的 role="tooltip"
|
|
28853
|
+
{
|
|
28854
|
+
role: "tooltip",
|
|
28855
|
+
selector: ["tp-helptip", '[class*="ti3-tooltip"]', ".tp-helptip-content", ".ti3-tooltip", ".ti3-tooltip-popper"]
|
|
28856
|
+
}
|
|
28857
|
+
],
|
|
28858
|
+
states: {
|
|
28859
|
+
// 选中态:挂在容器 class 上,用 selector + closest 即可命中内部交互节点
|
|
28860
|
+
selected: [
|
|
28861
|
+
{ selector: "li.ti3-tab-li.ti3-tab-active" },
|
|
28862
|
+
// Tiny3 按钮组(计费模式等):ti3-active 在 .ti3-btn-item-container 上,不在 button 上
|
|
28863
|
+
{ selector: ".ti3-btn-item-container.ti3-active" },
|
|
28864
|
+
{ selector: ".components-service-list-left-box-active" },
|
|
28865
|
+
{
|
|
28866
|
+
selector: [
|
|
28867
|
+
".modules-searchable-region-project-item-region-item-selected",
|
|
28868
|
+
".components-search-content-search-select-search-select-selected"
|
|
28869
|
+
]
|
|
28870
|
+
}
|
|
28871
|
+
],
|
|
28872
|
+
hasPopup: [
|
|
28873
|
+
{
|
|
28874
|
+
selector: [
|
|
28875
|
+
".ti3-select-dominator-container",
|
|
28876
|
+
".selected-label",
|
|
28877
|
+
".sort-select",
|
|
28878
|
+
".service-select",
|
|
28879
|
+
".region-select",
|
|
28880
|
+
'[cf-uba="searchableRegion..open"]',
|
|
28881
|
+
'[cf-uba="serviceList..open"]',
|
|
28882
|
+
'[cf-uba="userinfo"]',
|
|
28883
|
+
"tp-helptip"
|
|
28884
|
+
]
|
|
28885
|
+
}
|
|
28886
|
+
],
|
|
28887
|
+
disabled: [{ selector: ".ti3-disabled" }],
|
|
28888
|
+
// Tiny3 / Lego 校验错误
|
|
28889
|
+
error: [{ selector: [".ti3-unifyvalid-error", ".ti3-error", ".ti-error", ".lego-text-error", ".lego-error"] }],
|
|
28890
|
+
// Tiny3 / Lego 警告
|
|
28891
|
+
warning: [{ selector: [".ti3-warning", ".ti-warning", ".lego-text-warning"] }],
|
|
28892
|
+
// 展开态:需结合计算样式,选择器表达不了「可见」
|
|
28893
|
+
expanded: [
|
|
28894
|
+
{
|
|
28895
|
+
match: (el) => {
|
|
28896
|
+
try {
|
|
28897
|
+
if (!el.matches(
|
|
28898
|
+
".modules-layout-module-sidebar-panel, .modules-searchable-region-region-panel, .ti3-dropdown-container"
|
|
28899
|
+
)) {
|
|
28900
|
+
return false;
|
|
28901
|
+
}
|
|
28902
|
+
const style = window.getComputedStyle(el);
|
|
28903
|
+
return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0";
|
|
28904
|
+
} catch {
|
|
28905
|
+
return false;
|
|
28906
|
+
}
|
|
28907
|
+
}
|
|
28908
|
+
}
|
|
28909
|
+
]
|
|
28910
|
+
},
|
|
28911
|
+
// exposedAttributes 输出属性 token;带 name 的 ti-icon/tp-icon 可交互性由 roles/whitelist 中 ti-icon[name] 等规则判定。
|
|
28912
|
+
exposedAttributes: ["cf-uba", "data-qa-id", "name"],
|
|
28913
|
+
whitelist: [
|
|
28914
|
+
".modules-service-list-menu-service-icon-container",
|
|
28915
|
+
".ti3-tabs-text",
|
|
28916
|
+
"tp-helptip",
|
|
28917
|
+
'[cf-uba="cloudShell"]',
|
|
28918
|
+
'[cf-uba="messageBox"]',
|
|
28919
|
+
'[cf-uba="helpFeedback"]',
|
|
28920
|
+
'[cf-uba="globalMessage"]',
|
|
28921
|
+
'[cf-uba="rightSidebar..hideBtn"]',
|
|
28922
|
+
// 帮助中心等区域的 ti-icon / tp-icon 图标按钮
|
|
28923
|
+
".ti-global-help-panel-header-icon",
|
|
28924
|
+
"ti-icon[name]",
|
|
28925
|
+
"tp-icon[name]",
|
|
28926
|
+
"tp-icon.common-icon",
|
|
28927
|
+
"ti-icon.common-icon",
|
|
28928
|
+
"ti-icon.ti3-icon-full-screen"
|
|
28929
|
+
],
|
|
28930
|
+
blacklist: [
|
|
28931
|
+
"noscript",
|
|
28932
|
+
"pan-gu",
|
|
28933
|
+
// 忽略 WebMCP 高亮容器
|
|
28934
|
+
"#webmcpcli-highlight-container",
|
|
28935
|
+
"#page-agent-runtime_simulator-mask",
|
|
28936
|
+
// CFUI 忽略几个大区域
|
|
28937
|
+
"#J_header",
|
|
28938
|
+
"#J_rightSidebar",
|
|
28939
|
+
"#cf_service_icon",
|
|
28940
|
+
"tp-helptip"
|
|
28941
|
+
]
|
|
28942
|
+
})
|
|
28943
|
+
};
|
|
28944
|
+
function isConsoleCloudHost(hostname2 = typeof location !== "undefined" ? location.hostname : "") {
|
|
28945
|
+
return /(^|\.)console\.huaweicloud\.com$/i.test(hostname2);
|
|
28411
28946
|
}
|
|
28412
28947
|
|
|
28413
28948
|
// src/inject/page-init.ts
|
|
@@ -28417,12 +28952,18 @@ ${diff2.isFullRefresh ? "\uFF08\u9996\u6B21/\u5237\u65B0\uFF0C\u65E0\u589E\u91CF
|
|
|
28417
28952
|
window.__webmcpcli_tools = await ctx.getTools();
|
|
28418
28953
|
}
|
|
28419
28954
|
}
|
|
28955
|
+
function resolvePageAgentToolOptions() {
|
|
28956
|
+
if (isConsoleCloudHost(location.hostname)) {
|
|
28957
|
+
return consoleCloudPageAgentToolOptions;
|
|
28958
|
+
}
|
|
28959
|
+
return { a11yConfig: { exposedAttributes: ["cf-uba"] } };
|
|
28960
|
+
}
|
|
28420
28961
|
function initWebMcpCliPage() {
|
|
28421
28962
|
if (window.__webmcpcli_init) {
|
|
28422
28963
|
return;
|
|
28423
28964
|
}
|
|
28424
28965
|
initializeWebMCPPolyfill();
|
|
28425
|
-
registerPageAgentTool(
|
|
28966
|
+
registerPageAgentTool(resolvePageAgentToolOptions());
|
|
28426
28967
|
window.__webmcpcli_tools = [];
|
|
28427
28968
|
const ctx = document.modelContext;
|
|
28428
28969
|
if (ctx?.addEventListener) {
|