@opentiny/next-sdk 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/agent/AgentModelProvider.ts +78 -81
  2. package/agent/type.ts +6 -9
  3. package/agent/utils/getAISDKTools.ts +0 -1
  4. package/agent/utils/getBuiltinMcpTools.ts +7 -7
  5. package/core.ts +0 -3
  6. package/dist/SimulatorMask-BHVXyogh-CARX3Rff.js +361 -0
  7. package/dist/agent/type.d.ts +4 -12
  8. package/dist/agent/utils/getBuiltinMcpTools.d.ts +3 -3
  9. package/dist/core.d.ts +0 -1
  10. package/dist/core.js +16 -17
  11. package/dist/index-R_HIbfUX.js +6604 -0
  12. package/dist/index.d.ts +11 -3
  13. package/dist/index.js +76 -4969
  14. package/dist/{initialize-builtin-WebMCP-HgObT902.js → initialize-builtin-WebMCP-JaoKwVlm.js} +1156 -1037
  15. package/dist/page-tools/a11y/build.d.ts +10 -0
  16. package/dist/page-tools/a11y/config.d.ts +96 -0
  17. package/dist/page-tools/a11y/constants.d.ts +11 -0
  18. package/dist/page-tools/a11y/search.d.ts +17 -0
  19. package/dist/page-tools/a11y/types.d.ts +95 -0
  20. package/dist/page-tools/a11y/utils.d.ts +55 -0
  21. package/dist/page-tools/a11y/vnode.d.ts +40 -0
  22. package/dist/page-tools/a11y-tree.d.ts +9 -99
  23. package/dist/page-tools/configs/console-cloud.d.ts +6 -0
  24. package/dist/page-tools/constants.d.ts +10 -0
  25. package/dist/page-tools/context.d.ts +40 -0
  26. package/dist/page-tools/handlers/browserState.d.ts +8 -0
  27. package/dist/page-tools/handlers/click.d.ts +8 -0
  28. package/dist/page-tools/handlers/executeJavascript.d.ts +8 -0
  29. package/dist/page-tools/handlers/fill.d.ts +8 -0
  30. package/dist/page-tools/handlers/scroll.d.ts +8 -0
  31. package/dist/page-tools/handlers/searchTree.d.ts +9 -0
  32. package/dist/page-tools/handlers/select.d.ts +8 -0
  33. package/dist/page-tools/page-agent-highlight/index.d.ts +21 -0
  34. package/dist/page-tools/page-agent-mask/SimulatorMask.d.ts +16 -0
  35. package/dist/page-tools/page-agent-mask/checkDarkMode.d.ts +5 -0
  36. package/dist/page-tools/page-agent-tool-event.d.ts +26 -0
  37. package/dist/page-tools/page-agent-tool.d.ts +3 -8
  38. package/dist/page-tools/schema.d.ts +44 -0
  39. package/dist/page-tools/tool-config.d.ts +50 -0
  40. package/dist/page-tools/utils/dom.d.ts +6 -0
  41. package/dist/page-tools/utils/scroll.d.ts +15 -0
  42. package/dist/runtime.d.ts +7 -0
  43. package/dist/runtime.js +732 -0
  44. package/dist/utils/builtinProxy.d.ts +1 -1
  45. package/dist/vitest.config.d.ts +2 -0
  46. package/index.ts +35 -5
  47. package/package.json +23 -29
  48. package/page-tools/a11y/build.ts +74 -0
  49. package/page-tools/a11y/config.ts +465 -0
  50. package/page-tools/a11y/constants.ts +131 -0
  51. package/page-tools/a11y/search.ts +127 -0
  52. package/page-tools/a11y/types.ts +105 -0
  53. package/page-tools/a11y/utils.ts +239 -0
  54. package/page-tools/a11y/vnode.ts +439 -0
  55. package/page-tools/a11y-tree.ts +9 -527
  56. package/page-tools/bridge.ts +23 -3
  57. package/page-tools/configs/console-cloud.ts +172 -0
  58. package/page-tools/constants.ts +12 -0
  59. package/page-tools/context.ts +50 -0
  60. package/page-tools/handlers/browserState.ts +12 -0
  61. package/page-tools/handlers/click.ts +30 -0
  62. package/page-tools/handlers/executeJavascript.ts +22 -0
  63. package/page-tools/handlers/fill.ts +65 -0
  64. package/page-tools/handlers/scroll.ts +66 -0
  65. package/page-tools/handlers/searchTree.ts +27 -0
  66. package/page-tools/handlers/select.ts +39 -0
  67. package/page-tools/page-agent-highlight/index.ts +245 -0
  68. package/page-tools/page-agent-mask/SimulatorMask.module.css +14 -0
  69. package/page-tools/page-agent-mask/SimulatorMask.ts +299 -0
  70. package/page-tools/page-agent-mask/checkDarkMode.ts +181 -0
  71. package/page-tools/page-agent-mask/cursor-border.svg +3 -0
  72. package/page-tools/page-agent-mask/cursor-fill.svg +5 -0
  73. package/page-tools/page-agent-mask/cursor.module.css +70 -0
  74. package/page-tools/page-agent-mask/hauwei.svg +25 -0
  75. package/page-tools/page-agent-prompt.md +34 -18
  76. package/page-tools/page-agent-tool-event.ts +113 -0
  77. package/page-tools/page-agent-tool.ts +146 -162
  78. package/page-tools/schema.ts +52 -0
  79. package/page-tools/tool-config.ts +100 -0
  80. package/page-tools/utils/dom.ts +158 -0
  81. package/page-tools/utils/scroll.ts +58 -0
  82. package/runtime.ts +44 -0
  83. package/test/page-tools/a11y/build.test.ts +638 -0
  84. package/test/page-tools/a11y/config.test.ts +370 -0
  85. package/test/page-tools/configs/console-cloud.test.ts +168 -0
  86. package/test/page-tools/page-agent-highlight.test.ts +110 -0
  87. package/test/page-tools/page-agent-tool-dispatch.test.ts +208 -0
  88. package/test/page-tools/page-agent-tool.test.ts +102 -0
  89. package/test/page-tools/tool-config.test.ts +112 -0
  90. package/test/page-tools/utils/dom.test.ts +122 -0
  91. package/utils/builtinProxy.ts +45 -13
  92. package/vite.config.runtime.ts +22 -0
  93. package/vite.config.ts +52 -8
  94. package/vitest.config.ts +10 -0
  95. package/McpSdk.ts +0 -14
  96. package/WebAgent.ts +0 -5
  97. package/WebMcp.ts +0 -26
  98. package/Zod.ts +0 -1
  99. package/dist/McpSdk.d.ts +0 -14
  100. package/dist/SimulatorMask-BHVXyogh-BFEGpD5S.js +0 -1048
  101. package/dist/SimulatorMask-BHVXyogh-CCYbrb84.js +0 -801
  102. package/dist/WebAgent.d.ts +0 -5
  103. package/dist/WebMcp.d.ts +0 -23
  104. package/dist/Zod.d.ts +0 -1
  105. package/dist/index.es.dev.js +0 -59017
  106. package/dist/index.es.js +0 -46795
  107. package/dist/index.umd.dev.js +0 -60355
  108. package/dist/index.umd.js +0 -1248
  109. package/dist/mcpsdk@1.25.3.dev.js +0 -22780
  110. package/dist/mcpsdk@1.25.3.es.dev.js +0 -22778
  111. package/dist/mcpsdk@1.25.3.es.js +0 -16960
  112. package/dist/mcpsdk@1.25.3.js +0 -48
  113. package/dist/transport/ExtensionClientTransport.d.ts +0 -24
  114. package/dist/transport/ExtensionContentServerTransport.d.ts +0 -39
  115. package/dist/transport/ExtensionPageServerTransport.d.ts +0 -36
  116. package/dist/transport/messages.d.ts +0 -9
  117. package/dist/vite.config.mcpSdk.d.ts +0 -2
  118. package/dist/vite.config.webAgent.d.ts +0 -2
  119. package/dist/vite.config.webMcp.d.ts +0 -2
  120. package/dist/vite.config.webMcpFull.d.ts +0 -2
  121. package/dist/vite.config.zod.d.ts +0 -2
  122. package/dist/webagent.dev.js +0 -49360
  123. package/dist/webagent.es.dev.js +0 -49071
  124. package/dist/webagent.es.js +0 -39219
  125. package/dist/webagent.js +0 -642
  126. package/dist/webmcp-full.dev.js +0 -31336
  127. package/dist/webmcp-full.es.dev.js +0 -30283
  128. package/dist/webmcp-full.es.js +0 -22889
  129. package/dist/webmcp-full.js +0 -645
  130. package/dist/webmcp.dev.js +0 -9572
  131. package/dist/webmcp.es.dev.js +0 -8518
  132. package/dist/webmcp.es.js +0 -6727
  133. package/dist/webmcp.js +0 -602
  134. package/dist/zod@3.25.76.dev.js +0 -4037
  135. package/dist/zod@3.25.76.es.dev.js +0 -4033
  136. package/dist/zod@3.25.76.es.js +0 -2945
  137. package/dist/zod@3.25.76.js +0 -1
  138. package/transport/ExtensionClientTransport.ts +0 -100
  139. package/transport/ExtensionContentServerTransport.ts +0 -162
  140. package/transport/ExtensionPageServerTransport.ts +0 -149
  141. package/transport/messages.ts +0 -63
  142. package/vite-build-tsc.ts +0 -63
  143. package/vite-env.d.ts +0 -10
  144. package/vite.config.mcpSdk.ts +0 -28
  145. package/vite.config.webAgent.ts +0 -19
  146. package/vite.config.webMcp.ts +0 -40
  147. package/vite.config.webMcpFull.ts +0 -19
  148. package/vite.config.zod.ts +0 -23
  149. /package/dist/{vite-build-tsc.d.ts → vite.config.runtime.d.ts} +0 -0
@@ -0,0 +1,158 @@
1
+ import { extractSelectors } from '../a11y/config'
2
+ import { getPageAgentToolConfig } from '../tool-config'
3
+
4
+ // ─── 辅助:Shadow DOM 事件穿透 ───────────────────────────────────────────
5
+ // 外部包 inputTextElement/selectOptionElement 派发的合成事件 composed:false,
6
+ // 无法穿透 shadow boundary,导致事件委托框架(如 React)收不到 shadow 内元素的
7
+ // input/change 事件。这里对 shadow DOM 内元素补发 composed:true 事件。
8
+ export function isInShadowDom(el: Element): boolean {
9
+ return el.getRootNode() instanceof ShadowRoot
10
+ }
11
+
12
+ export function dispatchComposedEvents(el: Element, ...types: string[]) {
13
+ for (const type of types) {
14
+ el.dispatchEvent(new Event(type, { bubbles: true, composed: true }))
15
+ }
16
+ }
17
+
18
+ // ─── 辅助:穿透 Shadow DOM 的查询 ─────────────────────────────────────────
19
+ export function deepQuerySelectorAll(selector: string, root: Document | Element | ShadowRoot = document): Element[] {
20
+ const elements = Array.from(root.querySelectorAll(selector))
21
+
22
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null)
23
+ let currentNode: Node | null = walker.currentNode
24
+ while (currentNode) {
25
+ if ((currentNode as Element).shadowRoot) {
26
+ elements.push(...deepQuerySelectorAll(selector, (currentNode as Element).shadowRoot!))
27
+ }
28
+ currentNode = walker.nextNode()
29
+ }
30
+ return elements
31
+ }
32
+
33
+ // ─── 辅助:等待 DOM 变更稳定 ────────────────────────────────────────────
34
+ // click/fill/select 操作后,框架(Angular/React/Vue)可能异步插入校验错误、
35
+ // 条件渲染选项等动态内容。用 MutationObserver 监听 DOM 变更,等待变更平息后
36
+ // 再构建 A11y 树,确保动态插入的内容(如 ng-star-inserted 校验提示)被捕获。
37
+ export function waitForDomSettled(timeout = 600, settleTime = 150): Promise<void> {
38
+ return new Promise<void>((resolve) => {
39
+ let settled = false
40
+ let settleTimer: ReturnType<typeof setTimeout> | undefined
41
+ const finish = () => {
42
+ if (settled) return
43
+ settled = true
44
+ observer.disconnect()
45
+ if (settleTimer) clearTimeout(settleTimer)
46
+ resolve()
47
+ }
48
+ // 每次有 DOM 变更时重置 settle 计时器;变更平息 settleTime 后视为稳定
49
+ const observer = new MutationObserver(() => {
50
+ if (settleTimer) clearTimeout(settleTimer)
51
+ settleTimer = setTimeout(finish, settleTime)
52
+ })
53
+ // 若无任何变更,settleTime 后直接结束
54
+ settleTimer = setTimeout(finish, settleTime)
55
+ // 超时保护:timeout 后强制结束,避免无限等待
56
+ setTimeout(finish, timeout)
57
+ observer.observe(document.body, {
58
+ childList: true,
59
+ subtree: true,
60
+ attributes: true,
61
+ attributeFilter: ['class', 'style', 'hidden'],
62
+ })
63
+ })
64
+ }
65
+
66
+ // ─── 辅助:检测页面级模态弹窗/遮罩层 ────────────────────────────────────
67
+ // 仅检测真正阻塞交互的模态弹窗(确认框、提交对话框等),
68
+ // 不检测顶部通知横幅、站内消息等非模态提示,避免误报导致 AI 循环
69
+ export function detectPageDialog(): string {
70
+ const seen = new Set<Element>()
71
+ const dialogs: string[] = []
72
+ // 仅匹配明确的模态弹窗选择器,避免宽泛子串匹配误报
73
+ // 统一取 getPageAgentToolConfig().a11yConfig.dialogSelectors(已含默认值 + 用户配置)
74
+ const selectors = getPageAgentToolConfig().a11yConfig.dialogSelectors
75
+
76
+ for (const selector of selectors) {
77
+ try {
78
+ for (const el of deepQuerySelectorAll(selector)) {
79
+ if (seen.has(el)) continue
80
+ // 跳过 SDK 自身遮罩
81
+ if (el.id?.includes('page-agent-runtime')) continue
82
+ if (el.closest('#page-agent-runtime_simulator-mask')) continue
83
+
84
+ const rect = el.getBoundingClientRect()
85
+ if (rect.width < 50 || rect.height < 50) continue
86
+ const style = window.getComputedStyle(el as HTMLElement)
87
+ if (style.display === 'none' || style.visibility === 'hidden') continue
88
+
89
+ // 模态性验证:必须是 fixed/absolute 且 z-index 较高
90
+ const isFixed = style.position === 'fixed' || style.position === 'absolute'
91
+ const zIndex = parseInt(style.zIndex || '0', 10)
92
+ if (!isFixed || zIndex < 100) continue
93
+
94
+ // 必须覆盖视口中心区域(真正的模态弹窗会遮挡页面中心)
95
+ const vw = window.innerWidth
96
+ const vh = window.innerHeight
97
+ const coversCenter = rect.left < vw * 0.6 && rect.right > vw * 0.4 &&
98
+ rect.top < vh * 0.6 && rect.bottom > vh * 0.4
99
+ if (!coversCenter) continue
100
+
101
+ seen.add(el)
102
+ const text = (el.textContent || '').trim().replace(/\s+/g, ' ')
103
+ if (text.length > 5) {
104
+ // 提取弹窗内的可交互按钮,帮助 AI 快速决策
105
+ const btns = el.querySelectorAll('button, [role="button"], a')
106
+ const btnTexts = Array.from(btns)
107
+ .map(b => (b.textContent || '').trim())
108
+ .filter(t => t.length > 0 && t.length < 20)
109
+ .slice(0, 5)
110
+ const btnInfo = btnTexts.length ? ` [可操作按钮: ${btnTexts.join(' / ')}]` : ''
111
+ dialogs.push(`${text.substring(0, 300)}${btnInfo}`)
112
+ }
113
+ }
114
+ } catch {
115
+ // 忽略选择器异常
116
+ }
117
+ }
118
+
119
+ if (dialogs.length === 0) return ''
120
+ return `\n[页面弹窗检测] 检测到 ${dialogs.length} 个模态弹窗,请优先处理:\n${dialogs.map((d, i) => `${i + 1}. ${d}`).join('\n')}\n`
121
+ }
122
+
123
+ // ─── 辅助:检测页面可见的表单校验错误 ──────────────────────────────────
124
+ // 操作后自动扫描页面中的校验错误提示,提取文本并提醒 AI,
125
+ // 避免 AI 卡住时不知道是因为有校验错误未处理
126
+ export function detectValidationErrors(): string {
127
+ const seen = new Set<Element>()
128
+ const errors: string[] = []
129
+ // 校验错误选择器:ARIA 标准 + 主流 UI 框架(可配置)
130
+ // 统一取 getPageAgentToolConfig().a11yConfig.states.error(已含默认值 + 用户配置)
131
+ const selectors = extractSelectors(getPageAgentToolConfig().a11yConfig.states.error)
132
+
133
+ for (const selector of selectors) {
134
+ try {
135
+ for (const el of deepQuerySelectorAll(selector)) {
136
+ if (seen.has(el)) continue
137
+ // 跳过嵌套在已收集的错误元素内的子元素,避免重复
138
+ if (Array.from(seen).some(s => s.contains(el))) continue
139
+
140
+ const rect = el.getBoundingClientRect()
141
+ if (rect.width < 1 || rect.height < 1) continue
142
+ const style = window.getComputedStyle(el as HTMLElement)
143
+ if (style.display === 'none' || style.visibility === 'hidden') continue
144
+
145
+ const text = (el.textContent || '').trim().replace(/\s+/g, ' ')
146
+ if (text.length > 2 && text.length < 200) {
147
+ seen.add(el)
148
+ errors.push(text)
149
+ }
150
+ }
151
+ } catch {
152
+ // 忽略选择器异常
153
+ }
154
+ }
155
+
156
+ if (errors.length === 0) return ''
157
+ return `\n[校验提示] 检测到 ${errors.length} 个表单校验错误,请先修复后再继续:\n${errors.map((e, i) => `${i + 1}. ${e}`).join('\n')}\n`
158
+ }
@@ -0,0 +1,58 @@
1
+ // ─── 辅助:获取滚动目标的当前位置信息(仿 page-agent getPageInfo)────────
2
+ // 同时支持 window(文档滚动)和任意 Element(容器滚动)
3
+ export function getScrollInfo(target: Window | Element = window) {
4
+ if (target === window) {
5
+ const pageHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight)
6
+ const pageWidth = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth)
7
+ const scrollY = window.scrollY
8
+ const scrollX = window.scrollX
9
+ const pixelsBelow = Math.max(0, pageHeight - (window.innerHeight + scrollY))
10
+ const pixelsRight = Math.max(0, pageWidth - (window.innerWidth + scrollX))
11
+ return {
12
+ scrollY, scrollX,
13
+ pixelsAbove: scrollY, pixelsBelow,
14
+ pixelsLeft: scrollX, pixelsRight,
15
+ pagesAbove: window.innerHeight > 0 ? scrollY / window.innerHeight : 0,
16
+ pagesBelow: window.innerHeight > 0 ? pixelsBelow / window.innerHeight : 0,
17
+ atTop: scrollY <= 1,
18
+ atBottom: pixelsBelow <= 1,
19
+ atLeft: scrollX <= 1,
20
+ atRight: pixelsRight <= 1,
21
+ }
22
+ } else {
23
+ const el = target as Element
24
+ const scrollTop = el.scrollTop
25
+ const scrollLeft = el.scrollLeft
26
+ const pixelsBelow = el.scrollHeight - el.clientHeight - scrollTop
27
+ const pixelsRight = el.scrollWidth - el.clientWidth - scrollLeft
28
+ return {
29
+ scrollY: scrollTop, scrollX: scrollLeft,
30
+ pixelsAbove: scrollTop, pixelsBelow: Math.max(0, pixelsBelow),
31
+ pixelsLeft: scrollLeft, pixelsRight: Math.max(0, pixelsRight),
32
+ pagesAbove: el.clientHeight > 0 ? scrollTop / el.clientHeight : 0,
33
+ pagesBelow: el.clientHeight > 0 ? Math.max(0, pixelsBelow) / el.clientHeight : 0,
34
+ atTop: scrollTop <= 1,
35
+ atBottom: pixelsBelow <= 1,
36
+ atLeft: scrollLeft <= 1,
37
+ atRight: pixelsRight <= 1,
38
+ }
39
+ }
40
+ }
41
+
42
+ // 等待 smooth scroll 结束:优先监听 scrollend,超时兜底(边界无位移时 scrollend 可能不触发)
43
+ export function waitForScrollEnd(target: Window | Element, timeout = 2000): Promise<void> {
44
+ return new Promise((resolve) => {
45
+ let settled = false
46
+ const el = target === window ? document : (target as Element)
47
+ const finish = () => {
48
+ if (settled) return
49
+ settled = true
50
+ el.removeEventListener('scrollend', onScrollEnd)
51
+ clearTimeout(timer)
52
+ resolve()
53
+ }
54
+ const onScrollEnd = () => finish()
55
+ const timer = setTimeout(finish, timeout)
56
+ el.addEventListener('scrollend', onScrollEnd, { once: true })
57
+ })
58
+ }
package/runtime.ts ADDED
@@ -0,0 +1,44 @@
1
+ import { initializeBuiltinWebMCP } from './page-tools/initialize-builtin-WebMCP'
2
+ import { registerPageAgentTool } from './page-tools/page-agent-tool'
3
+ import { getPageAgentToolConfig, setPageAgentToolConfig } from './page-tools/tool-config'
4
+ import { defineA11yConfig } from './page-tools/a11y/config'
5
+ import {
6
+ consoleCloudPageAgentToolOptions,
7
+ isConsoleCloudHost,
8
+ } from './page-tools/configs/console-cloud'
9
+
10
+ /**
11
+ * runtime IIFE 仅挂载可调用 API,不自动 registerPageAgentTool。
12
+ * 调用方需自行传入 enableHighlight / a11yConfig 等选项后再注册,例如:
13
+ * registerPageAgentTool({ enableHighlight: true, a11yConfig: { exposedAttributes: ['cf-uba'] } })
14
+ * registerPageAgentTool(consoleCloudPageAgentToolOptions)
15
+ */
16
+ const runtimeApi = {
17
+ initializeBuiltinWebMCP,
18
+ registerPageAgentTool,
19
+ getPageAgentToolConfig,
20
+ setPageAgentToolConfig,
21
+ defineA11yConfig,
22
+ consoleCloudPageAgentToolOptions,
23
+ isConsoleCloudHost,
24
+ }
25
+
26
+ if (typeof window !== 'undefined') {
27
+ Object.assign(window, runtimeApi)
28
+
29
+ // 之前版本存在 WebMCP.registerPageAgentTool,当前先临时兼容,后续再移除
30
+ if (!(window as any).WebMCP) {
31
+ ;(window as any).WebMCP = {}
32
+ }
33
+ Object.assign((window as any).WebMCP, runtimeApi)
34
+ }
35
+
36
+ export {
37
+ initializeBuiltinWebMCP,
38
+ registerPageAgentTool,
39
+ getPageAgentToolConfig,
40
+ setPageAgentToolConfig,
41
+ defineA11yConfig,
42
+ consoleCloudPageAgentToolOptions,
43
+ isConsoleCloudHost,
44
+ }