@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.
Files changed (90) hide show
  1. package/dist/{SimulatorMask-BHVXyogh-iNUb4dyF.js → SimulatorMask-BHVXyogh-CKmEDsYG.js} +1 -1
  2. package/dist/core.js +1 -1
  3. package/dist/{index-CXK8CcKq.js → index-CHMa2zG4.js} +1985 -1434
  4. package/dist/index.d.ts +11 -0
  5. package/dist/index.js +69 -50
  6. package/dist/{initialize-builtin-WebMCP-rALfqS-o.js → initialize-builtin-WebMCP-JaoKwVlm.js} +355 -346
  7. package/dist/page-tools/a11y/build.d.ts +3 -4
  8. package/dist/page-tools/a11y/config.d.ts +99 -0
  9. package/dist/page-tools/a11y/constants.d.ts +22 -0
  10. package/dist/page-tools/a11y/search.d.ts +1 -1
  11. package/dist/page-tools/a11y/types.d.ts +13 -22
  12. package/dist/page-tools/a11y/utils.d.ts +46 -11
  13. package/dist/page-tools/a11y/vnode.d.ts +14 -11
  14. package/dist/page-tools/a11y-tree.d.ts +1 -0
  15. package/dist/page-tools/configs/console-cloud.d.ts +6 -0
  16. package/dist/page-tools/constants.d.ts +7 -17
  17. package/dist/page-tools/context.d.ts +14 -0
  18. package/dist/page-tools/handlers/hover.d.ts +9 -0
  19. package/dist/page-tools/handlers/searchTree.d.ts +2 -1
  20. package/dist/page-tools/page-agent-highlight/index.d.ts +12 -0
  21. package/dist/page-tools/page-agent-mask/SimulatorMask.d.ts +2 -0
  22. package/dist/page-tools/page-agent-tool-event.d.ts +26 -0
  23. package/dist/page-tools/schema.d.ts +4 -3
  24. package/dist/page-tools/tool-config.d.ts +50 -0
  25. package/dist/page-tools/utils/dom.d.ts +8 -2
  26. package/dist/runtime.d.ts +4 -1
  27. package/dist/runtime.js +22 -187
  28. package/dist/vitest.config.d.ts +2 -0
  29. package/package.json +26 -16
  30. package/WebMcpClient.ts +0 -505
  31. package/WebMcpServer.ts +0 -447
  32. package/agent/AgentModelProvider.ts +0 -932
  33. package/agent/type.ts +0 -91
  34. package/agent/utils/generateReActPrompt.ts +0 -71
  35. package/agent/utils/getAISDKTools.ts +0 -34
  36. package/agent/utils/getBuiltinMcpTools.ts +0 -86
  37. package/agent/utils/parseReActAction.ts +0 -34
  38. package/core.ts +0 -26
  39. package/index.ts +0 -56
  40. package/page-tools/a11y/build.ts +0 -70
  41. package/page-tools/a11y/constants.ts +0 -110
  42. package/page-tools/a11y/search.ts +0 -129
  43. package/page-tools/a11y/types.ts +0 -108
  44. package/page-tools/a11y/utils.ts +0 -266
  45. package/page-tools/a11y/vnode.ts +0 -229
  46. package/page-tools/a11y-tree.ts +0 -13
  47. package/page-tools/bridge.ts +0 -702
  48. package/page-tools/constants.ts +0 -72
  49. package/page-tools/context.ts +0 -13
  50. package/page-tools/effects.ts +0 -345
  51. package/page-tools/handlers/browserState.ts +0 -12
  52. package/page-tools/handlers/click.ts +0 -26
  53. package/page-tools/handlers/executeJavascript.ts +0 -22
  54. package/page-tools/handlers/fill.ts +0 -60
  55. package/page-tools/handlers/scroll.ts +0 -66
  56. package/page-tools/handlers/searchTree.ts +0 -30
  57. package/page-tools/handlers/select.ts +0 -34
  58. package/page-tools/initialize-builtin-WebMCP.ts +0 -20
  59. package/page-tools/page-agent-highlight/index.ts +0 -198
  60. package/page-tools/page-agent-mask/SimulatorMask.module.css +0 -14
  61. package/page-tools/page-agent-mask/SimulatorMask.ts +0 -279
  62. package/page-tools/page-agent-mask/checkDarkMode.ts +0 -181
  63. package/page-tools/page-agent-mask/cursor-border.svg +0 -3
  64. package/page-tools/page-agent-mask/cursor-fill.svg +0 -5
  65. package/page-tools/page-agent-mask/cursor.module.css +0 -70
  66. package/page-tools/page-agent-prompt.md +0 -139
  67. package/page-tools/page-agent-tool.ts +0 -175
  68. package/page-tools/page-state-cache.ts +0 -78
  69. package/page-tools/schema.ts +0 -51
  70. package/page-tools/utils/dom.ts +0 -155
  71. package/page-tools/utils/scroll.ts +0 -58
  72. package/remoter/QrCode.ts +0 -54
  73. package/remoter/createRemoter.ts +0 -957
  74. package/remoter/svgs/chat.svg +0 -43
  75. package/remoter/svgs/icon-copy.svg +0 -25
  76. package/remoter/svgs/link.svg +0 -28
  77. package/remoter/svgs/logo.svg +0 -45
  78. package/remoter/svgs/qrcode.svg +0 -35
  79. package/remoter/svgs/scan.svg +0 -21
  80. package/remoter/tooltips.ts +0 -260
  81. package/runtime.html +0 -39
  82. package/runtime.ts +0 -13
  83. package/script/utils.ts +0 -26
  84. package/skills/index.ts +0 -287
  85. package/tsconfig.json +0 -16
  86. package/utils/builtinProxy.ts +0 -144
  87. package/utils/env.ts +0 -13
  88. package/utils/uuid.ts +0 -10
  89. package/vite.config.runtime.ts +0 -22
  90. package/vite.config.ts +0 -63
@@ -1,155 +0,0 @@
1
- import { DEFAULT_DIALOG_SELECTORS, DEFAULT_ERROR_SELECTORS } from '../constants'
2
-
3
- // ─── 辅助:Shadow DOM 事件穿透 ───────────────────────────────────────────
4
- // 外部包 inputTextElement/selectOptionElement 派发的合成事件 composed:false,
5
- // 无法穿透 shadow boundary,导致事件委托框架(如 React)收不到 shadow 内元素的
6
- // input/change 事件。这里对 shadow DOM 内元素补发 composed:true 事件。
7
- export function isInShadowDom(el: Element): boolean {
8
- return el.getRootNode() instanceof ShadowRoot
9
- }
10
-
11
- export function dispatchComposedEvents(el: Element, ...types: string[]) {
12
- for (const type of types) {
13
- el.dispatchEvent(new Event(type, { bubbles: true, composed: true }))
14
- }
15
- }
16
-
17
- // ─── 辅助:穿透 Shadow DOM 的查询 ─────────────────────────────────────────
18
- export function deepQuerySelectorAll(selector: string, root: Document | Element | ShadowRoot = document): Element[] {
19
- const elements = Array.from(root.querySelectorAll(selector))
20
-
21
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null)
22
- let currentNode: Node | null = walker.currentNode
23
- while (currentNode) {
24
- if ((currentNode as Element).shadowRoot) {
25
- elements.push(...deepQuerySelectorAll(selector, (currentNode as Element).shadowRoot!))
26
- }
27
- currentNode = walker.nextNode()
28
- }
29
- return elements
30
- }
31
-
32
- // ─── 辅助:等待 DOM 变更稳定 ────────────────────────────────────────────
33
- // click/fill/select 操作后,框架(Angular/React/Vue)可能异步插入校验错误、
34
- // 条件渲染选项等动态内容。用 MutationObserver 监听 DOM 变更,等待变更平息后
35
- // 再构建 A11y 树,确保动态插入的内容(如 ng-star-inserted 校验提示)被捕获。
36
- export function waitForDomSettled(timeout = 600, settleTime = 150): Promise<void> {
37
- return new Promise<void>((resolve) => {
38
- let settled = false
39
- let settleTimer: ReturnType<typeof setTimeout> | undefined
40
- const finish = () => {
41
- if (settled) return
42
- settled = true
43
- observer.disconnect()
44
- if (settleTimer) clearTimeout(settleTimer)
45
- resolve()
46
- }
47
- // 每次有 DOM 变更时重置 settle 计时器;变更平息 settleTime 后视为稳定
48
- const observer = new MutationObserver(() => {
49
- if (settleTimer) clearTimeout(settleTimer)
50
- settleTimer = setTimeout(finish, settleTime)
51
- })
52
- // 若无任何变更,settleTime 后直接结束
53
- settleTimer = setTimeout(finish, settleTime)
54
- // 超时保护:timeout 后强制结束,避免无限等待
55
- setTimeout(finish, timeout)
56
- observer.observe(document.body, {
57
- childList: true,
58
- subtree: true,
59
- attributes: true,
60
- attributeFilter: ['class', 'style', 'hidden'],
61
- })
62
- })
63
- }
64
-
65
- // ─── 辅助:检测页面级模态弹窗/遮罩层 ────────────────────────────────────
66
- // 仅检测真正阻塞交互的模态弹窗(确认框、提交对话框等),
67
- // 不检测顶部通知横幅、站内消息等非模态提示,避免误报导致 AI 循环
68
- export function detectPageDialog(): string {
69
- const seen = new Set<Element>()
70
- const dialogs: string[] = []
71
- // 仅匹配明确的模态弹窗选择器,避免宽泛子串匹配误报
72
- const selectors = (window.__webmcpcli_dialogSelectors ?? DEFAULT_DIALOG_SELECTORS)
73
-
74
- for (const selector of selectors) {
75
- try {
76
- for (const el of deepQuerySelectorAll(selector)) {
77
- if (seen.has(el)) continue
78
- // 跳过 SDK 自身遮罩
79
- if (el.id?.includes('page-agent-runtime')) continue
80
- if (el.closest('#page-agent-runtime_simulator-mask')) continue
81
-
82
- const rect = el.getBoundingClientRect()
83
- if (rect.width < 50 || rect.height < 50) continue
84
- const style = window.getComputedStyle(el as HTMLElement)
85
- if (style.display === 'none' || style.visibility === 'hidden') continue
86
-
87
- // 模态性验证:必须是 fixed/absolute 且 z-index 较高
88
- const isFixed = style.position === 'fixed' || style.position === 'absolute'
89
- const zIndex = parseInt(style.zIndex || '0', 10)
90
- if (!isFixed || zIndex < 100) continue
91
-
92
- // 必须覆盖视口中心区域(真正的模态弹窗会遮挡页面中心)
93
- const vw = window.innerWidth
94
- const vh = window.innerHeight
95
- const coversCenter = rect.left < vw * 0.6 && rect.right > vw * 0.4 &&
96
- rect.top < vh * 0.6 && rect.bottom > vh * 0.4
97
- if (!coversCenter) continue
98
-
99
- seen.add(el)
100
- const text = (el.textContent || '').trim().replace(/\s+/g, ' ')
101
- if (text.length > 5) {
102
- // 提取弹窗内的可交互按钮,帮助 AI 快速决策
103
- const btns = el.querySelectorAll('button, [role="button"], a')
104
- const btnTexts = Array.from(btns)
105
- .map(b => (b.textContent || '').trim())
106
- .filter(t => t.length > 0 && t.length < 20)
107
- .slice(0, 5)
108
- const btnInfo = btnTexts.length ? ` [可操作按钮: ${btnTexts.join(' / ')}]` : ''
109
- dialogs.push(`${text.substring(0, 300)}${btnInfo}`)
110
- }
111
- }
112
- } catch {
113
- // 忽略选择器异常
114
- }
115
- }
116
-
117
- if (dialogs.length === 0) return ''
118
- return `\n[页面弹窗检测] 检测到 ${dialogs.length} 个模态弹窗,请优先处理:\n${dialogs.map((d, i) => `${i + 1}. ${d}`).join('\n')}\n`
119
- }
120
-
121
- // ─── 辅助:检测页面可见的表单校验错误 ──────────────────────────────────
122
- // 操作后自动扫描页面中的校验错误提示,提取文本并提醒 AI,
123
- // 避免 AI 卡住时不知道是因为有校验错误未处理
124
- export function detectValidationErrors(): string {
125
- const seen = new Set<Element>()
126
- const errors: string[] = []
127
- // 校验错误选择器:ARIA 标准 + 主流 UI 框架(可配置)
128
- const selectors = (window.__webmcpcli_errorSelectors ?? DEFAULT_ERROR_SELECTORS)
129
-
130
- for (const selector of selectors) {
131
- try {
132
- for (const el of deepQuerySelectorAll(selector)) {
133
- if (seen.has(el)) continue
134
- // 跳过嵌套在已收集的错误元素内的子元素,避免重复
135
- if (Array.from(seen).some(s => s.contains(el))) continue
136
-
137
- const rect = el.getBoundingClientRect()
138
- if (rect.width < 1 || rect.height < 1) continue
139
- const style = window.getComputedStyle(el as HTMLElement)
140
- if (style.display === 'none' || style.visibility === 'hidden') continue
141
-
142
- const text = (el.textContent || '').trim().replace(/\s+/g, ' ')
143
- if (text.length > 2 && text.length < 200) {
144
- seen.add(el)
145
- errors.push(text)
146
- }
147
- }
148
- } catch {
149
- // 忽略选择器异常
150
- }
151
- }
152
-
153
- if (errors.length === 0) return ''
154
- return `\n[校验提示] 检测到 ${errors.length} 个表单校验错误,请先修复后再继续:\n${errors.map((e, i) => `${i + 1}. ${e}`).join('\n')}\n`
155
- }
@@ -1,58 +0,0 @@
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/remoter/QrCode.ts DELETED
@@ -1,54 +0,0 @@
1
- import QRCodePck from 'qrcode'
2
-
3
- /** QrCode 类的配置信息 */
4
- export type QrCodeOption = ConstructorParameters<typeof QrCode>[1]
5
-
6
- /**
7
- * 二维码工具类,根据传入的value,生成相应的二维码,并输出到 <canvas> 或 <img>上。
8
- * @example
9
- * const qr= new QrCode('https://www.baidu.com', { size: 100 })
10
- *
11
- * qr.toCanvas(canvasDom)
12
- * qr.toImage(imgDom)
13
- */
14
- export class QrCode {
15
- private value: string
16
- private size: number
17
- private margin: number
18
- private color: string
19
- private bgColor: string
20
-
21
- constructor(value: string, { size = 200, margin = 4, color = '#000', bgColor = '#fff' }) {
22
- this.value = value
23
- this.size = size
24
- this.margin = margin
25
- this.color = color
26
- this.bgColor = bgColor
27
- }
28
-
29
- get qrCodeOption() {
30
- return {
31
- width: this.size,
32
- margin: this.margin,
33
- color: {
34
- dark: this.color, // 前景色
35
- light: this.bgColor // 背景色
36
- }
37
- }
38
- }
39
-
40
- /** 生成二维码的 Data URL(base64 图片) */
41
- async toDataURL(): Promise<string> {
42
- return QRCodePck.toDataURL(this.value, this.qrCodeOption)
43
- }
44
-
45
- /** 渲染二维码到指定的 canvas 元素 */
46
- async toCanvas(canvas: HTMLCanvasElement): Promise<void> {
47
- return QRCodePck.toCanvas(canvas, this.value, this.qrCodeOption)
48
- }
49
-
50
- /** 渲染二维码到指定的 img 元素 */
51
- async toImage(img: HTMLImageElement): Promise<void> {
52
- img.src = await this.toDataURL()
53
- }
54
- }