@opentiny/next-sdk 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{SimulatorMask-BHVXyogh-iNUb4dyF.js → SimulatorMask-BHVXyogh-CKmEDsYG.js} +1 -1
- package/dist/core.js +1 -1
- package/dist/{index-CXK8CcKq.js → index-CHMa2zG4.js} +1985 -1434
- package/dist/index.d.ts +11 -0
- package/dist/index.js +69 -50
- package/dist/{initialize-builtin-WebMCP-rALfqS-o.js → initialize-builtin-WebMCP-JaoKwVlm.js} +355 -346
- package/dist/page-tools/a11y/build.d.ts +3 -4
- package/dist/page-tools/a11y/config.d.ts +99 -0
- package/dist/page-tools/a11y/constants.d.ts +22 -0
- package/dist/page-tools/a11y/search.d.ts +1 -1
- package/dist/page-tools/a11y/types.d.ts +13 -22
- package/dist/page-tools/a11y/utils.d.ts +46 -11
- package/dist/page-tools/a11y/vnode.d.ts +14 -11
- package/dist/page-tools/a11y-tree.d.ts +1 -0
- package/dist/page-tools/configs/console-cloud.d.ts +6 -0
- package/dist/page-tools/constants.d.ts +7 -17
- package/dist/page-tools/context.d.ts +14 -0
- package/dist/page-tools/handlers/hover.d.ts +9 -0
- package/dist/page-tools/handlers/searchTree.d.ts +2 -1
- package/dist/page-tools/page-agent-highlight/index.d.ts +12 -0
- package/dist/page-tools/page-agent-mask/SimulatorMask.d.ts +2 -0
- package/dist/page-tools/page-agent-tool-event.d.ts +26 -0
- package/dist/page-tools/schema.d.ts +4 -3
- package/dist/page-tools/tool-config.d.ts +50 -0
- package/dist/page-tools/utils/dom.d.ts +8 -2
- package/dist/runtime.d.ts +4 -1
- package/dist/runtime.js +22 -187
- package/dist/vitest.config.d.ts +2 -0
- package/package.json +26 -16
- package/WebMcpClient.ts +0 -505
- package/WebMcpServer.ts +0 -447
- package/agent/AgentModelProvider.ts +0 -932
- package/agent/type.ts +0 -91
- package/agent/utils/generateReActPrompt.ts +0 -71
- package/agent/utils/getAISDKTools.ts +0 -34
- package/agent/utils/getBuiltinMcpTools.ts +0 -86
- package/agent/utils/parseReActAction.ts +0 -34
- package/core.ts +0 -26
- package/index.ts +0 -56
- package/page-tools/a11y/build.ts +0 -70
- package/page-tools/a11y/constants.ts +0 -110
- package/page-tools/a11y/search.ts +0 -129
- package/page-tools/a11y/types.ts +0 -108
- package/page-tools/a11y/utils.ts +0 -266
- package/page-tools/a11y/vnode.ts +0 -229
- package/page-tools/a11y-tree.ts +0 -13
- package/page-tools/bridge.ts +0 -702
- package/page-tools/constants.ts +0 -72
- package/page-tools/context.ts +0 -13
- package/page-tools/effects.ts +0 -345
- package/page-tools/handlers/browserState.ts +0 -12
- package/page-tools/handlers/click.ts +0 -26
- package/page-tools/handlers/executeJavascript.ts +0 -22
- package/page-tools/handlers/fill.ts +0 -60
- package/page-tools/handlers/scroll.ts +0 -66
- package/page-tools/handlers/searchTree.ts +0 -30
- package/page-tools/handlers/select.ts +0 -34
- package/page-tools/initialize-builtin-WebMCP.ts +0 -20
- package/page-tools/page-agent-highlight/index.ts +0 -198
- package/page-tools/page-agent-mask/SimulatorMask.module.css +0 -14
- package/page-tools/page-agent-mask/SimulatorMask.ts +0 -279
- package/page-tools/page-agent-mask/checkDarkMode.ts +0 -181
- package/page-tools/page-agent-mask/cursor-border.svg +0 -3
- package/page-tools/page-agent-mask/cursor-fill.svg +0 -5
- package/page-tools/page-agent-mask/cursor.module.css +0 -70
- package/page-tools/page-agent-prompt.md +0 -139
- package/page-tools/page-agent-tool.ts +0 -175
- package/page-tools/page-state-cache.ts +0 -78
- package/page-tools/schema.ts +0 -51
- package/page-tools/utils/dom.ts +0 -155
- package/page-tools/utils/scroll.ts +0 -58
- package/remoter/QrCode.ts +0 -54
- package/remoter/createRemoter.ts +0 -957
- package/remoter/svgs/chat.svg +0 -43
- package/remoter/svgs/icon-copy.svg +0 -25
- package/remoter/svgs/link.svg +0 -28
- package/remoter/svgs/logo.svg +0 -45
- package/remoter/svgs/qrcode.svg +0 -35
- package/remoter/svgs/scan.svg +0 -21
- package/remoter/tooltips.ts +0 -260
- package/runtime.html +0 -39
- package/runtime.ts +0 -13
- package/script/utils.ts +0 -26
- package/skills/index.ts +0 -287
- package/tsconfig.json +0 -16
- package/utils/builtinProxy.ts +0 -144
- package/utils/env.ts +0 -13
- package/utils/uuid.ts +0 -10
- package/vite.config.runtime.ts +0 -22
- package/vite.config.ts +0 -63
package/page-tools/a11y/vnode.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* a11y/vnode.ts
|
|
3
|
-
*
|
|
4
|
-
* 处理无障碍树节点 (VNode) 的构建、剪枝与序列化逻辑。
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { computeAccessibleName } from 'dom-accessibility-api'
|
|
8
|
-
import { isFocusable, isTabbable } from 'tabbable'
|
|
9
|
-
import type { VNode, RefMap, A11yTreeOptions } from './types'
|
|
10
|
-
import { isHidden, inferRole, getStateTokens, collectDescendantText, getComposedChildren } from './utils'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 递归将 DOM 元素转换为 VNode 中间表示
|
|
14
|
-
* @param el 当前 DOM 元素
|
|
15
|
-
* @param refCounter 引用计数器(使用对象引用避免全局可变状态)
|
|
16
|
-
* @param refMap ref 索引 → 元素映射
|
|
17
|
-
* @param blacklistSet 用户自定义黑名单
|
|
18
|
-
* @param whitelistSet 用户自定义白名单
|
|
19
|
-
* @param exposedAttributes 需要暴露的自定义属性
|
|
20
|
-
* @param errorSelectors 错误选择器
|
|
21
|
-
* @param warningSelectors 警告选择器
|
|
22
|
-
*/
|
|
23
|
-
export function buildVNode(
|
|
24
|
-
el: Element,
|
|
25
|
-
refCounter: { value: number },
|
|
26
|
-
refMap: RefMap,
|
|
27
|
-
blacklistSet: Set<Element>,
|
|
28
|
-
whitelistSet: Set<Element>,
|
|
29
|
-
exposedAttributes?: string[],
|
|
30
|
-
errorSelectors?: string | string[],
|
|
31
|
-
warningSelectors?: string | string[],
|
|
32
|
-
/** 祖先节点是否已是可交互节点(已分配 ref)。为 true 时,纯 CSS 继承的 cursor=pointer 不再额外分配 ref */
|
|
33
|
-
ancestorIsInteractive = false,
|
|
34
|
-
): VNode | null {
|
|
35
|
-
if (isHidden(el) || blacklistSet.has(el)) return null
|
|
36
|
-
|
|
37
|
-
const role = inferRole(el)
|
|
38
|
-
const tokens = getStateTokens(el, exposedAttributes, errorSelectors, warningSelectors)
|
|
39
|
-
|
|
40
|
-
let name = computeAccessibleName(el as HTMLElement)
|
|
41
|
-
const isTrulyInteractive = isTabbable(el as HTMLElement)
|
|
42
|
-
const isVisuallyClickable = tokens.includes('cursor=pointer')
|
|
43
|
-
// 包含白名单属性的节点也视为白名单节点(确保不被剪枝并分配 ref 操作索引)
|
|
44
|
-
const isWhitelisted = whitelistSet.has(el) || (exposedAttributes?.some(attr => el.hasAttribute(attr)) ?? false)
|
|
45
|
-
// <label for="..."> 原生可点击:浏览器将点击转发到关联的表单控件(checkbox/radio 等)
|
|
46
|
-
// Angular/React 自定义组件常隐藏原生 input,仅暴露 label 文本和自定义 skin
|
|
47
|
-
const isLabelFor = el.tagName.toLowerCase() === 'label' && el.hasAttribute('for')
|
|
48
|
-
|
|
49
|
-
// 兜底方案:如果 AccName 计算结果为空,但该节点具有明显的交互性或属于结构性列表项,
|
|
50
|
-
// 我们从其子树收集纯文本作为其 fallback name,以防 AI 丢失可读上下文。
|
|
51
|
-
// 注意:不要对 <select> / combobox / listbox 等下拉组件进行文本兜底,以防它们吸收所有子选项文本导致极其嘈杂。
|
|
52
|
-
if (!name.trim()) {
|
|
53
|
-
const tag = el.tagName.toLowerCase()
|
|
54
|
-
const isDropdown = tag === 'select' || role === 'combobox' || role === 'listbox'
|
|
55
|
-
if (!isDropdown) {
|
|
56
|
-
const isInteractiveTag = ['button', 'a', 'input', 'textarea', 'li', 'label'].includes(tag)
|
|
57
|
-
if (isTrulyInteractive || isWhitelisted || isVisuallyClickable || isInteractiveTag || role === 'listitem' || role === 'option') {
|
|
58
|
-
name = collectDescendantText(el)
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 最终兜底:非交互元素(如错误提示 ti-error-msg、状态信息)的纯文本捕获。
|
|
64
|
-
// 仅当元素没有有价值的子元素时触发,避免与子节点文本重复:
|
|
65
|
-
// - 叶子 span(只有文本节点)→ 捕获文本作为 name
|
|
66
|
-
// - 容器元素(有 element 子节点)→ 不触发,由子节点各自捕获
|
|
67
|
-
if (!name.trim()) {
|
|
68
|
-
const hasElementChildren = getComposedChildren(el).length > 0
|
|
69
|
-
if (!hasElementChildren) {
|
|
70
|
-
const text = collectDescendantText(el)
|
|
71
|
-
if (text) {
|
|
72
|
-
name = text
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// generic 无 name 时,即使有 cursor=pointer 也不分配 ref:
|
|
78
|
-
// cursor 通常是 CSS 继承传播的,这类 div 本身无法被有意义地操作。
|
|
79
|
-
// 此外,当祖先节点已是可交互节点时,子节点仅凭 isVisuallyClickable(CSS 继承)
|
|
80
|
-
// 不再额外分配 ref,避免父节点 cursor:pointer 传染给所有子孙导致高亮泛滥。
|
|
81
|
-
//
|
|
82
|
-
// 例外:<a>/<button>/<input> 等语义性交互标签,无论祖先是否已有 ref,
|
|
83
|
-
// 始终强制分配 ref,因为它们在 HTML 语义上就是独立的操作单元。
|
|
84
|
-
const tagName = el.tagName.toLowerCase()
|
|
85
|
-
const isSemanticInteractiveTag =
|
|
86
|
-
(tagName === 'a' && el.hasAttribute('href')) ||
|
|
87
|
-
(['button', 'input', 'select', 'textarea'].includes(tagName) && !el.hasAttribute('disabled'))
|
|
88
|
-
|
|
89
|
-
// 虽然有些元素有 tabindex="0" (isTrulyInteractive),但如果它是 generic 且没有 cursor:pointer,
|
|
90
|
-
// 往往是开发者加的结构化 focus 容器(如 tp-card),而非真正的可交互按钮,我们在此过滤掉它们。
|
|
91
|
-
const isMeaningfullyInteractive = isTrulyInteractive && !(role === 'generic' && !isVisuallyClickable)
|
|
92
|
-
|
|
93
|
-
const interactive =
|
|
94
|
-
isMeaningfullyInteractive ||
|
|
95
|
-
isWhitelisted ||
|
|
96
|
-
isLabelFor ||
|
|
97
|
-
isSemanticInteractiveTag ||
|
|
98
|
-
(!ancestorIsInteractive && isVisuallyClickable && (role !== 'generic' || name !== ''))
|
|
99
|
-
|
|
100
|
-
let ref: number | undefined
|
|
101
|
-
if (interactive) {
|
|
102
|
-
ref = refCounter.value
|
|
103
|
-
refMap.set(ref, el as HTMLElement)
|
|
104
|
-
refCounter.value++
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const children: VNode[] = []
|
|
108
|
-
for (const child of getComposedChildren(el)) {
|
|
109
|
-
const childVNode = buildVNode(
|
|
110
|
-
child,
|
|
111
|
-
refCounter,
|
|
112
|
-
refMap,
|
|
113
|
-
blacklistSet,
|
|
114
|
-
whitelistSet,
|
|
115
|
-
exposedAttributes,
|
|
116
|
-
errorSelectors,
|
|
117
|
-
warningSelectors,
|
|
118
|
-
// 将当前节点的交互性向下传递,子节点据此决定是否抑制 cursor=pointer
|
|
119
|
-
interactive || ancestorIsInteractive,
|
|
120
|
-
)
|
|
121
|
-
if (childVNode) children.push(childVNode)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return { role, name, tokens, ref, el: el as HTMLElement, children }
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* 判断 VNode 子树是否包含任何有价值的节点(有 ref 或有 accessible name)
|
|
129
|
-
* 用于过滤空容器子树,避免输出无内容的嵌套层级
|
|
130
|
-
*/
|
|
131
|
-
export function hasValue(vnode: VNode): boolean {
|
|
132
|
-
if (vnode.ref !== undefined || vnode.name.trim() !== '') return true
|
|
133
|
-
return vnode.children.some(hasValue)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* 检查节点子树中是否存在任何有 ref 的可交互子节点。
|
|
138
|
-
* 用于判断父节点是否可以安全省略其子节点输出。
|
|
139
|
-
*/
|
|
140
|
-
function hasInteractiveDescendant(vnode: VNode): boolean {
|
|
141
|
-
return vnode.children.some(c => c.ref !== undefined || hasInteractiveDescendant(c))
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* 找到子树中恰好唯一一个有 ref 的节点,若有多个则返回 null。
|
|
146
|
-
* 用于判断是否可将该子节点与父节点合并输出。
|
|
147
|
-
*/
|
|
148
|
-
function findSingleRefDescendant(vnode: VNode): VNode | null {
|
|
149
|
-
const refs: VNode[] = []
|
|
150
|
-
const collect = (v: VNode) => {
|
|
151
|
-
if (v.ref !== undefined) refs.push(v)
|
|
152
|
-
if (refs.length > 1) return // 超过一个就提前退出
|
|
153
|
-
v.children.forEach(collect)
|
|
154
|
-
}
|
|
155
|
-
vnode.children.forEach(collect)
|
|
156
|
-
return refs.length === 1 ? refs[0] : null
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* 判断节点是否需要透明穿透(跳过本节点但保留子节点)
|
|
161
|
-
*
|
|
162
|
-
* 统一规则:无 ref(非交互)且无 accessible name → 穿透
|
|
163
|
-
* 这样可以同时:
|
|
164
|
-
* - 去掉 generic/list/listitem 等纯布局噪音(无 name 时穿透)
|
|
165
|
-
* - 保留有 name 的 listitem(有 name 时保留,兼顾内容理解场景)
|
|
166
|
-
*/
|
|
167
|
-
export function shouldPassThrough(vnode: VNode, opts: Required<A11yTreeOptions>): boolean {
|
|
168
|
-
if (!opts.pruneUnnamed) return false
|
|
169
|
-
// preserveRoles 中的角色强制保留
|
|
170
|
-
if (opts.preserveRoles.includes(vnode.role)) return false
|
|
171
|
-
// 有 ref(交互节点)→ 永远保留
|
|
172
|
-
if (vnode.ref !== undefined) return false
|
|
173
|
-
// 有 accessible name → 保留(兼顾内容理解场景)
|
|
174
|
-
if (vnode.name.trim() !== '') return false
|
|
175
|
-
// 无 ref 且无 name → 透明穿透
|
|
176
|
-
return true
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* 将 VNode 序列化为 YAML 行数组
|
|
181
|
-
* 穿透节点时,子节点在当前 depth 平铺输出(不增加缩进层级)
|
|
182
|
-
*/
|
|
183
|
-
export function serializeVNode(
|
|
184
|
-
vnode: VNode,
|
|
185
|
-
depth: number,
|
|
186
|
-
opts: Required<A11yTreeOptions>,
|
|
187
|
-
): string[] {
|
|
188
|
-
if (shouldPassThrough(vnode, opts)) {
|
|
189
|
-
// 透明穿透:跳过本节点,子节点保持当前 depth(层级不增加)
|
|
190
|
-
// 同时过滤掉整棵子树都无价値的空容器,避免输出无意义的嵌套
|
|
191
|
-
return vnode.children
|
|
192
|
-
.filter(c => hasValue(c))
|
|
193
|
-
.flatMap(c => serializeVNode(c, depth, opts))
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const indent = ' '.repeat(depth)
|
|
197
|
-
const refStr = vnode.ref !== undefined ? ` #${vnode.ref}` : ''
|
|
198
|
-
const safeTokens = vnode.tokens.map(t => t.replace(/[\r\n]+/g, ' ').replace(/"/g, '\\"'))
|
|
199
|
-
const tokenStr = safeTokens.length > 0 ? ` [${safeTokens.join(' ')}]` : ''
|
|
200
|
-
|
|
201
|
-
if (vnode.ref !== undefined) {
|
|
202
|
-
if (!hasInteractiveDescendant(vnode)) {
|
|
203
|
-
// 子树无任何 ref 节点 → 直接省略子节点
|
|
204
|
-
// 父节点的 name 已由 computeAccessibleName 汇总了子树文本,信息不会丢失
|
|
205
|
-
const safeName = vnode.name ? vnode.name.replace(/[\r\n]+/g, ' ').replace(/"/g, '\\"') : ''
|
|
206
|
-
const nameStr = safeName ? ` "${safeName}"` : ''
|
|
207
|
-
return [`${indent}- ${vnode.role}${refStr}${tokenStr}${nameStr}`]
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// 子树中唯一一个 ref 节点且是无子 ref 的 generic 时,将其 name 提升到父节点,省略子节点输出。
|
|
211
|
-
// 场景:`listitem #22 [active]` 内部只有 `generic #23 "总览"`,
|
|
212
|
-
// 点击意义相同时,就展示为一行 `- listitem #22 [active] "总览"`。
|
|
213
|
-
const singleChild = findSingleRefDescendant(vnode)
|
|
214
|
-
if (singleChild && singleChild.role === 'generic' && !hasInteractiveDescendant(singleChild)) {
|
|
215
|
-
const mergedName = (vnode.name.trim() || singleChild.name.trim())
|
|
216
|
-
.replace(/[\r\n]+/g, ' ')
|
|
217
|
-
.replace(/"/g, '\\"')
|
|
218
|
-
const nameStr = mergedName ? ` "${mergedName}"` : ''
|
|
219
|
-
return [`${indent}- ${vnode.role}${refStr}${tokenStr}${nameStr}`]
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const safeName = vnode.name ? vnode.name.replace(/[\r\n]+/g, ' ').replace(/"/g, '\\"') : ''
|
|
224
|
-
const nameStr = safeName ? ` "${safeName}"` : ''
|
|
225
|
-
const line = `${indent}- ${vnode.role}${refStr}${tokenStr}${nameStr}`
|
|
226
|
-
|
|
227
|
-
const childLines = vnode.children.flatMap(c => serializeVNode(c, depth + 1, opts))
|
|
228
|
-
return [line, ...childLines]
|
|
229
|
-
}
|
package/page-tools/a11y-tree.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* a11y-tree.ts
|
|
3
|
-
*
|
|
4
|
-
* 此文件为 A11y Tree 模块的汇总出口,
|
|
5
|
-
* 方便外部直接从 './a11y-tree' 引入相关类型及方法,而无需调整现有的引用路径。
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export * from './a11y/types'
|
|
9
|
-
export * from './a11y/constants'
|
|
10
|
-
export * from './a11y/utils'
|
|
11
|
-
export * from './a11y/vnode'
|
|
12
|
-
export * from './a11y/build'
|
|
13
|
-
export * from './a11y/search'
|