@agentrhq/webcmd 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +278 -20
- package/cli-manifest.json +16247 -34913
- package/clis/_atlassian/shared.js +1 -1
- package/clis/booking/search.js +4 -4
- package/clis/chatgpt/ask.js +2 -2
- package/clis/chatgpt/utils.js +41 -42
- package/clis/chatgpt/utils.test.js +23 -23
- package/clis/chatgpt-app/ax.js +5 -5
- package/clis/chatgpt-app/ax.test.js +8 -8
- package/clis/chatgpt-app/new.js +2 -2
- package/clis/codex/sidebar.js +1 -1
- package/clis/codex/sidebar.test.js +12 -12
- package/clis/coingecko/top.js +3 -3
- package/clis/dblp/dblp.test.js +1 -1
- package/clis/discord-app/search.js +1 -1
- package/clis/discord-app/utils.js +6 -6
- package/clis/facebook/__fixtures__/notifications-page.html +6 -6
- package/clis/facebook/add-friend.js +2 -2
- package/clis/facebook/feed.js +18 -18
- package/clis/facebook/friends.js +4 -4
- package/clis/facebook/groups.js +3 -3
- package/clis/facebook/join-group.js +2 -2
- package/clis/facebook/marketplace-inbox.js +3 -3
- package/clis/facebook/marketplace-listings.js +1 -1
- package/clis/facebook/notifications.js +14 -15
- package/clis/facebook/notifications.test.js +28 -29
- package/clis/gemini/ask.test.js +12 -12
- package/clis/gemini/deep-research-result.js +2 -2
- package/clis/gemini/deep-research-result.test.js +2 -2
- package/clis/gemini/deep-research.js +2 -2
- package/clis/gemini/deep-research.test.js +1 -1
- package/clis/gemini/models.js +11 -11
- package/clis/gemini/models.test.js +1 -1
- package/clis/gemini/reply-state.test.js +89 -89
- package/clis/gemini/utils.js +41 -41
- package/clis/gemini/utils.test.js +30 -30
- package/clis/geogebra/utils.js +1 -1
- package/clis/google-scholar/search.js +3 -3
- package/clis/grok/delete.js +1 -1
- package/clis/grok/export-all.js +2 -2
- package/clis/grok/export.js +2 -2
- package/clis/grok/pin.js +3 -3
- package/clis/grok/utils.js +12 -12
- package/clis/grok/utils.test.js +2 -2
- package/clis/indeed/indeed.test.js +3 -3
- package/clis/indeed/utils.js +1 -1
- package/clis/instagram/post.js +19 -19
- package/clis/instagram/post.test.js +2 -2
- package/clis/instagram/reel.js +6 -6
- package/clis/linkedin/connect.js +3 -3
- package/clis/linkedin/people-search.js +4 -4
- package/clis/linkedin/profile-experience.js +6 -6
- package/clis/linkedin/profile-experience.test.js +10 -10
- package/clis/linkedin/profile-read.js +1 -1
- package/clis/linkedin/safe-send.js +1 -1
- package/clis/linkedin/search.js +1 -1
- package/clis/linkedin/shared.js +2 -2
- package/clis/linkedin/timeline.js +5 -5
- package/clis/manus/manus.test.js +2 -2
- package/clis/medium/feed.js +3 -3
- package/clis/medium/search.js +3 -3
- package/clis/medium/user.js +3 -3
- package/clis/notebooklm/auth.js +2 -2
- package/clis/notebooklm/note-list.test.js +4 -4
- package/clis/notebooklm/notes-get.test.js +8 -8
- package/clis/notebooklm/source-fulltext.test.js +11 -11
- package/clis/notebooklm/utils.js +28 -28
- package/clis/notebooklm/utils.test.js +10 -10
- package/clis/pixiv/search.test.js +3 -3
- package/clis/qoder/quest.js +2 -2
- package/clis/reddit/home.js +2 -2
- package/clis/reddit/hot.js +1 -1
- package/clis/reddit/read.js +2 -2
- package/clis/reddit/read.test.js +1 -1
- package/clis/reddit/reply.js +2 -2
- package/clis/reddit/whoami.js +2 -2
- package/clis/reuters/article-detail.js +1 -1
- package/clis/reuters/search.js +1 -1
- package/clis/slock/attachment-upload.test.js +1 -1
- package/clis/slock/task-convert.js +1 -1
- package/clis/substack/feed.js +3 -3
- package/clis/substack/publication.js +3 -3
- package/clis/substack/search.js +4 -4
- package/clis/tiktok/comment.js +2 -2
- package/clis/tiktok/follow.js +4 -4
- package/clis/tiktok/like.js +1 -1
- package/clis/tiktok/save.js +1 -1
- package/clis/tiktok/unfollow.js +4 -4
- package/clis/tiktok/unlike.js +1 -1
- package/clis/tiktok/unsave.js +2 -2
- package/clis/tiktok/write-refactor.test.js +5 -5
- package/clis/twitter/accept.js +3 -3
- package/clis/twitter/followers.js +1 -1
- package/clis/twitter/list-remove-core.js +2 -2
- package/clis/twitter/list-tweets.test.js +3 -3
- package/clis/twitter/lists.js +6 -6
- package/clis/twitter/lists.test.js +2 -2
- package/clis/twitter/reply-dm.js +1 -1
- package/clis/twitter/shared.test.js +4 -5
- package/clis/twitter/trending.js +1 -1
- package/clis/twitter/utils.js +1 -1
- package/clis/web/read.js +1 -1
- package/clis/web/read.test.js +2 -2
- package/clis/yahoo-finance/quote.js +1 -1
- package/clis/youtube/history.js +4 -4
- package/clis/youtube/transcript-group.js +1 -1
- package/clis/youtube/transcript-group.test.js +5 -5
- package/clis/youtube/transcript.js +5 -5
- package/clis/youtube/video.js +4 -4
- package/clis/youtube/video.test.js +6 -6
- package/dist/src/adapter-shadow.d.ts +11 -0
- package/dist/src/adapter-shadow.js +72 -0
- package/dist/src/adapter-shadow.test.js +49 -0
- package/dist/src/adapter-source.d.ts +11 -0
- package/dist/src/adapter-source.js +24 -0
- package/dist/src/adapter-source.test.d.ts +1 -0
- package/dist/src/adapter-source.test.js +29 -0
- package/dist/src/brand.d.ts +9 -0
- package/dist/src/brand.js +9 -0
- package/dist/src/brand.test.d.ts +1 -0
- package/dist/src/brand.test.js +15 -0
- package/dist/src/browser/analyze.d.ts +118 -0
- package/dist/src/browser/analyze.js +405 -0
- package/dist/src/browser/analyze.test.d.ts +1 -0
- package/dist/src/browser/analyze.test.js +209 -0
- package/dist/src/browser/article-extract.d.ts +57 -0
- package/dist/src/browser/article-extract.e2e.test.d.ts +1 -0
- package/dist/src/browser/article-extract.e2e.test.js +105 -0
- package/dist/src/browser/article-extract.js +169 -0
- package/dist/src/browser/article-extract.test.d.ts +1 -0
- package/dist/src/browser/article-extract.test.js +94 -0
- package/dist/src/browser/ax-snapshot.d.ts +37 -0
- package/dist/src/browser/ax-snapshot.js +217 -0
- package/dist/src/browser/ax-snapshot.test.d.ts +1 -0
- package/dist/src/browser/ax-snapshot.test.js +91 -0
- package/dist/src/browser/base-page.d.ts +151 -0
- package/dist/src/browser/base-page.js +1060 -0
- package/dist/src/browser/base-page.test.d.ts +1 -0
- package/dist/src/browser/base-page.test.js +803 -0
- package/dist/src/browser/bridge-readiness.d.ts +14 -0
- package/dist/src/browser/bridge-readiness.js +24 -0
- package/dist/src/browser/bridge-readiness.test.d.ts +1 -0
- package/dist/src/browser/bridge-readiness.test.js +58 -0
- package/dist/src/browser/bridge.d.ts +26 -0
- package/dist/src/browser/bridge.js +58 -0
- package/dist/src/browser/cdp-click-fixture.test.d.ts +1 -0
- package/dist/src/browser/cdp-click-fixture.test.js +87 -0
- package/dist/src/browser/cdp.d.ts +46 -0
- package/dist/src/browser/cdp.js +536 -0
- package/dist/src/browser/cdp.test.d.ts +1 -0
- package/dist/src/browser/cdp.test.js +79 -0
- package/dist/src/browser/compound.d.ts +59 -0
- package/dist/src/browser/compound.js +112 -0
- package/dist/src/browser/compound.test.d.ts +1 -0
- package/dist/src/browser/compound.test.js +175 -0
- package/dist/src/browser/config.d.ts +2 -0
- package/dist/src/browser/config.js +14 -0
- package/dist/src/browser/daemon-client.d.ts +33 -0
- package/dist/src/browser/daemon-client.js +187 -0
- package/dist/src/browser/daemon-client.test.d.ts +1 -0
- package/dist/src/browser/daemon-client.test.js +411 -0
- package/dist/src/browser/daemon-lifecycle.d.ts +37 -0
- package/dist/src/browser/daemon-lifecycle.js +147 -0
- package/dist/src/browser/daemon-transport.d.ts +54 -0
- package/dist/src/browser/daemon-transport.js +68 -0
- package/dist/src/browser/daemon-version.d.ts +4 -0
- package/dist/src/browser/daemon-version.js +12 -0
- package/dist/src/browser/dom-helpers.d.ts +41 -0
- package/dist/src/browser/dom-helpers.js +239 -0
- package/dist/src/browser/dom-helpers.test.d.ts +1 -0
- package/dist/src/browser/dom-helpers.test.js +106 -0
- package/dist/src/browser/dom-snapshot.d.ts +93 -0
- package/dist/src/browser/dom-snapshot.js +894 -0
- package/dist/src/browser/dom-snapshot.test.d.ts +11 -0
- package/dist/src/browser/dom-snapshot.test.js +313 -0
- package/dist/src/browser/errors.d.ts +38 -0
- package/dist/src/browser/errors.js +90 -0
- package/dist/src/browser/errors.test.d.ts +1 -0
- package/dist/src/browser/errors.test.js +60 -0
- package/dist/src/browser/extract.d.ts +69 -0
- package/dist/src/browser/extract.js +132 -0
- package/dist/src/browser/extract.test.d.ts +1 -0
- package/dist/src/browser/extract.test.js +129 -0
- package/dist/src/browser/find.d.ts +84 -0
- package/dist/src/browser/find.js +398 -0
- package/dist/src/browser/find.test.d.ts +1 -0
- package/dist/src/browser/find.test.js +180 -0
- package/dist/src/browser/html-tree.d.ts +75 -0
- package/dist/src/browser/html-tree.js +112 -0
- package/dist/src/browser/html-tree.test.d.ts +1 -0
- package/dist/src/browser/html-tree.test.js +181 -0
- package/dist/src/browser/index.d.ts +14 -0
- package/dist/src/browser/index.js +12 -0
- package/dist/src/browser/network-cache.d.ts +49 -0
- package/dist/src/browser/network-cache.js +78 -0
- package/dist/src/browser/network-cache.test.d.ts +1 -0
- package/dist/src/browser/network-cache.test.js +75 -0
- package/dist/src/browser/network-interceptor.d.ts +11 -0
- package/dist/src/browser/network-interceptor.js +11 -0
- package/dist/src/browser/network-key.d.ts +22 -0
- package/dist/src/browser/network-key.js +66 -0
- package/dist/src/browser/network-key.test.d.ts +1 -0
- package/dist/src/browser/network-key.test.js +49 -0
- package/dist/src/browser/page.d.ts +83 -0
- package/dist/src/browser/page.js +453 -0
- package/dist/src/browser/page.test.d.ts +1 -0
- package/dist/src/browser/page.test.js +406 -0
- package/dist/src/browser/profile.d.ts +14 -0
- package/dist/src/browser/profile.js +86 -0
- package/dist/src/browser/protocol.d.ts +65 -0
- package/dist/src/browser/protocol.js +1 -0
- package/dist/src/browser/runtime/local-cloak/actions.d.ts +3 -0
- package/dist/src/browser/runtime/local-cloak/actions.js +240 -0
- package/dist/src/browser/runtime/local-cloak/downloads.d.ts +3 -0
- package/dist/src/browser/runtime/local-cloak/downloads.js +28 -0
- package/dist/src/browser/runtime/local-cloak/network.d.ts +28 -0
- package/dist/src/browser/runtime/local-cloak/network.js +120 -0
- package/dist/src/browser/runtime/local-cloak/network.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/network.test.js +124 -0
- package/dist/src/browser/runtime/local-cloak/profiles.d.ts +6 -0
- package/dist/src/browser/runtime/local-cloak/profiles.js +17 -0
- package/dist/src/browser/runtime/local-cloak/profiles.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/profiles.test.js +19 -0
- package/dist/src/browser/runtime/local-cloak/provider.d.ts +15 -0
- package/dist/src/browser/runtime/local-cloak/provider.js +27 -0
- package/dist/src/browser/runtime/local-cloak/provider.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/provider.test.js +244 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +77 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.js +280 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.test.js +92 -0
- package/dist/src/browser/runtime/provider.d.ts +9 -0
- package/dist/src/browser/runtime/provider.js +1 -0
- package/dist/src/browser/runtime/provider.test.d.ts +2 -0
- package/dist/src/browser/runtime/provider.test.js +49 -0
- package/dist/src/browser/shape-filter.d.ts +52 -0
- package/dist/src/browser/shape-filter.js +101 -0
- package/dist/src/browser/shape-filter.test.d.ts +1 -0
- package/dist/src/browser/shape-filter.test.js +101 -0
- package/dist/src/browser/shape.d.ts +23 -0
- package/dist/src/browser/shape.js +95 -0
- package/dist/src/browser/shape.test.d.ts +1 -0
- package/dist/src/browser/shape.test.js +82 -0
- package/dist/src/browser/stealth.d.ts +11 -0
- package/dist/src/browser/stealth.js +359 -0
- package/dist/src/browser/stealth.test.d.ts +1 -0
- package/dist/src/browser/stealth.test.js +134 -0
- package/dist/src/browser/tabs.d.ts +13 -0
- package/dist/src/browser/tabs.js +70 -0
- package/dist/src/browser/target-errors.d.ts +39 -0
- package/dist/src/browser/target-errors.js +45 -0
- package/dist/src/browser/target-errors.test.d.ts +1 -0
- package/dist/src/browser/target-errors.test.js +94 -0
- package/dist/src/browser/target-resolver.d.ts +158 -0
- package/dist/src/browser/target-resolver.js +570 -0
- package/dist/src/browser/target-resolver.test.d.ts +1 -0
- package/dist/src/browser/target-resolver.test.js +118 -0
- package/dist/src/browser/utils.d.ts +20 -0
- package/dist/src/browser/utils.js +64 -0
- package/dist/src/browser/utils.test.d.ts +1 -0
- package/dist/src/browser/utils.test.js +29 -0
- package/dist/src/browser/verify-fixture.d.ts +65 -0
- package/dist/src/browser/verify-fixture.js +318 -0
- package/dist/src/browser/verify-fixture.test.d.ts +1 -0
- package/dist/src/browser/verify-fixture.test.js +219 -0
- package/dist/src/browser/visual-refs.d.ts +11 -0
- package/dist/src/browser/visual-refs.js +108 -0
- package/dist/src/browser.test.d.ts +1 -0
- package/dist/src/browser.test.js +297 -0
- package/dist/src/build-manifest.d.ts +103 -0
- package/dist/src/build-manifest.js +363 -0
- package/dist/src/build-manifest.test.d.ts +1 -0
- package/dist/src/build-manifest.test.js +341 -0
- package/dist/src/capabilityRouting.d.ts +19 -0
- package/dist/src/capabilityRouting.js +56 -0
- package/dist/src/capabilityRouting.test.d.ts +1 -0
- package/dist/src/capabilityRouting.test.js +63 -0
- package/dist/src/cli-argv-preprocess.d.ts +63 -0
- package/dist/src/cli-argv-preprocess.js +303 -0
- package/dist/src/cli-argv-preprocess.test.d.ts +1 -0
- package/dist/src/cli-argv-preprocess.test.js +304 -0
- package/dist/src/cli.d.ts +79 -0
- package/dist/src/cli.js +3350 -0
- package/dist/src/cli.test.d.ts +1 -0
- package/dist/src/cli.test.js +3041 -0
- package/dist/src/commanderAdapter.d.ts +21 -0
- package/dist/src/commanderAdapter.js +208 -0
- package/dist/src/commanderAdapter.test.d.ts +1 -0
- package/dist/src/commanderAdapter.test.js +352 -0
- package/dist/src/commands/auth.d.ts +40 -0
- package/dist/src/commands/auth.js +434 -0
- package/dist/src/commands/auth.test.d.ts +1 -0
- package/dist/src/commands/auth.test.js +252 -0
- package/dist/src/commands/daemon.d.ts +9 -0
- package/dist/src/commands/daemon.js +91 -0
- package/dist/src/commands/daemon.test.d.ts +1 -0
- package/dist/src/commands/daemon.test.js +293 -0
- package/dist/src/completion-fast.d.ts +22 -0
- package/dist/src/completion-fast.js +88 -0
- package/dist/src/completion-shared.d.ts +13 -0
- package/dist/src/completion-shared.js +61 -0
- package/dist/src/completion.d.ts +21 -0
- package/dist/src/completion.js +68 -0
- package/dist/src/completion.test.d.ts +1 -0
- package/dist/src/completion.test.js +24 -0
- package/dist/src/constants.d.ts +18 -0
- package/dist/src/constants.js +41 -0
- package/dist/src/convention-audit.d.ts +50 -0
- package/dist/src/convention-audit.js +553 -0
- package/dist/src/convention-audit.test.d.ts +1 -0
- package/dist/src/convention-audit.test.js +255 -0
- package/dist/src/daemon/server.d.ts +13 -0
- package/dist/src/daemon/server.js +190 -0
- package/dist/src/daemon/server.test.d.ts +1 -0
- package/dist/src/daemon/server.test.js +184 -0
- package/dist/src/daemon-utils.d.ts +19 -0
- package/dist/src/daemon-utils.js +46 -0
- package/dist/src/daemon.d.ts +1 -0
- package/dist/src/daemon.js +27 -0
- package/dist/src/daemon.test.d.ts +1 -0
- package/dist/src/daemon.test.js +69 -0
- package/dist/src/discovery.d.ts +46 -0
- package/dist/src/discovery.js +341 -0
- package/dist/src/doctor.d.ts +39 -0
- package/dist/src/doctor.js +174 -0
- package/dist/src/doctor.test.d.ts +1 -0
- package/dist/src/doctor.test.js +309 -0
- package/dist/src/download/article-download.d.ts +72 -0
- package/dist/src/download/article-download.js +305 -0
- package/dist/src/download/article-download.test.d.ts +1 -0
- package/dist/src/download/article-download.test.js +235 -0
- package/dist/src/download/index.d.ts +71 -0
- package/dist/src/download/index.js +363 -0
- package/dist/src/download/index.test.d.ts +1 -0
- package/dist/src/download/index.test.js +173 -0
- package/dist/src/download/media-download.d.ts +49 -0
- package/dist/src/download/media-download.js +127 -0
- package/dist/src/download/media-download.test.d.ts +1 -0
- package/dist/src/download/media-download.test.js +112 -0
- package/dist/src/download/progress.d.ts +36 -0
- package/dist/src/download/progress.js +120 -0
- package/dist/src/download/progress.test.d.ts +1 -0
- package/dist/src/download/progress.test.js +36 -0
- package/dist/src/electron-apps.d.ts +31 -0
- package/dist/src/electron-apps.js +83 -0
- package/dist/src/electron-apps.test.d.ts +1 -0
- package/dist/src/electron-apps.test.js +67 -0
- package/dist/src/engine.test.d.ts +1 -0
- package/dist/src/engine.test.js +312 -0
- package/dist/src/errors.d.ts +114 -0
- package/dist/src/errors.js +174 -0
- package/dist/src/errors.test.d.ts +1 -0
- package/dist/src/errors.test.js +109 -0
- package/dist/src/execution.d.ts +24 -0
- package/dist/src/execution.js +511 -0
- package/dist/src/execution.test.d.ts +1 -0
- package/dist/src/execution.test.js +657 -0
- package/dist/src/external-clis.yaml +0 -37
- package/dist/src/external.d.ts +49 -0
- package/dist/src/external.js +211 -0
- package/dist/src/external.test.d.ts +1 -0
- package/dist/src/external.test.js +95 -0
- package/dist/src/generate-release-notes-cli.test.d.ts +1 -0
- package/dist/src/generate-release-notes-cli.test.js +140 -0
- package/dist/src/help.d.ts +88 -0
- package/dist/src/help.js +556 -0
- package/dist/src/help.test.d.ts +1 -0
- package/dist/src/help.test.js +58 -0
- package/dist/src/hooks.d.ts +46 -0
- package/dist/src/hooks.js +58 -0
- package/dist/src/hooks.test.d.ts +4 -0
- package/dist/src/hooks.test.js +92 -0
- package/dist/src/interceptor.d.ts +44 -0
- package/dist/src/interceptor.js +183 -0
- package/dist/src/interceptor.test.d.ts +4 -0
- package/dist/src/interceptor.test.js +81 -0
- package/dist/src/launcher.d.ts +41 -0
- package/dist/src/launcher.js +226 -0
- package/dist/src/launcher.test.d.ts +1 -0
- package/dist/src/launcher.test.js +153 -0
- package/dist/src/logger.d.ts +26 -0
- package/dist/src/logger.js +49 -0
- package/dist/src/main.d.ts +5 -0
- package/dist/src/main.js +177 -0
- package/dist/src/manifest-types.d.ts +43 -0
- package/dist/src/manifest-types.js +9 -0
- package/dist/src/node-network.d.ts +10 -0
- package/dist/src/node-network.js +174 -0
- package/dist/src/node-network.test.d.ts +1 -0
- package/dist/src/node-network.test.js +55 -0
- package/dist/src/observation/artifact.d.ts +16 -0
- package/dist/src/observation/artifact.js +260 -0
- package/dist/src/observation/artifact.test.d.ts +1 -0
- package/dist/src/observation/artifact.test.js +121 -0
- package/dist/src/observation/events.d.ts +89 -0
- package/dist/src/observation/events.js +1 -0
- package/dist/src/observation/index.d.ts +7 -0
- package/dist/src/observation/index.js +7 -0
- package/dist/src/observation/manager.d.ts +9 -0
- package/dist/src/observation/manager.js +27 -0
- package/dist/src/observation/manager.test.d.ts +1 -0
- package/dist/src/observation/manager.test.js +13 -0
- package/dist/src/observation/redaction.d.ts +11 -0
- package/dist/src/observation/redaction.js +81 -0
- package/dist/src/observation/redaction.test.d.ts +1 -0
- package/dist/src/observation/redaction.test.js +32 -0
- package/dist/src/observation/retention.d.ts +32 -0
- package/dist/src/observation/retention.js +160 -0
- package/dist/src/observation/retention.test.d.ts +1 -0
- package/dist/src/observation/retention.test.js +118 -0
- package/dist/src/observation/ring-buffer.d.ts +22 -0
- package/dist/src/observation/ring-buffer.js +45 -0
- package/dist/src/observation/ring-buffer.test.d.ts +1 -0
- package/dist/src/observation/ring-buffer.test.js +22 -0
- package/dist/src/observation/session.d.ts +25 -0
- package/dist/src/observation/session.js +50 -0
- package/dist/src/output.d.ts +14 -0
- package/dist/src/output.js +152 -0
- package/dist/src/output.test.d.ts +1 -0
- package/dist/src/output.test.js +53 -0
- package/dist/src/package-exports.test.d.ts +1 -0
- package/dist/src/package-exports.test.js +112 -0
- package/dist/src/package-paths.d.ts +8 -0
- package/dist/src/package-paths.js +41 -0
- package/dist/src/pipeline/executor.d.ts +11 -0
- package/dist/src/pipeline/executor.js +93 -0
- package/dist/src/pipeline/executor.test.d.ts +4 -0
- package/dist/src/pipeline/executor.test.js +182 -0
- package/dist/src/pipeline/index.d.ts +5 -0
- package/dist/src/pipeline/index.js +5 -0
- package/dist/src/pipeline/registry.d.ts +28 -0
- package/dist/src/pipeline/registry.js +55 -0
- package/dist/src/pipeline/steps/browser.d.ts +13 -0
- package/dist/src/pipeline/steps/browser.js +86 -0
- package/dist/src/pipeline/steps/download.d.ts +18 -0
- package/dist/src/pipeline/steps/download.js +252 -0
- package/dist/src/pipeline/steps/download.test.d.ts +1 -0
- package/dist/src/pipeline/steps/download.test.js +102 -0
- package/dist/src/pipeline/steps/fetch.d.ts +5 -0
- package/dist/src/pipeline/steps/fetch.js +122 -0
- package/dist/src/pipeline/steps/fetch.test.d.ts +1 -0
- package/dist/src/pipeline/steps/fetch.test.js +117 -0
- package/dist/src/pipeline/steps/intercept.d.ts +5 -0
- package/dist/src/pipeline/steps/intercept.js +50 -0
- package/dist/src/pipeline/steps/tap.d.ts +12 -0
- package/dist/src/pipeline/steps/tap.js +93 -0
- package/dist/src/pipeline/steps/transform.d.ts +9 -0
- package/dist/src/pipeline/steps/transform.js +70 -0
- package/dist/src/pipeline/template.d.ts +17 -0
- package/dist/src/pipeline/template.js +344 -0
- package/dist/src/pipeline/template.test.d.ts +4 -0
- package/dist/src/pipeline/template.test.js +197 -0
- package/dist/src/pipeline/transform.test.d.ts +4 -0
- package/dist/src/pipeline/transform.test.js +133 -0
- package/dist/src/plugin-manifest.d.ts +70 -0
- package/dist/src/plugin-manifest.js +160 -0
- package/dist/src/plugin-manifest.test.d.ts +4 -0
- package/dist/src/plugin-manifest.test.js +179 -0
- package/dist/src/plugin-scaffold.d.ts +28 -0
- package/dist/src/plugin-scaffold.js +143 -0
- package/dist/src/plugin-scaffold.test.d.ts +4 -0
- package/dist/src/plugin-scaffold.test.js +83 -0
- package/dist/src/plugin.d.ts +146 -0
- package/dist/src/plugin.js +1303 -0
- package/dist/src/plugin.test.d.ts +4 -0
- package/dist/src/plugin.test.js +1363 -0
- package/dist/src/registry-api.d.ts +13 -0
- package/dist/src/registry-api.js +10 -0
- package/dist/src/registry.d.ts +123 -0
- package/dist/src/registry.js +125 -0
- package/dist/src/registry.test.d.ts +4 -0
- package/dist/src/registry.test.js +209 -0
- package/dist/src/release-notes.d.ts +38 -0
- package/dist/src/release-notes.js +99 -0
- package/dist/src/release-notes.test.d.ts +1 -0
- package/dist/src/release-notes.test.js +61 -0
- package/dist/src/runtime-copy.test.d.ts +1 -0
- package/dist/src/runtime-copy.test.js +29 -0
- package/dist/src/runtime-detect.d.ts +31 -0
- package/dist/src/runtime-detect.js +47 -0
- package/dist/src/runtime-detect.test.d.ts +1 -0
- package/dist/src/runtime-detect.test.js +39 -0
- package/dist/src/runtime-identity.test.d.ts +1 -0
- package/dist/src/runtime-identity.test.js +18 -0
- package/dist/src/runtime.d.ts +47 -0
- package/dist/src/runtime.js +54 -0
- package/dist/src/scripts/framework.d.ts +7 -0
- package/dist/src/scripts/framework.js +25 -0
- package/dist/src/scripts/interact.d.ts +4 -0
- package/dist/src/scripts/interact.js +20 -0
- package/dist/src/scripts/store.d.ts +13 -0
- package/dist/src/scripts/store.js +48 -0
- package/dist/src/serialization.d.ts +42 -0
- package/dist/src/serialization.js +103 -0
- package/dist/src/serialization.test.d.ts +1 -0
- package/dist/src/serialization.test.js +78 -0
- package/dist/src/skills.d.ts +14 -0
- package/dist/src/skills.js +127 -0
- package/dist/src/skills.test.d.ts +1 -0
- package/dist/src/skills.test.js +71 -0
- package/dist/src/snapshotFormatter.d.ts +11 -0
- package/dist/src/snapshotFormatter.js +336 -0
- package/dist/src/snapshotFormatter.test.d.ts +7 -0
- package/dist/src/snapshotFormatter.test.js +521 -0
- package/dist/src/tui.d.ts +28 -0
- package/dist/src/tui.js +179 -0
- package/dist/src/tui.test.d.ts +1 -0
- package/dist/src/tui.test.js +19 -0
- package/dist/src/types.d.ts +236 -0
- package/dist/src/types.js +7 -0
- package/dist/src/update-check.d.ts +66 -0
- package/dist/src/update-check.js +206 -0
- package/dist/src/update-check.test.d.ts +1 -0
- package/dist/src/update-check.test.js +117 -0
- package/dist/src/utils.d.ts +57 -0
- package/dist/src/utils.js +152 -0
- package/dist/src/utils.test.d.ts +1 -0
- package/dist/src/utils.test.js +155 -0
- package/dist/src/validate.d.ts +21 -0
- package/dist/src/validate.js +130 -0
- package/dist/src/validate.test.d.ts +9 -0
- package/dist/src/validate.test.js +90 -0
- package/dist/src/verify.d.ts +26 -0
- package/dist/src/verify.js +67 -0
- package/dist/src/version.d.ts +4 -0
- package/dist/src/version.js +22 -0
- package/package.json +7 -3
- package/scripts/check-package-bin.mjs +95 -0
- package/scripts/generate-release-notes.ts +234 -0
- package/scripts/postinstall.js +1 -1
- package/scripts/silent-column-drop-baseline.json +0 -498
- package/scripts/typed-error-lint-baseline.json +0 -464
- package/skills/webcmd-adapter-author/SKILL.md +216 -213
- package/skills/webcmd-adapter-author/references/adapter-template.md +206 -399
- package/skills/webcmd-adapter-author/references/api-discovery.md +111 -220
- package/skills/webcmd-adapter-author/references/coverage-matrix.md +34 -68
- package/skills/webcmd-adapter-author/references/field-conventions.md +84 -167
- package/skills/webcmd-adapter-author/references/field-decode-playbook.md +60 -146
- package/skills/webcmd-adapter-author/references/jsdom-fixture-pattern.md +111 -178
- package/skills/webcmd-adapter-author/references/output-design.md +47 -125
- package/skills/webcmd-adapter-author/references/site-memory.md +116 -166
- package/skills/webcmd-adapter-author/references/site-recon.md +74 -78
- package/skills/webcmd-adapter-author/references/strategy-selection.md +80 -124
- package/skills/webcmd-adapter-author/references/success-rate-pitfalls.md +80 -105
- package/skills/webcmd-adapter-author/references/typed-errors.md +87 -178
- package/skills/webcmd-autofix/SKILL.md +136 -143
- package/skills/webcmd-sitemap-author/SKILL.md +58 -67
- package/skills/webcmd-sitemap-author/references/sitemap-schema.md +354 -494
- package/skills/webcmd-usage/SKILL.md +106 -97
- package/clis/12306/auth.js +0 -59
- package/clis/12306/me.js +0 -73
- package/clis/12306/orders.js +0 -96
- package/clis/12306/passengers.js +0 -90
- package/clis/12306/price.js +0 -166
- package/clis/12306/stations.js +0 -66
- package/clis/12306/train.js +0 -91
- package/clis/12306/trains.js +0 -166
- package/clis/12306/utils.js +0 -272
- package/clis/12306/utils.test.js +0 -424
- package/clis/1688/assets.js +0 -205
- package/clis/1688/assets.test.js +0 -39
- package/clis/1688/auth.js +0 -46
- package/clis/1688/download.js +0 -77
- package/clis/1688/download.test.js +0 -31
- package/clis/1688/item.js +0 -188
- package/clis/1688/item.test.js +0 -67
- package/clis/1688/search.js +0 -310
- package/clis/1688/search.test.js +0 -75
- package/clis/1688/shared.js +0 -557
- package/clis/1688/shared.test.js +0 -57
- package/clis/1688/store.js +0 -227
- package/clis/1688/store.test.js +0 -62
- package/clis/1point3acres/auth.js +0 -52
- package/clis/1point3acres/digest.js +0 -35
- package/clis/1point3acres/forum.js +0 -51
- package/clis/1point3acres/forums.js +0 -44
- package/clis/1point3acres/hot.js +0 -35
- package/clis/1point3acres/latest.js +0 -35
- package/clis/1point3acres/notifications.js +0 -64
- package/clis/1point3acres/search.js +0 -71
- package/clis/1point3acres/thread.js +0 -117
- package/clis/1point3acres/user.js +0 -77
- package/clis/1point3acres/utils.js +0 -247
- package/clis/36kr/article.js +0 -66
- package/clis/36kr/article.test.js +0 -46
- package/clis/36kr/hot.js +0 -87
- package/clis/36kr/hot.test.js +0 -15
- package/clis/36kr/news.js +0 -52
- package/clis/36kr/news.test.js +0 -85
- package/clis/36kr/search.js +0 -79
- package/clis/51job/company.js +0 -126
- package/clis/51job/detail.js +0 -109
- package/clis/51job/hot.js +0 -56
- package/clis/51job/search.js +0 -80
- package/clis/51job/utils.js +0 -302
- package/clis/51job/utils.test.js +0 -69
- package/clis/aibase/news.js +0 -110
- package/clis/aibase/news.test.js +0 -59
- package/clis/autohome/__fixtures__/catalog.html +0 -11
- package/clis/autohome/__fixtures__/koubei.json +0 -116
- package/clis/autohome/autohome.test.js +0 -115
- package/clis/autohome/brand.js +0 -108
- package/clis/autohome/score.js +0 -103
- package/clis/autohome/utils.js +0 -157
- package/clis/baidu-scholar/search.js +0 -87
- package/clis/baidu-scholar/search.test.js +0 -23
- package/clis/bilibili/auth.js +0 -36
- package/clis/bilibili/comment.js +0 -107
- package/clis/bilibili/comment.test.js +0 -153
- package/clis/bilibili/comments.js +0 -136
- package/clis/bilibili/comments.test.js +0 -142
- package/clis/bilibili/download.js +0 -178
- package/clis/bilibili/download.test.js +0 -173
- package/clis/bilibili/dynamic.js +0 -34
- package/clis/bilibili/dynamic.test.js +0 -68
- package/clis/bilibili/favorite.js +0 -47
- package/clis/bilibili/feed.js +0 -220
- package/clis/bilibili/follow.js +0 -140
- package/clis/bilibili/follow.test.js +0 -203
- package/clis/bilibili/following.js +0 -44
- package/clis/bilibili/history.js +0 -45
- package/clis/bilibili/hot.js +0 -40
- package/clis/bilibili/hot.test.js +0 -17
- package/clis/bilibili/me.js +0 -13
- package/clis/bilibili/ranking.js +0 -25
- package/clis/bilibili/search.js +0 -24
- package/clis/bilibili/subtitle.js +0 -141
- package/clis/bilibili/subtitle.test.js +0 -240
- package/clis/bilibili/summary.js +0 -167
- package/clis/bilibili/summary.test.js +0 -210
- package/clis/bilibili/unfollow.js +0 -121
- package/clis/bilibili/user-videos.js +0 -39
- package/clis/bilibili/utils.js +0 -273
- package/clis/bilibili/utils.test.js +0 -97
- package/clis/bilibili/video.js +0 -155
- package/clis/bilibili/video.test.js +0 -308
- package/clis/boss/auth.js +0 -47
- package/clis/boss/batchgreet.js +0 -61
- package/clis/boss/chatlist.js +0 -116
- package/clis/boss/chatlist.test.js +0 -211
- package/clis/boss/chatmsg.js +0 -117
- package/clis/boss/chatmsg.test.js +0 -230
- package/clis/boss/detail.js +0 -63
- package/clis/boss/exchange.js +0 -46
- package/clis/boss/greet.js +0 -49
- package/clis/boss/invite.js +0 -64
- package/clis/boss/joblist.js +0 -31
- package/clis/boss/mark.js +0 -70
- package/clis/boss/recommend.js +0 -45
- package/clis/boss/resume.js +0 -150
- package/clis/boss/search.js +0 -197
- package/clis/boss/search.test.js +0 -78
- package/clis/boss/send.js +0 -44
- package/clis/boss/stats.js +0 -66
- package/clis/boss/utils.js +0 -468
- package/clis/boss/utils.test.js +0 -34
- package/clis/chaoxing/assignments.js +0 -76
- package/clis/chaoxing/auth.js +0 -54
- package/clis/chaoxing/exams.js +0 -75
- package/clis/chaoxing/utils.js +0 -223
- package/clis/chaoxing/utils.test.js +0 -45
- package/clis/cnki/search.js +0 -61
- package/clis/cnki/search.test.js +0 -18
- package/clis/ctrip/auth.js +0 -50
- package/clis/ctrip/ctrip.test.js +0 -719
- package/clis/ctrip/flight.js +0 -136
- package/clis/ctrip/hotel-search.js +0 -132
- package/clis/ctrip/hotel-suggest.js +0 -45
- package/clis/ctrip/search.js +0 -41
- package/clis/ctrip/utils.js +0 -473
- package/clis/deepseek/ask.js +0 -158
- package/clis/deepseek/ask.test.js +0 -399
- package/clis/deepseek/auth.js +0 -54
- package/clis/deepseek/detail.js +0 -46
- package/clis/deepseek/detail.test.js +0 -81
- package/clis/deepseek/history.js +0 -27
- package/clis/deepseek/new.js +0 -33
- package/clis/deepseek/read.js +0 -25
- package/clis/deepseek/send.js +0 -140
- package/clis/deepseek/send.test.js +0 -107
- package/clis/deepseek/status.js +0 -26
- package/clis/deepseek/utils.js +0 -487
- package/clis/deepseek/utils.test.js +0 -370
- package/clis/dianping/__fixtures__/search.html +0 -168
- package/clis/dianping/__fixtures__/shop.html +0 -6
- package/clis/dianping/auth.js +0 -49
- package/clis/dianping/cityResolver.js +0 -185
- package/clis/dianping/dianping.test.js +0 -578
- package/clis/dianping/search.js +0 -157
- package/clis/dianping/shop.js +0 -173
- package/clis/dianping/utils.js +0 -157
- package/clis/dongchedi/__fixtures__/search.json +0 -60
- package/clis/dongchedi/__fixtures__/series-detail.json +0 -911
- package/clis/dongchedi/__fixtures__/series-score.json +0 -1396
- package/clis/dongchedi/dongchedi.test.js +0 -191
- package/clis/dongchedi/koubei.js +0 -85
- package/clis/dongchedi/models.js +0 -91
- package/clis/dongchedi/score.js +0 -83
- package/clis/dongchedi/search.js +0 -83
- package/clis/dongchedi/series.js +0 -87
- package/clis/dongchedi/specs.js +0 -115
- package/clis/dongchedi/utils.js +0 -180
- package/clis/douban/auth.js +0 -50
- package/clis/douban/book-hot.js +0 -15
- package/clis/douban/download.js +0 -68
- package/clis/douban/download.test.js +0 -170
- package/clis/douban/marks.js +0 -116
- package/clis/douban/movie-hot.js +0 -15
- package/clis/douban/movie-hot.test.js +0 -14
- package/clis/douban/photos.js +0 -35
- package/clis/douban/reviews.js +0 -107
- package/clis/douban/search.js +0 -18
- package/clis/douban/search.test.js +0 -11
- package/clis/douban/subject.js +0 -46
- package/clis/douban/subject.test.js +0 -11
- package/clis/douban/top250.js +0 -68
- package/clis/douban/utils.js +0 -657
- package/clis/douban/utils.test.js +0 -488
- package/clis/doubao/ask.js +0 -40
- package/clis/doubao/auth.js +0 -66
- package/clis/doubao/detail.js +0 -35
- package/clis/doubao/detail.test.js +0 -42
- package/clis/doubao/history.js +0 -30
- package/clis/doubao/history.test.js +0 -37
- package/clis/doubao/meeting-summary.js +0 -41
- package/clis/doubao/meeting-transcript.js +0 -38
- package/clis/doubao/new.js +0 -22
- package/clis/doubao/read.js +0 -21
- package/clis/doubao/send.js +0 -24
- package/clis/doubao/status.js +0 -26
- package/clis/doubao/utils.js +0 -1156
- package/clis/doubao/utils.test.js +0 -396
- package/clis/doubao-app/ask.js +0 -54
- package/clis/doubao-app/dump.js +0 -25
- package/clis/doubao-app/new.js +0 -21
- package/clis/doubao-app/read.js +0 -19
- package/clis/doubao-app/screenshot.js +0 -19
- package/clis/doubao-app/send.js +0 -28
- package/clis/doubao-app/status.js +0 -17
- package/clis/doubao-app/utils.js +0 -110
- package/clis/douyin/_shared/browser-fetch.js +0 -66
- package/clis/douyin/_shared/browser-fetch.test.js +0 -64
- package/clis/douyin/_shared/creation-id.js +0 -5
- package/clis/douyin/_shared/creation-id.test.js +0 -22
- package/clis/douyin/_shared/evaluate-result.js +0 -16
- package/clis/douyin/_shared/imagex-upload.js +0 -53
- package/clis/douyin/_shared/imagex-upload.test.js +0 -87
- package/clis/douyin/_shared/public-api.js +0 -29
- package/clis/douyin/_shared/sts2.js +0 -21
- package/clis/douyin/_shared/sts2.test.js +0 -27
- package/clis/douyin/_shared/text-extra.js +0 -15
- package/clis/douyin/_shared/text-extra.test.js +0 -37
- package/clis/douyin/_shared/timing.js +0 -22
- package/clis/douyin/_shared/timing.test.js +0 -28
- package/clis/douyin/_shared/tos-upload-short-read.test.js +0 -83
- package/clis/douyin/_shared/tos-upload.js +0 -331
- package/clis/douyin/_shared/tos-upload.test.js +0 -229
- package/clis/douyin/_shared/transcode.js +0 -45
- package/clis/douyin/_shared/transcode.test.js +0 -91
- package/clis/douyin/_shared/vod-upload.js +0 -212
- package/clis/douyin/_shared/vod-upload.test.js +0 -38
- package/clis/douyin/activities.js +0 -23
- package/clis/douyin/activities.test.js +0 -55
- package/clis/douyin/auth.js +0 -39
- package/clis/douyin/collections.js +0 -23
- package/clis/douyin/collections.test.js +0 -45
- package/clis/douyin/delete.js +0 -152
- package/clis/douyin/delete.test.js +0 -100
- package/clis/douyin/draft.js +0 -355
- package/clis/douyin/draft.test.js +0 -335
- package/clis/douyin/drafts.js +0 -24
- package/clis/douyin/drafts.test.js +0 -11
- package/clis/douyin/hashtag.js +0 -114
- package/clis/douyin/hashtag.test.js +0 -171
- package/clis/douyin/location.js +0 -25
- package/clis/douyin/location.test.js +0 -23
- package/clis/douyin/profile.js +0 -29
- package/clis/douyin/profile.test.js +0 -46
- package/clis/douyin/publish-upload-id.test.js +0 -206
- package/clis/douyin/publish.js +0 -341
- package/clis/douyin/publish.test.js +0 -38
- package/clis/douyin/search.js +0 -308
- package/clis/douyin/search.test.js +0 -307
- package/clis/douyin/stats.js +0 -28
- package/clis/douyin/stats.test.js +0 -22
- package/clis/douyin/update.js +0 -32
- package/clis/douyin/update.test.js +0 -11
- package/clis/douyin/user-videos.js +0 -82
- package/clis/douyin/user-videos.test.js +0 -151
- package/clis/douyin/videos.js +0 -52
- package/clis/douyin/videos.test.js +0 -54
- package/clis/eastmoney/_secid.js +0 -78
- package/clis/eastmoney/announcement.js +0 -53
- package/clis/eastmoney/convertible.js +0 -74
- package/clis/eastmoney/etf.js +0 -66
- package/clis/eastmoney/holders.js +0 -79
- package/clis/eastmoney/hot-rank.js +0 -51
- package/clis/eastmoney/hot-rank.test.js +0 -59
- package/clis/eastmoney/index-board.js +0 -97
- package/clis/eastmoney/kline.js +0 -88
- package/clis/eastmoney/kuaixun.js +0 -55
- package/clis/eastmoney/longhu.js +0 -68
- package/clis/eastmoney/money-flow.js +0 -79
- package/clis/eastmoney/northbound.js +0 -58
- package/clis/eastmoney/quote.js +0 -108
- package/clis/eastmoney/rank.js +0 -95
- package/clis/eastmoney/sectors.js +0 -77
- package/clis/flomo/auth.js +0 -55
- package/clis/flomo/memos.js +0 -228
- package/clis/flomo/memos.test.js +0 -144
- package/clis/gitee/auth.js +0 -41
- package/clis/gitee/index.js +0 -3
- package/clis/gitee/search.js +0 -137
- package/clis/gitee/search.test.js +0 -65
- package/clis/gitee/trending.js +0 -568
- package/clis/gitee/user.js +0 -200
- package/clis/gitee/user.test.js +0 -63
- package/clis/gov-law/commands.test.js +0 -39
- package/clis/gov-law/recent.js +0 -22
- package/clis/gov-law/search.js +0 -41
- package/clis/gov-law/shared.js +0 -51
- package/clis/gov-policy/__fixtures__/recent.html +0 -16
- package/clis/gov-policy/__fixtures__/search.html +0 -41
- package/clis/gov-policy/gov-policy.test.js +0 -224
- package/clis/gov-policy/recent.js +0 -90
- package/clis/gov-policy/search.js +0 -91
- package/clis/gov-policy/utils.js +0 -54
- package/clis/guazi/__fixtures__/detail.html +0 -7
- package/clis/guazi/__fixtures__/list.html +0 -5
- package/clis/guazi/browse.js +0 -95
- package/clis/guazi/car.js +0 -110
- package/clis/guazi/guazi.test.js +0 -126
- package/clis/guazi/utils.js +0 -133
- package/clis/huodongxing/events.js +0 -322
- package/clis/huodongxing/events.test.js +0 -296
- package/clis/hupu/__fixtures__/hot-home.html +0 -64
- package/clis/hupu/auth.js +0 -47
- package/clis/hupu/detail.js +0 -72
- package/clis/hupu/hot.js +0 -163
- package/clis/hupu/hot.test.js +0 -224
- package/clis/hupu/like.js +0 -76
- package/clis/hupu/mentions.js +0 -160
- package/clis/hupu/reply.js +0 -72
- package/clis/hupu/search.js +0 -60
- package/clis/hupu/unlike.js +0 -76
- package/clis/hupu/utils.js +0 -319
- package/clis/jd/add-cart.js +0 -72
- package/clis/jd/auth.js +0 -46
- package/clis/jd/cart.js +0 -80
- package/clis/jd/commands.test.js +0 -41
- package/clis/jd/detail.js +0 -63
- package/clis/jd/item.js +0 -730
- package/clis/jd/item.test.js +0 -354
- package/clis/jd/item.test.ts +0 -517
- package/clis/jd/reviews.js +0 -55
- package/clis/jd/search.js +0 -66
- package/clis/jianyu/auth.js +0 -62
- package/clis/jianyu/detail.js +0 -21
- package/clis/jianyu/search.js +0 -634
- package/clis/jianyu/search.test.js +0 -153
- package/clis/jianyu/shared/china-bid-search.js +0 -165
- package/clis/jianyu/shared/procurement-contract.js +0 -324
- package/clis/jianyu/shared/procurement-contract.test.js +0 -72
- package/clis/jianyu/shared/procurement-detail.js +0 -107
- package/clis/jianyu/shared/procurement-detail.test.js +0 -84
- package/clis/jike/auth.js +0 -48
- package/clis/jike/comment.js +0 -107
- package/clis/jike/create.js +0 -106
- package/clis/jike/feed.js +0 -68
- package/clis/jike/like.js +0 -61
- package/clis/jike/notifications.js +0 -169
- package/clis/jike/post.js +0 -72
- package/clis/jike/read.test.js +0 -86
- package/clis/jike/repost.js +0 -103
- package/clis/jike/search.js +0 -68
- package/clis/jike/topic.js +0 -65
- package/clis/jike/user.js +0 -65
- package/clis/jike/utils.js +0 -25
- package/clis/jimeng/auth.js +0 -46
- package/clis/jimeng/generate.js +0 -84
- package/clis/jimeng/history.js +0 -48
- package/clis/jimeng/new.js +0 -44
- package/clis/jimeng/workspaces.js +0 -42
- package/clis/juejin/hot.js +0 -37
- package/clis/juejin/juejin.test.js +0 -241
- package/clis/juejin/recommend.js +0 -61
- package/clis/juejin/utils.js +0 -199
- package/clis/ke/auth.js +0 -46
- package/clis/ke/chengjiao.js +0 -78
- package/clis/ke/ershoufang.js +0 -101
- package/clis/ke/utils.js +0 -104
- package/clis/ke/xiaoqu.js +0 -78
- package/clis/ke/zufang.js +0 -95
- package/clis/kimi/_utils.js +0 -110
- package/clis/kimi/audit-extras.js +0 -268
- package/clis/kimi/auth.js +0 -57
- package/clis/kimi/chat.js +0 -470
- package/clis/kimi/kimi.test.js +0 -187
- package/clis/kimi/storage.js +0 -169
- package/clis/kimi/ui.js +0 -314
- package/clis/kimi/usage.js +0 -144
- package/clis/linux-do/auth.js +0 -55
- package/clis/linux-do/categories.js +0 -50
- package/clis/linux-do/feed.js +0 -395
- package/clis/linux-do/feed.test.js +0 -153
- package/clis/linux-do/search.js +0 -29
- package/clis/linux-do/tags.js +0 -28
- package/clis/linux-do/topic-content.js +0 -155
- package/clis/linux-do/topic-content.test.js +0 -59
- package/clis/linux-do/topic.js +0 -53
- package/clis/linux-do/user-posts.js +0 -57
- package/clis/linux-do/user-topics.js +0 -37
- package/clis/maimai/auth.js +0 -47
- package/clis/maimai/search-talents.js +0 -192
- package/clis/maimai/search-talents.test.js +0 -29
- package/clis/mubu/doc.js +0 -41
- package/clis/mubu/docs.js +0 -44
- package/clis/mubu/notes.js +0 -245
- package/clis/mubu/recent.js +0 -28
- package/clis/mubu/search.js +0 -63
- package/clis/mubu/utils.js +0 -304
- package/clis/nowcoder/auth.js +0 -65
- package/clis/nowcoder/companies.js +0 -24
- package/clis/nowcoder/creators.js +0 -28
- package/clis/nowcoder/detail.js +0 -62
- package/clis/nowcoder/experience.js +0 -37
- package/clis/nowcoder/hot.js +0 -25
- package/clis/nowcoder/jobs.js +0 -22
- package/clis/nowcoder/notifications.js +0 -30
- package/clis/nowcoder/papers.js +0 -41
- package/clis/nowcoder/practice.js +0 -38
- package/clis/nowcoder/recommend.js +0 -31
- package/clis/nowcoder/referral.js +0 -40
- package/clis/nowcoder/salary.js +0 -41
- package/clis/nowcoder/search.js +0 -50
- package/clis/nowcoder/suggest.js +0 -34
- package/clis/nowcoder/topics.js +0 -28
- package/clis/nowcoder/trending.js +0 -26
- package/clis/ones/common.js +0 -144
- package/clis/ones/enrich-tasks.js +0 -37
- package/clis/ones/login.js +0 -81
- package/clis/ones/logout.js +0 -18
- package/clis/ones/me.js +0 -31
- package/clis/ones/my-tasks.js +0 -121
- package/clis/ones/resolve-labels.js +0 -64
- package/clis/ones/task-helpers.js +0 -212
- package/clis/ones/task-helpers.test.js +0 -12
- package/clis/ones/task.js +0 -67
- package/clis/ones/tasks.js +0 -80
- package/clis/ones/token-info.js +0 -43
- package/clis/ones/worklog.js +0 -268
- package/clis/ones/worklog.test.js +0 -20
- package/clis/powerchina/auth.js +0 -52
- package/clis/powerchina/search.js +0 -251
- package/clis/powerchina/search.test.js +0 -93
- package/clis/quark/auth.js +0 -47
- package/clis/quark/ls.js +0 -64
- package/clis/quark/mkdir.js +0 -37
- package/clis/quark/mv.js +0 -54
- package/clis/quark/rename.js +0 -27
- package/clis/quark/rm.js +0 -25
- package/clis/quark/save.js +0 -81
- package/clis/quark/share-tree.js +0 -46
- package/clis/quark/utils.js +0 -146
- package/clis/quark/utils.test.js +0 -58
- package/clis/qwen/ask.js +0 -104
- package/clis/qwen/ask.test.js +0 -36
- package/clis/qwen/auth.js +0 -56
- package/clis/qwen/detail.js +0 -62
- package/clis/qwen/history.js +0 -61
- package/clis/qwen/image.js +0 -179
- package/clis/qwen/new.js +0 -23
- package/clis/qwen/read.js +0 -41
- package/clis/qwen/send.js +0 -55
- package/clis/qwen/status.js +0 -37
- package/clis/qwen/utils.js +0 -461
- package/clis/qwen/utils.test.js +0 -128
- package/clis/rednote/auth.js +0 -52
- package/clis/rednote/comments.js +0 -85
- package/clis/rednote/download.js +0 -59
- package/clis/rednote/feed.js +0 -27
- package/clis/rednote/navigation.test.js +0 -26
- package/clis/rednote/note.js +0 -68
- package/clis/rednote/notifications.js +0 -139
- package/clis/rednote/rednote.test.js +0 -240
- package/clis/rednote/search.js +0 -107
- package/clis/rednote/user.js +0 -55
- package/clis/sinablog/article.js +0 -15
- package/clis/sinablog/hot.js +0 -15
- package/clis/sinablog/search.js +0 -52
- package/clis/sinablog/user.js +0 -16
- package/clis/sinablog/utils.js +0 -186
- package/clis/sinafinance/news.js +0 -62
- package/clis/sinafinance/rolling-news.js +0 -41
- package/clis/sinafinance/stock-rank.js +0 -66
- package/clis/sinafinance/stock.js +0 -121
- package/clis/sinafinance/stock.test.js +0 -59
- package/clis/smzdm/search.js +0 -149
- package/clis/smzdm/search.test.js +0 -114
- package/clis/taobao/add-cart.js +0 -150
- package/clis/taobao/auth.js +0 -58
- package/clis/taobao/cart.js +0 -96
- package/clis/taobao/commands.test.js +0 -41
- package/clis/taobao/detail.js +0 -71
- package/clis/taobao/reviews.js +0 -77
- package/clis/taobao/search.js +0 -97
- package/clis/tdx/hot-rank.js +0 -48
- package/clis/tdx/hot-rank.test.js +0 -59
- package/clis/ths/hot-rank.js +0 -50
- package/clis/ths/hot-rank.test.js +0 -64
- package/clis/tieba/commands.test.js +0 -79
- package/clis/tieba/hot.js +0 -48
- package/clis/tieba/posts.js +0 -86
- package/clis/tieba/read.js +0 -141
- package/clis/tieba/search.js +0 -109
- package/clis/tieba/utils.js +0 -240
- package/clis/tieba/utils.test.js +0 -290
- package/clis/toutiao/articles.js +0 -55
- package/clis/toutiao/auth.js +0 -70
- package/clis/toutiao/hot.js +0 -63
- package/clis/toutiao/toutiao.test.js +0 -378
- package/clis/toutiao/utils.js +0 -161
- package/clis/trae-cn/activity.js +0 -22
- package/clis/trae-cn/approve.js +0 -52
- package/clis/trae-cn/ask.js +0 -99
- package/clis/trae-cn/dump.js +0 -5
- package/clis/trae-cn/export.js +0 -40
- package/clis/trae-cn/model.js +0 -22
- package/clis/trae-cn/new.js +0 -63
- package/clis/trae-cn/read.js +0 -23
- package/clis/trae-cn/screenshot.js +0 -5
- package/clis/trae-cn/select-model.js +0 -25
- package/clis/trae-cn/send.js +0 -23
- package/clis/trae-cn/setup.js +0 -75
- package/clis/trae-cn/status.js +0 -27
- package/clis/trae-cn/targets.js +0 -96
- package/clis/trae-cn/trae-cn.test.js +0 -412
- package/clis/trae-cn/utils.js +0 -750
- package/clis/trae-cn/watch.js +0 -119
- package/clis/uisdc/news.js +0 -105
- package/clis/uisdc/news.test.js +0 -66
- package/clis/v2ex/auth.js +0 -44
- package/clis/v2ex/daily.js +0 -99
- package/clis/v2ex/hot.js +0 -26
- package/clis/v2ex/latest.js +0 -26
- package/clis/v2ex/me.js +0 -100
- package/clis/v2ex/member.js +0 -28
- package/clis/v2ex/node.js +0 -39
- package/clis/v2ex/nodes.js +0 -26
- package/clis/v2ex/notifications.js +0 -72
- package/clis/v2ex/replies.js +0 -27
- package/clis/v2ex/topic.js +0 -31
- package/clis/v2ex/user.js +0 -34
- package/clis/wanfang/search.js +0 -66
- package/clis/wanfang/search.test.js +0 -23
- package/clis/wechat-channels/auth.js +0 -62
- package/clis/wechat-channels/publish.js +0 -732
- package/clis/wechat-channels/publish.test.js +0 -144
- package/clis/weibo/auth.js +0 -53
- package/clis/weibo/comments.js +0 -53
- package/clis/weibo/delete.js +0 -172
- package/clis/weibo/delete.test.js +0 -94
- package/clis/weibo/envelope.test.js +0 -85
- package/clis/weibo/favorites.js +0 -170
- package/clis/weibo/favorites.test.js +0 -114
- package/clis/weibo/feed.js +0 -69
- package/clis/weibo/hot.js +0 -39
- package/clis/weibo/me.js +0 -75
- package/clis/weibo/post.js +0 -75
- package/clis/weibo/publish.js +0 -306
- package/clis/weibo/publish.test.js +0 -192
- package/clis/weibo/search.js +0 -80
- package/clis/weibo/user-posts.js +0 -234
- package/clis/weibo/user-posts.test.js +0 -92
- package/clis/weibo/user.js +0 -63
- package/clis/weibo/utils.js +0 -59
- package/clis/weibo/utils.test.js +0 -36
- package/clis/weixin/create-draft.js +0 -226
- package/clis/weixin/download.js +0 -371
- package/clis/weixin/download.test.js +0 -106
- package/clis/weixin/drafts.js +0 -66
- package/clis/weixin/drafts.test.js +0 -69
- package/clis/weixin/search.js +0 -157
- package/clis/weixin/search.test.js +0 -227
- package/clis/weread/ai-outline.js +0 -171
- package/clis/weread/ai-outline.test.js +0 -83
- package/clis/weread/auth.js +0 -59
- package/clis/weread/book-search.js +0 -438
- package/clis/weread/book-search.test.js +0 -242
- package/clis/weread/book.js +0 -233
- package/clis/weread/commands.test.js +0 -398
- package/clis/weread/highlights.js +0 -24
- package/clis/weread/notebooks.js +0 -22
- package/clis/weread/notes.js +0 -30
- package/clis/weread/private-api-regression.test.js +0 -369
- package/clis/weread/ranking.js +0 -29
- package/clis/weread/search-regression.test.js +0 -494
- package/clis/weread/search.js +0 -186
- package/clis/weread/shelf.js +0 -66
- package/clis/weread/utils.js +0 -321
- package/clis/weread/utils.test.js +0 -128
- package/clis/weread-official/book.js +0 -135
- package/clis/weread-official/commands.test.js +0 -385
- package/clis/weread-official/discover.js +0 -107
- package/clis/weread-official/list-apis.js +0 -95
- package/clis/weread-official/notes.js +0 -171
- package/clis/weread-official/readdata.js +0 -158
- package/clis/weread-official/review.js +0 -93
- package/clis/weread-official/search.js +0 -106
- package/clis/weread-official/shelf.js +0 -97
- package/clis/weread-official/utils.js +0 -293
- package/clis/weread-official/utils.test.js +0 -242
- package/clis/xianyu/auth.js +0 -68
- package/clis/xianyu/chat.js +0 -74
- package/clis/xianyu/chat.test.js +0 -84
- package/clis/xianyu/im.js +0 -322
- package/clis/xianyu/im.test.js +0 -253
- package/clis/xianyu/inbox.js +0 -96
- package/clis/xianyu/item.js +0 -153
- package/clis/xianyu/item.test.js +0 -56
- package/clis/xianyu/messages.js +0 -91
- package/clis/xianyu/publish.js +0 -485
- package/clis/xianyu/publish.test.js +0 -220
- package/clis/xianyu/reply.js +0 -82
- package/clis/xianyu/search.js +0 -262
- package/clis/xianyu/search.test.js +0 -104
- package/clis/xianyu/utils.js +0 -8
- package/clis/xiaoe/auth.js +0 -55
- package/clis/xiaoe/catalog.js +0 -227
- package/clis/xiaoe/content.js +0 -175
- package/clis/xiaoe/courses.js +0 -127
- package/clis/xiaoe/detail.js +0 -36
- package/clis/xiaoe/play-url.js +0 -121
- package/clis/xiaoe/xiaoe.test.js +0 -486
- package/clis/xiaohongshu/ask.js +0 -426
- package/clis/xiaohongshu/ask.test.js +0 -271
- package/clis/xiaohongshu/auth.js +0 -53
- package/clis/xiaohongshu/collection-helpers.js +0 -283
- package/clis/xiaohongshu/collection-helpers.test.js +0 -125
- package/clis/xiaohongshu/comments.js +0 -228
- package/clis/xiaohongshu/comments.test.js +0 -320
- package/clis/xiaohongshu/creator-note-detail.js +0 -482
- package/clis/xiaohongshu/creator-note-detail.test.js +0 -451
- package/clis/xiaohongshu/creator-notes-summary.js +0 -98
- package/clis/xiaohongshu/creator-notes-summary.test.js +0 -94
- package/clis/xiaohongshu/creator-notes.js +0 -479
- package/clis/xiaohongshu/creator-notes.test.js +0 -281
- package/clis/xiaohongshu/creator-profile.js +0 -55
- package/clis/xiaohongshu/creator-stats.js +0 -76
- package/clis/xiaohongshu/creator-stats.test.js +0 -24
- package/clis/xiaohongshu/delete-note.js +0 -260
- package/clis/xiaohongshu/delete-note.test.js +0 -172
- package/clis/xiaohongshu/download.js +0 -249
- package/clis/xiaohongshu/download.test.js +0 -339
- package/clis/xiaohongshu/draft-clear.js +0 -91
- package/clis/xiaohongshu/draft-delete.js +0 -103
- package/clis/xiaohongshu/draft-open.js +0 -43
- package/clis/xiaohongshu/draft-utils.js +0 -142
- package/clis/xiaohongshu/drafts.js +0 -28
- package/clis/xiaohongshu/drafts.test.js +0 -172
- package/clis/xiaohongshu/feed.js +0 -163
- package/clis/xiaohongshu/feed.test.js +0 -126
- package/clis/xiaohongshu/follow.js +0 -226
- package/clis/xiaohongshu/follow.test.js +0 -211
- package/clis/xiaohongshu/liked.js +0 -29
- package/clis/xiaohongshu/liked.test.js +0 -82
- package/clis/xiaohongshu/navigation.test.js +0 -38
- package/clis/xiaohongshu/note-helpers.js +0 -69
- package/clis/xiaohongshu/note.js +0 -104
- package/clis/xiaohongshu/note.test.js +0 -249
- package/clis/xiaohongshu/notifications.js +0 -46
- package/clis/xiaohongshu/publish.js +0 -1423
- package/clis/xiaohongshu/publish.test.js +0 -1141
- package/clis/xiaohongshu/saved.js +0 -29
- package/clis/xiaohongshu/saved.test.js +0 -143
- package/clis/xiaohongshu/search.js +0 -330
- package/clis/xiaohongshu/search.test.js +0 -325
- package/clis/xiaohongshu/unfollow.js +0 -285
- package/clis/xiaohongshu/user-helpers.js +0 -78
- package/clis/xiaohongshu/user-helpers.test.js +0 -160
- package/clis/xiaohongshu/user.js +0 -140
- package/clis/xiaohongshu/user.test.js +0 -141
- package/clis/xiaoyuzhou/auth.js +0 -303
- package/clis/xiaoyuzhou/auth.test.js +0 -124
- package/clis/xiaoyuzhou/download.js +0 -54
- package/clis/xiaoyuzhou/download.test.js +0 -135
- package/clis/xiaoyuzhou/episode.js +0 -34
- package/clis/xiaoyuzhou/podcast-episodes.js +0 -41
- package/clis/xiaoyuzhou/podcast-episodes.test.js +0 -78
- package/clis/xiaoyuzhou/podcast.js +0 -33
- package/clis/xiaoyuzhou/transcript.js +0 -77
- package/clis/xiaoyuzhou/transcript.test.js +0 -195
- package/clis/xiaoyuzhou/utils.js +0 -15
- package/clis/xiaoyuzhou/utils.test.js +0 -39
- package/clis/xueqiu/auth.js +0 -63
- package/clis/xueqiu/comments.js +0 -355
- package/clis/xueqiu/comments.test.js +0 -696
- package/clis/xueqiu/danjuan-utils.js +0 -126
- package/clis/xueqiu/danjuan-utils.test.js +0 -41
- package/clis/xueqiu/earnings-date.js +0 -45
- package/clis/xueqiu/feed.js +0 -39
- package/clis/xueqiu/fund-holdings.js +0 -29
- package/clis/xueqiu/fund-snapshot.js +0 -26
- package/clis/xueqiu/groups.js +0 -23
- package/clis/xueqiu/hot-stock.js +0 -32
- package/clis/xueqiu/hot.js +0 -37
- package/clis/xueqiu/kline.js +0 -44
- package/clis/xueqiu/search.js +0 -37
- package/clis/xueqiu/stock.js +0 -65
- package/clis/xueqiu/utils.js +0 -48
- package/clis/xueqiu/utils.test.js +0 -26
- package/clis/xueqiu/watchlist.js +0 -37
- package/clis/youdao/note.js +0 -258
- package/clis/youdao/note.test.js +0 -99
- package/clis/yuanbao/ask.js +0 -362
- package/clis/yuanbao/ask.test.js +0 -124
- package/clis/yuanbao/auth.js +0 -59
- package/clis/yuanbao/detail.js +0 -65
- package/clis/yuanbao/history.js +0 -51
- package/clis/yuanbao/new.js +0 -72
- package/clis/yuanbao/new.test.js +0 -30
- package/clis/yuanbao/read.js +0 -38
- package/clis/yuanbao/send.js +0 -57
- package/clis/yuanbao/shared.js +0 -341
- package/clis/yuanbao/shared.test.js +0 -80
- package/clis/yuanbao/status.js +0 -44
- package/clis/zhihu/answer-comments.js +0 -280
- package/clis/zhihu/answer-comments.test.js +0 -287
- package/clis/zhihu/answer-detail.js +0 -216
- package/clis/zhihu/answer-detail.test.js +0 -338
- package/clis/zhihu/answer.js +0 -54
- package/clis/zhihu/answer.test.js +0 -54
- package/clis/zhihu/auth.js +0 -59
- package/clis/zhihu/collection.js +0 -199
- package/clis/zhihu/collection.test.js +0 -337
- package/clis/zhihu/collections.js +0 -128
- package/clis/zhihu/collections.test.js +0 -182
- package/clis/zhihu/comment.js +0 -55
- package/clis/zhihu/comment.test.js +0 -50
- package/clis/zhihu/download.js +0 -80
- package/clis/zhihu/download.test.js +0 -12
- package/clis/zhihu/favorite.js +0 -87
- package/clis/zhihu/favorite.test.js +0 -59
- package/clis/zhihu/follow.js +0 -50
- package/clis/zhihu/follow.test.js +0 -42
- package/clis/zhihu/followers.js +0 -40
- package/clis/zhihu/followers.test.js +0 -42
- package/clis/zhihu/following.js +0 -40
- package/clis/zhihu/following.test.js +0 -44
- package/clis/zhihu/hot.js +0 -44
- package/clis/zhihu/like.js +0 -47
- package/clis/zhihu/like.test.js +0 -41
- package/clis/zhihu/paginate.js +0 -128
- package/clis/zhihu/pins.js +0 -41
- package/clis/zhihu/pins.test.js +0 -44
- package/clis/zhihu/question.js +0 -113
- package/clis/zhihu/question.test.js +0 -251
- package/clis/zhihu/recommend.js +0 -103
- package/clis/zhihu/recommend.test.js +0 -143
- package/clis/zhihu/search.js +0 -206
- package/clis/zhihu/search.test.js +0 -198
- package/clis/zhihu/target.js +0 -91
- package/clis/zhihu/target.test.js +0 -77
- package/clis/zhihu/text.js +0 -29
- package/clis/zhihu/text.test.js +0 -24
- package/clis/zhihu/user-answers.js +0 -41
- package/clis/zhihu/user-answers.test.js +0 -69
- package/clis/zhihu/user-arg.js +0 -34
- package/clis/zhihu/user-articles.js +0 -40
- package/clis/zhihu/user-articles.test.js +0 -44
- package/clis/zhihu/user.js +0 -59
- package/clis/zhihu/user.test.js +0 -73
- package/clis/zhihu/write-shared.js +0 -228
- package/clis/zhihu/write-shared.test.js +0 -176
- package/clis/zsxq/auth.js +0 -68
- package/clis/zsxq/dynamics.js +0 -48
- package/clis/zsxq/groups.js +0 -33
- package/clis/zsxq/search.js +0 -44
- package/clis/zsxq/search.test.js +0 -24
- package/clis/zsxq/topic.js +0 -50
- package/clis/zsxq/topic.test.js +0 -30
- package/clis/zsxq/topics.js +0 -26
- package/clis/zsxq/topics.test.js +0 -24
- package/clis/zsxq/utils.js +0 -233
- package/clis/zsxq/utils.test.js +0 -31
- package/skills/webcmd-adapter-author/references/site-memory/bilibili.md +0 -70
- package/skills/webcmd-adapter-author/references/site-memory/eastmoney.md +0 -70
- package/skills/webcmd-adapter-author/references/site-memory/tonghuashun.md +0 -51
- package/skills/webcmd-adapter-author/references/site-memory/xueqiu.md +0 -58
- /package/{clis/douyin/_shared/types.js → dist/src/adapter-shadow.test.d.ts} +0 -0
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified target resolver for browser actions.
|
|
3
|
+
*
|
|
4
|
+
* Resolution pipeline:
|
|
5
|
+
*
|
|
6
|
+
* 1. Input classification: all-digit → numeric ref path, otherwise → CSS path.
|
|
7
|
+
* The CSS path passes the raw string to `querySelectorAll` and lets the
|
|
8
|
+
* browser parser decide what's valid. No frontend regex whitelist — the
|
|
9
|
+
* goal is that any selector accepted by `browser find --css` is accepted
|
|
10
|
+
* by the same selector on `get/click/type/select`.
|
|
11
|
+
* 2. Ref path: cascading match levels (see below), using data-webcmd-ref
|
|
12
|
+
* plus the fingerprint map populated by snapshot + find.
|
|
13
|
+
* 3. CSS path: querySelectorAll + match-count policy (see ResolveOptions)
|
|
14
|
+
* 4. Structured errors:
|
|
15
|
+
* - numeric: not_found / stale_ref
|
|
16
|
+
* - CSS: invalid_selector / selector_not_found / selector_ambiguous
|
|
17
|
+
* / selector_nth_out_of_range
|
|
18
|
+
*
|
|
19
|
+
* All JS is generated as strings for page.evaluate() — runs in the browser.
|
|
20
|
+
*
|
|
21
|
+
* ── Cascading stale-ref (browser-use style) ──────────────────────────
|
|
22
|
+
* Strict equality on the fingerprint rejected too many live pages — SPA
|
|
23
|
+
* re-renders swap text / role while keeping id + testId. The resolver
|
|
24
|
+
* now walks three tiers before giving up:
|
|
25
|
+
*
|
|
26
|
+
* 1. EXACT — tag + strong id (id or testId) agree, ≤1 soft mismatch
|
|
27
|
+
* 2. STABLE — tag + strong id agree, soft signals drifted (aria-label,
|
|
28
|
+
* role, text) — agent gets a warning but the action
|
|
29
|
+
* proceeds so dynamic pages don't stall
|
|
30
|
+
* 3. REIDENTIFIED — original ref either missing from the DOM or fully
|
|
31
|
+
* mismatched, but the fingerprint uniquely identifies
|
|
32
|
+
* a single other live element via id / testId /
|
|
33
|
+
* aria-label. Re-tag that element with the old ref and
|
|
34
|
+
* surface match_level so the caller knows we swapped.
|
|
35
|
+
*
|
|
36
|
+
* Only when all three fail do we emit `stale_ref`. Every success envelope
|
|
37
|
+
* carries `match_level` so downstream CLIs can surface the weakest tier
|
|
38
|
+
* a caller actually traversed.
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Generate JS that resolves a target to a single DOM element.
|
|
42
|
+
*
|
|
43
|
+
* Returns a JS expression that evaluates to:
|
|
44
|
+
* { ok: true, matches_n, match_level } — success (el stored in `__resolved`)
|
|
45
|
+
* { ok: false, code, message, hint, candidates, matches_n? } — structured error
|
|
46
|
+
*
|
|
47
|
+
* `match_level` is always set on success:
|
|
48
|
+
* - CSS path → 'exact'
|
|
49
|
+
* - numeric ref path → whichever tier matched ('exact' / 'stable' / 'reidentified')
|
|
50
|
+
*
|
|
51
|
+
* The resolved element is stored in `window.__resolved` for downstream helpers.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveTargetJs(ref, opts = {}) {
|
|
54
|
+
const safeRef = JSON.stringify(ref);
|
|
55
|
+
const nthJs = opts.nth !== undefined ? String(opts.nth | 0) : 'null';
|
|
56
|
+
const firstOnMulti = opts.firstOnMulti === true ? 'true' : 'false';
|
|
57
|
+
return `
|
|
58
|
+
(() => {
|
|
59
|
+
const ref = ${safeRef};
|
|
60
|
+
const nth = ${nthJs};
|
|
61
|
+
const firstOnMulti = ${firstOnMulti};
|
|
62
|
+
const identity = window.__webcmd_ref_identity || {};
|
|
63
|
+
|
|
64
|
+
// ── Classify input ──
|
|
65
|
+
// Numeric = snapshot ref. Everything else is handed to querySelectorAll
|
|
66
|
+
// and whatever the browser parser accepts is a valid selector. No regex
|
|
67
|
+
// shortlist up front: \`find --css\` and \`get/click/type/select\` must agree
|
|
68
|
+
// on the same selector surface (see contract note at the top of this file).
|
|
69
|
+
const isNumeric = /^\\d+$/.test(ref);
|
|
70
|
+
|
|
71
|
+
if (isNumeric) {
|
|
72
|
+
// ── Ref path (cascading match levels) ──
|
|
73
|
+
|
|
74
|
+
// Shared helper: compute a fingerprint off a live element, same shape
|
|
75
|
+
// snapshot + find populate into \`__webcmd_ref_identity\`. Kept inline
|
|
76
|
+
// (not imported) because this source string is compiled standalone.
|
|
77
|
+
function fingerprintOf(node) {
|
|
78
|
+
return {
|
|
79
|
+
tag: node.tagName.toLowerCase(),
|
|
80
|
+
role: node.getAttribute('role') || '',
|
|
81
|
+
text: (node.textContent || '').trim().slice(0, 30),
|
|
82
|
+
ariaLabel: node.getAttribute('aria-label') || '',
|
|
83
|
+
id: node.id || '',
|
|
84
|
+
testId: node.getAttribute('data-testid') || node.getAttribute('data-test') || '',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Classify how strongly a live element matches a stored fingerprint.
|
|
89
|
+
// Returns one of 'exact' | 'stable' | 'mismatch'.
|
|
90
|
+
//
|
|
91
|
+
// 'exact' — tag + every non-empty stored field agrees (±text prefix).
|
|
92
|
+
// 'stable' — tag agrees AND at least one strong id (id or testId) still
|
|
93
|
+
// matches; soft signals (aria-label, role, text) may have
|
|
94
|
+
// drifted. This covers SPA re-render / i18n label swaps.
|
|
95
|
+
// 'mismatch' otherwise.
|
|
96
|
+
function classifyMatch(fp, liveFp) {
|
|
97
|
+
if (fp.tag !== liveFp.tag) return 'mismatch';
|
|
98
|
+
|
|
99
|
+
const idMatch = !fp.id || fp.id === liveFp.id;
|
|
100
|
+
const testIdMatch = !fp.testId || fp.testId === liveFp.testId;
|
|
101
|
+
const roleMatch = !fp.role || fp.role === liveFp.role;
|
|
102
|
+
const ariaMatch = !fp.ariaLabel || fp.ariaLabel === liveFp.ariaLabel;
|
|
103
|
+
const textMatch = !fp.text || (
|
|
104
|
+
!!liveFp.text && (liveFp.text.startsWith(fp.text) || fp.text.startsWith(liveFp.text))
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (idMatch && testIdMatch && roleMatch && ariaMatch && textMatch) return 'exact';
|
|
108
|
+
|
|
109
|
+
// Strong id decides: if id + testId still agree and we had at least one
|
|
110
|
+
// of them, accept as stable regardless of soft-signal drift.
|
|
111
|
+
const hadStrongId = !!fp.id || !!fp.testId;
|
|
112
|
+
if (hadStrongId && idMatch && testIdMatch) return 'stable';
|
|
113
|
+
|
|
114
|
+
return 'mismatch';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Try to recover a stale ref by searching the page for a live element
|
|
118
|
+
// whose fingerprint still matches. Uniqueness is required — if two
|
|
119
|
+
// candidates match equally well, we refuse rather than silently pick
|
|
120
|
+
// the wrong one. Covers ref annotations lost to a re-mount.
|
|
121
|
+
function reidentify(fp) {
|
|
122
|
+
if (!fp) return null;
|
|
123
|
+
const candidates = [];
|
|
124
|
+
function tryAdd(el) {
|
|
125
|
+
if (el && el.nodeType === 1 && classifyMatch(fp, fingerprintOf(el)) !== 'mismatch') {
|
|
126
|
+
if (candidates.indexOf(el) === -1) candidates.push(el);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Prefer strong-id lookups. If id / testId is present and yields a
|
|
130
|
+
// unique element, that's our hit.
|
|
131
|
+
try {
|
|
132
|
+
if (fp.id) {
|
|
133
|
+
const byId = document.getElementById(fp.id);
|
|
134
|
+
if (byId) tryAdd(byId);
|
|
135
|
+
}
|
|
136
|
+
if (fp.testId) {
|
|
137
|
+
const byTestIdA = document.querySelectorAll('[data-testid="' + fp.testId.replace(/"/g, '\\\\"') + '"]');
|
|
138
|
+
for (let i = 0; i < byTestIdA.length; i++) tryAdd(byTestIdA[i]);
|
|
139
|
+
const byTestIdB = document.querySelectorAll('[data-test="' + fp.testId.replace(/"/g, '\\\\"') + '"]');
|
|
140
|
+
for (let i = 0; i < byTestIdB.length; i++) tryAdd(byTestIdB[i]);
|
|
141
|
+
}
|
|
142
|
+
// aria-label is only a useful shortlist when nothing stronger is set
|
|
143
|
+
if (candidates.length === 0 && fp.ariaLabel) {
|
|
144
|
+
const byAria = document.querySelectorAll('[aria-label="' + fp.ariaLabel.replace(/"/g, '\\\\"') + '"]');
|
|
145
|
+
for (let i = 0; i < byAria.length; i++) tryAdd(byAria[i]);
|
|
146
|
+
}
|
|
147
|
+
} catch (_) { /* bad selectors from weird fp values — skip */ }
|
|
148
|
+
return candidates.length === 1 ? candidates[0] : null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const fp = identity[ref];
|
|
152
|
+
let el = document.querySelector('[data-webcmd-ref="' + ref + '"]');
|
|
153
|
+
if (!el) el = document.querySelector('[data-ref="' + ref + '"]');
|
|
154
|
+
|
|
155
|
+
// If the ref tag is gone from the DOM, last-chance reidentify.
|
|
156
|
+
if (!el) {
|
|
157
|
+
const recovered = reidentify(fp);
|
|
158
|
+
if (recovered) {
|
|
159
|
+
try {
|
|
160
|
+
recovered.setAttribute('data-webcmd-ref', ref);
|
|
161
|
+
identity[ref] = fingerprintOf(recovered);
|
|
162
|
+
} catch (_) {}
|
|
163
|
+
window.__resolved = recovered;
|
|
164
|
+
return { ok: true, matches_n: 1, match_level: 'reidentified' };
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
code: 'not_found',
|
|
169
|
+
message: 'ref=' + ref + ' not found in DOM',
|
|
170
|
+
hint: 'The element may have been removed. Re-run \`webcmd browser state\` to get a fresh snapshot.',
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// No stored fingerprint (older page / unknown ref) — accept as exact.
|
|
175
|
+
if (!fp) {
|
|
176
|
+
window.__resolved = el;
|
|
177
|
+
return { ok: true, matches_n: 1, match_level: 'exact' };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const liveFp = fingerprintOf(el);
|
|
181
|
+
const level = classifyMatch(fp, liveFp);
|
|
182
|
+
|
|
183
|
+
if (level === 'exact' || level === 'stable') {
|
|
184
|
+
window.__resolved = el;
|
|
185
|
+
return { ok: true, matches_n: 1, match_level: level };
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Tag / strong-id mismatch — try to find the real element elsewhere
|
|
189
|
+
// before giving up. Covers e.g. a modal re-mount that discarded the
|
|
190
|
+
// data-webcmd-ref attribute on the surviving node.
|
|
191
|
+
const recovered = reidentify(fp);
|
|
192
|
+
if (recovered && recovered !== el) {
|
|
193
|
+
try {
|
|
194
|
+
el.removeAttribute('data-webcmd-ref');
|
|
195
|
+
recovered.setAttribute('data-webcmd-ref', ref);
|
|
196
|
+
identity[ref] = fingerprintOf(recovered);
|
|
197
|
+
} catch (_) {}
|
|
198
|
+
window.__resolved = recovered;
|
|
199
|
+
return { ok: true, matches_n: 1, match_level: 'reidentified' };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
ok: false,
|
|
204
|
+
code: 'stale_ref',
|
|
205
|
+
message: 'ref=' + ref + ' was <' + fp.tag + '>' + (fp.text ? '"' + fp.text + '"' : '')
|
|
206
|
+
+ ' but now points to <' + liveFp.tag + '>' + (liveFp.text ? '"' + liveFp.text.slice(0, 30) + '"' : ''),
|
|
207
|
+
hint: 'The page has changed since the last snapshot. Re-run \`webcmd browser state\` to refresh.',
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ── CSS selector path (any non-numeric input) ──
|
|
212
|
+
{
|
|
213
|
+
let matches;
|
|
214
|
+
try {
|
|
215
|
+
matches = document.querySelectorAll(ref);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
return {
|
|
218
|
+
ok: false,
|
|
219
|
+
code: 'invalid_selector',
|
|
220
|
+
message: 'Invalid CSS selector: ' + ref + ' (' + ((e && e.message) || String(e)) + ')',
|
|
221
|
+
hint: 'Check the selector syntax. Use ref numbers from snapshot for reliable targeting.',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (matches.length === 0) {
|
|
226
|
+
return {
|
|
227
|
+
ok: false,
|
|
228
|
+
code: 'selector_not_found',
|
|
229
|
+
message: 'CSS selector "' + ref + '" matched 0 elements',
|
|
230
|
+
hint: 'The element may not exist or may be hidden. Re-run \`webcmd browser state\` to check, or use \`webcmd browser find --css\` to explore candidates.',
|
|
231
|
+
matches_n: 0,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (nth !== null) {
|
|
236
|
+
if (nth < 0 || nth >= matches.length) {
|
|
237
|
+
return {
|
|
238
|
+
ok: false,
|
|
239
|
+
code: 'selector_nth_out_of_range',
|
|
240
|
+
message: 'CSS selector "' + ref + '" matched ' + matches.length + ' elements, but --nth=' + nth + ' is out of range',
|
|
241
|
+
hint: 'Use --nth between 0 and ' + (matches.length - 1) + ', or omit --nth to target the first match (read ops) or require explicit disambiguation (write ops).',
|
|
242
|
+
matches_n: matches.length,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
window.__resolved = matches[nth];
|
|
246
|
+
return { ok: true, matches_n: matches.length, match_level: 'exact' };
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (matches.length > 1 && !firstOnMulti) {
|
|
250
|
+
const candidates = [];
|
|
251
|
+
const limit = Math.min(matches.length, 5);
|
|
252
|
+
for (let i = 0; i < limit; i++) {
|
|
253
|
+
const m = matches[i];
|
|
254
|
+
const tag = m.tagName.toLowerCase();
|
|
255
|
+
const text = (m.textContent || '').trim().slice(0, 40);
|
|
256
|
+
const id = m.id ? '#' + m.id : '';
|
|
257
|
+
candidates.push('<' + tag + id + '>' + (text ? ' "' + text + '"' : ''));
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
ok: false,
|
|
261
|
+
code: 'selector_ambiguous',
|
|
262
|
+
message: 'CSS selector "' + ref + '" matched ' + matches.length + ' elements',
|
|
263
|
+
hint: 'Pass --nth <n> (0-based) to pick one, or use a more specific selector. Use \`webcmd browser find --css\` to list all candidates.',
|
|
264
|
+
candidates: candidates,
|
|
265
|
+
matches_n: matches.length,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Single match, OR multi-match with firstOnMulti (read path)
|
|
270
|
+
window.__resolved = matches[0];
|
|
271
|
+
return { ok: true, matches_n: matches.length, match_level: 'exact' };
|
|
272
|
+
}
|
|
273
|
+
})()
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Generate JS that scrolls + measures `__resolved` without clicking.
|
|
278
|
+
*
|
|
279
|
+
* Generic click prefers CDP `Input.dispatchMouseEvent`, which fires the full
|
|
280
|
+
* pointer/mouse chain that Radix/MUI/shadcn dropdowns rely on. Keep measurement
|
|
281
|
+
* separate so the CDP-primary path does not call DOM `el.click()` first.
|
|
282
|
+
*/
|
|
283
|
+
export function boundingRectResolvedJs(opts = {}) {
|
|
284
|
+
const shouldScroll = opts.skipScroll ? 'false' : 'true';
|
|
285
|
+
return `
|
|
286
|
+
(() => {
|
|
287
|
+
const el = window.__resolved;
|
|
288
|
+
if (!el) throw new Error('No resolved element');
|
|
289
|
+
if (${shouldScroll}) el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
290
|
+
const rect = el.getBoundingClientRect();
|
|
291
|
+
const w = Math.round(rect.width);
|
|
292
|
+
const h = Math.round(rect.height);
|
|
293
|
+
const x = Math.round(rect.left + rect.width / 2);
|
|
294
|
+
const y = Math.round(rect.top + rect.height / 2);
|
|
295
|
+
const visible = w > 0 && h > 0;
|
|
296
|
+
return { x, y, w, h, visible };
|
|
297
|
+
})()
|
|
298
|
+
`;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Generate JS for click that uses the unified resolver.
|
|
302
|
+
* Assumes resolveTargetJs has been called and __resolved is set.
|
|
303
|
+
*
|
|
304
|
+
* This is the JS fallback path. BasePage.click uses boundingRectResolvedJs for
|
|
305
|
+
* the CDP-primary path and only reaches this when native click is unavailable
|
|
306
|
+
* or the target has no usable rect.
|
|
307
|
+
*/
|
|
308
|
+
export function clickResolvedJs(opts = {}) {
|
|
309
|
+
const shouldScroll = opts.skipScroll ? 'false' : 'true';
|
|
310
|
+
return `
|
|
311
|
+
(() => {
|
|
312
|
+
const el = window.__resolved;
|
|
313
|
+
if (!el) throw new Error('No resolved element');
|
|
314
|
+
if (${shouldScroll}) el.scrollIntoView({ behavior: 'instant', block: 'center' });
|
|
315
|
+
const rect = el.getBoundingClientRect();
|
|
316
|
+
const x = Math.round(rect.left + rect.width / 2);
|
|
317
|
+
const y = Math.round(rect.top + rect.height / 2);
|
|
318
|
+
try {
|
|
319
|
+
el.click();
|
|
320
|
+
return { status: 'clicked', x, y, w: Math.round(rect.width), h: Math.round(rect.height) };
|
|
321
|
+
} catch (e) {
|
|
322
|
+
return { status: 'js_failed', x, y, w: Math.round(rect.width), h: Math.round(rect.height), error: e.message };
|
|
323
|
+
}
|
|
324
|
+
})()
|
|
325
|
+
`;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Generate JS for type that uses the unified resolver.
|
|
329
|
+
*/
|
|
330
|
+
export function typeResolvedJs(text) {
|
|
331
|
+
const safeText = JSON.stringify(text);
|
|
332
|
+
return `
|
|
333
|
+
(() => {
|
|
334
|
+
const el = window.__resolved;
|
|
335
|
+
if (!el) throw new Error('No resolved element');
|
|
336
|
+
el.focus();
|
|
337
|
+
if (el.isContentEditable) {
|
|
338
|
+
const sel = window.getSelection();
|
|
339
|
+
const range = document.createRange();
|
|
340
|
+
range.selectNodeContents(el);
|
|
341
|
+
sel.removeAllRanges();
|
|
342
|
+
sel.addRange(range);
|
|
343
|
+
document.execCommand('delete', false);
|
|
344
|
+
document.execCommand('insertText', false, ${safeText});
|
|
345
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
346
|
+
} else {
|
|
347
|
+
const proto = el instanceof HTMLTextAreaElement
|
|
348
|
+
? HTMLTextAreaElement.prototype
|
|
349
|
+
: HTMLInputElement.prototype;
|
|
350
|
+
const nativeSetter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;
|
|
351
|
+
if (nativeSetter) {
|
|
352
|
+
nativeSetter.call(el, ${safeText});
|
|
353
|
+
} else {
|
|
354
|
+
el.value = ${safeText};
|
|
355
|
+
}
|
|
356
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
357
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
358
|
+
}
|
|
359
|
+
return 'typed';
|
|
360
|
+
})()
|
|
361
|
+
`;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Prepare the resolved element for native CDP Input.insertText.
|
|
365
|
+
*
|
|
366
|
+
* This preserves `browser type`'s existing "replace current text" semantics:
|
|
367
|
+
* focus the editable target, select its current contents, then let CDP insert
|
|
368
|
+
* real browser text input so rich editors can update their internal state.
|
|
369
|
+
*/
|
|
370
|
+
export function prepareNativeTypeResolvedJs(opts = {}) {
|
|
371
|
+
const shouldScroll = opts.skipScroll ? 'false' : 'true';
|
|
372
|
+
const shouldFocus = opts.skipFocus ? 'false' : 'true';
|
|
373
|
+
return `
|
|
374
|
+
(() => {
|
|
375
|
+
const original = window.__resolved;
|
|
376
|
+
if (!original) throw new Error('No resolved element');
|
|
377
|
+
|
|
378
|
+
function nearestContentEditableHost(el) {
|
|
379
|
+
let current = el;
|
|
380
|
+
while (current && current.nodeType === 1) {
|
|
381
|
+
if (current.hasAttribute && current.hasAttribute('contenteditable')) return current;
|
|
382
|
+
current = current.parentElement;
|
|
383
|
+
}
|
|
384
|
+
return el.isContentEditable ? el : null;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const editableHost = original.isContentEditable ? nearestContentEditableHost(original) : null;
|
|
388
|
+
const inputTypes = new Set(['', 'text', 'search', 'url', 'tel', 'email', 'password']);
|
|
389
|
+
const isInput = original instanceof HTMLInputElement;
|
|
390
|
+
const isTextarea = original instanceof HTMLTextAreaElement;
|
|
391
|
+
const isTextControl = isTextarea || (isInput && inputTypes.has((original.getAttribute('type') || original.type || '').toLowerCase()));
|
|
392
|
+
const el = editableHost || (isTextControl ? original : null);
|
|
393
|
+
|
|
394
|
+
if (!el) {
|
|
395
|
+
return {
|
|
396
|
+
ok: false,
|
|
397
|
+
reason: 'not_editable',
|
|
398
|
+
tag: original.tagName ? original.tagName.toLowerCase() : '',
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
window.__resolved = el;
|
|
403
|
+
if (${shouldScroll}) el.scrollIntoView({ behavior: 'instant', block: 'center', inline: 'nearest' });
|
|
404
|
+
if (${shouldFocus}) {
|
|
405
|
+
try {
|
|
406
|
+
el.focus({ preventScroll: true });
|
|
407
|
+
} catch (_) {
|
|
408
|
+
el.focus();
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (editableHost) {
|
|
413
|
+
const sel = window.getSelection();
|
|
414
|
+
if (!sel) return { ok: false, reason: 'selection_unavailable', mode: 'contenteditable' };
|
|
415
|
+
const range = document.createRange();
|
|
416
|
+
range.selectNodeContents(el);
|
|
417
|
+
sel.removeAllRanges();
|
|
418
|
+
sel.addRange(range);
|
|
419
|
+
return { ok: true, mode: 'contenteditable' };
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
let selected = false;
|
|
423
|
+
try {
|
|
424
|
+
if (typeof el.setSelectionRange === 'function') {
|
|
425
|
+
el.setSelectionRange(0, String(el.value || '').length);
|
|
426
|
+
selected = true;
|
|
427
|
+
}
|
|
428
|
+
} catch (_) {}
|
|
429
|
+
try {
|
|
430
|
+
if (!selected && typeof el.select === 'function') {
|
|
431
|
+
el.select();
|
|
432
|
+
selected = true;
|
|
433
|
+
}
|
|
434
|
+
} catch (_) {}
|
|
435
|
+
|
|
436
|
+
return selected
|
|
437
|
+
? { ok: true, mode: isTextarea ? 'textarea' : 'input' }
|
|
438
|
+
: { ok: false, reason: 'selection_unavailable', mode: isTextarea ? 'textarea' : 'input' };
|
|
439
|
+
})()
|
|
440
|
+
`;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Verify the exact value/text currently held by the resolved editable target.
|
|
444
|
+
* Assumes resolveTargetJs and prepareNativeTypeResolvedJs have already set
|
|
445
|
+
* `window.__resolved` to the normalized editable host.
|
|
446
|
+
*/
|
|
447
|
+
export function verifyFilledResolvedJs(expected) {
|
|
448
|
+
const safeText = JSON.stringify(expected);
|
|
449
|
+
return `
|
|
450
|
+
(() => {
|
|
451
|
+
const el = window.__resolved;
|
|
452
|
+
if (!el) return { ok: false, reason: 'no_resolved_element' };
|
|
453
|
+
|
|
454
|
+
const tag = el.tagName ? el.tagName.toLowerCase() : '';
|
|
455
|
+
const isInput = el instanceof HTMLInputElement;
|
|
456
|
+
const isTextarea = el instanceof HTMLTextAreaElement;
|
|
457
|
+
const mode = el.isContentEditable
|
|
458
|
+
? 'contenteditable'
|
|
459
|
+
: isTextarea
|
|
460
|
+
? 'textarea'
|
|
461
|
+
: isInput
|
|
462
|
+
? 'input'
|
|
463
|
+
: '';
|
|
464
|
+
|
|
465
|
+
if (!mode) {
|
|
466
|
+
return {
|
|
467
|
+
ok: false,
|
|
468
|
+
reason: 'not_editable',
|
|
469
|
+
tag,
|
|
470
|
+
role: el.getAttribute ? (el.getAttribute('role') || '') : '',
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const actual = mode === 'contenteditable' ? (el.innerText || '') : String(el.value || '');
|
|
475
|
+
return {
|
|
476
|
+
ok: actual === ${safeText},
|
|
477
|
+
actual,
|
|
478
|
+
expected: ${safeText},
|
|
479
|
+
length: actual.length,
|
|
480
|
+
mode,
|
|
481
|
+
};
|
|
482
|
+
})()
|
|
483
|
+
`;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Generate JS for scrollTo that uses the unified resolver.
|
|
487
|
+
* Assumes resolveTargetJs has been called and __resolved is set.
|
|
488
|
+
*/
|
|
489
|
+
export function scrollResolvedJs(opts = {}) {
|
|
490
|
+
const shouldScroll = opts.skipScroll ? 'false' : 'true';
|
|
491
|
+
return `
|
|
492
|
+
(() => {
|
|
493
|
+
const el = window.__resolved;
|
|
494
|
+
if (!el) throw new Error('No resolved element');
|
|
495
|
+
if (${shouldScroll}) el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
|
|
496
|
+
return { scrolled: true, tag: el.tagName.toLowerCase(), text: (el.textContent || '').trim().slice(0, 80) };
|
|
497
|
+
})()
|
|
498
|
+
`;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Generate JS to get text content of resolved element.
|
|
502
|
+
*/
|
|
503
|
+
export function getTextResolvedJs() {
|
|
504
|
+
return `
|
|
505
|
+
(() => {
|
|
506
|
+
const el = window.__resolved;
|
|
507
|
+
if (!el) throw new Error('No resolved element');
|
|
508
|
+
return el.textContent?.trim() ?? null;
|
|
509
|
+
})()
|
|
510
|
+
`;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Generate JS to get value of resolved input/textarea element.
|
|
514
|
+
*/
|
|
515
|
+
export function getValueResolvedJs() {
|
|
516
|
+
return `
|
|
517
|
+
(() => {
|
|
518
|
+
const el = window.__resolved;
|
|
519
|
+
if (!el) throw new Error('No resolved element');
|
|
520
|
+
return el.value ?? null;
|
|
521
|
+
})()
|
|
522
|
+
`;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Generate JS to get all attributes of resolved element.
|
|
526
|
+
*/
|
|
527
|
+
export function getAttributesResolvedJs() {
|
|
528
|
+
return `
|
|
529
|
+
(() => {
|
|
530
|
+
const el = window.__resolved;
|
|
531
|
+
if (!el) throw new Error('No resolved element');
|
|
532
|
+
return JSON.stringify(Object.fromEntries([...el.attributes].map(a => [a.name, a.value])));
|
|
533
|
+
})()
|
|
534
|
+
`;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Generate JS to select an option on a resolved <select> element.
|
|
538
|
+
*/
|
|
539
|
+
export function selectResolvedJs(option) {
|
|
540
|
+
const safeOption = JSON.stringify(option);
|
|
541
|
+
return `
|
|
542
|
+
(() => {
|
|
543
|
+
const el = window.__resolved;
|
|
544
|
+
if (!el) throw new Error('No resolved element');
|
|
545
|
+
if (el.tagName !== 'SELECT') return { error: 'Not a <select>' };
|
|
546
|
+
const match = Array.from(el.options).find(o => o.text.trim() === ${safeOption} || o.value === ${safeOption});
|
|
547
|
+
if (!match) return { error: 'Option not found', available: Array.from(el.options).map(o => o.text.trim()) };
|
|
548
|
+
const setter = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, 'value')?.set;
|
|
549
|
+
if (setter) setter.call(el, match.value); else el.value = match.value;
|
|
550
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
551
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
552
|
+
return { selected: match.text };
|
|
553
|
+
})()
|
|
554
|
+
`;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Generate JS to check if resolved element is an autocomplete/combobox field.
|
|
558
|
+
*/
|
|
559
|
+
export function isAutocompleteResolvedJs() {
|
|
560
|
+
return `
|
|
561
|
+
(() => {
|
|
562
|
+
const el = window.__resolved;
|
|
563
|
+
if (!el) return false;
|
|
564
|
+
const role = el.getAttribute('role');
|
|
565
|
+
const ac = el.getAttribute('aria-autocomplete');
|
|
566
|
+
const list = el.getAttribute('list');
|
|
567
|
+
return role === 'combobox' || ac === 'list' || ac === 'both' || !!list;
|
|
568
|
+
})()
|
|
569
|
+
`;
|
|
570
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { resolveTargetJs } from './target-resolver.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tests for the target resolver JS generator.
|
|
5
|
+
*
|
|
6
|
+
* Since resolveTargetJs() produces JS strings for browser evaluate(),
|
|
7
|
+
* we test the generated JS by running it in a simulated DOM-like context
|
|
8
|
+
* and verifying the structure of the output.
|
|
9
|
+
*/
|
|
10
|
+
describe('resolveTargetJs', () => {
|
|
11
|
+
it('generates JS that returns structured resolution for numeric ref', () => {
|
|
12
|
+
const js = resolveTargetJs('12');
|
|
13
|
+
expect(js).toContain('data-webcmd-ref');
|
|
14
|
+
expect(js).toContain('__webcmd_ref_identity');
|
|
15
|
+
expect(js).toContain('"12"');
|
|
16
|
+
});
|
|
17
|
+
it('generates JS that handles CSS selector input', () => {
|
|
18
|
+
const js = resolveTargetJs('#submit-btn');
|
|
19
|
+
expect(js).toContain('querySelectorAll');
|
|
20
|
+
expect(js).toContain('"#submit-btn"');
|
|
21
|
+
});
|
|
22
|
+
it('generates JS with stale_ref detection for numeric refs', () => {
|
|
23
|
+
const js = resolveTargetJs('5');
|
|
24
|
+
expect(js).toContain('stale_ref');
|
|
25
|
+
expect(js).toContain('__webcmd_ref_identity');
|
|
26
|
+
});
|
|
27
|
+
it('generates JS with ambiguity detection for CSS selectors', () => {
|
|
28
|
+
const js = resolveTargetJs('.btn');
|
|
29
|
+
expect(js).toContain('selector_ambiguous');
|
|
30
|
+
expect(js).toContain('candidates');
|
|
31
|
+
});
|
|
32
|
+
it('generates JS that propagates --nth option into the CSS branch', () => {
|
|
33
|
+
const js = resolveTargetJs('.btn', { nth: 2 });
|
|
34
|
+
expect(js).toContain('selector_nth_out_of_range');
|
|
35
|
+
// opt.nth=2 should be inlined so the runtime picks matches[2]
|
|
36
|
+
expect(js).toMatch(/const nth = 2;?/);
|
|
37
|
+
});
|
|
38
|
+
it('generates JS that enables firstOnMulti for read commands', () => {
|
|
39
|
+
const js = resolveTargetJs('.btn', { firstOnMulti: true });
|
|
40
|
+
expect(js).toContain('firstOnMulti = true');
|
|
41
|
+
});
|
|
42
|
+
it('generates JS with invalid_selector branch for CSS syntax errors', () => {
|
|
43
|
+
const js = resolveTargetJs('.btn');
|
|
44
|
+
expect(js).toContain('invalid_selector');
|
|
45
|
+
});
|
|
46
|
+
it('generates JS with selector_not_found branch for 0 matches', () => {
|
|
47
|
+
const js = resolveTargetJs('#does-not-exist');
|
|
48
|
+
expect(js).toContain('selector_not_found');
|
|
49
|
+
});
|
|
50
|
+
it('hands every non-numeric input to querySelectorAll (no regex shortlist)', () => {
|
|
51
|
+
// Inputs that the old isCssLike regex rejected — must all flow into the
|
|
52
|
+
// CSS branch so `find --css` and `get/click/type/select` accept the same surface.
|
|
53
|
+
for (const sel of [':root', '*', ':has(.foo)', '::shadow-root', '???']) {
|
|
54
|
+
const js = resolveTargetJs(sel);
|
|
55
|
+
expect(js).toContain('querySelectorAll');
|
|
56
|
+
// invalid selectors still route through invalid_selector at runtime,
|
|
57
|
+
// never through a frontend "Cannot parse target" rejection.
|
|
58
|
+
expect(js).not.toContain('Cannot parse target');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
it('escapes ref value safely', () => {
|
|
62
|
+
const js = resolveTargetJs('"; alert(1); "');
|
|
63
|
+
// JSON.stringify should handle escaping
|
|
64
|
+
expect(js).not.toContain('alert(1); "');
|
|
65
|
+
expect(js).toContain('\\"');
|
|
66
|
+
});
|
|
67
|
+
it('tags every success envelope with match_level so agents can tell tiers apart', () => {
|
|
68
|
+
const numericJs = resolveTargetJs('7');
|
|
69
|
+
const cssJs = resolveTargetJs('.btn');
|
|
70
|
+
// Exact / reidentified emit the literal directly; stable flows through the
|
|
71
|
+
// classifier's `level` variable. All three strings must appear in the JS.
|
|
72
|
+
expect(numericJs).toContain("match_level: 'exact'");
|
|
73
|
+
expect(numericJs).toContain("match_level: 'reidentified'");
|
|
74
|
+
expect(numericJs).toContain("return 'stable'");
|
|
75
|
+
// Stable + exact share the same emit site (match_level: level) — make sure
|
|
76
|
+
// we didn't hardcode one of them and drop the other.
|
|
77
|
+
expect(numericJs).toContain('match_level: level');
|
|
78
|
+
// CSS path is always exact (selector ran successfully).
|
|
79
|
+
expect(cssJs).toContain("match_level: 'exact'");
|
|
80
|
+
});
|
|
81
|
+
it('cascading ref path — classifier + reidentifier are both wired in', () => {
|
|
82
|
+
const js = resolveTargetJs('3');
|
|
83
|
+
// Classifier distinguishes the three tiers
|
|
84
|
+
expect(js).toContain('function classifyMatch');
|
|
85
|
+
expect(js).toContain("return 'exact'");
|
|
86
|
+
expect(js).toContain("return 'stable'");
|
|
87
|
+
expect(js).toContain("return 'mismatch'");
|
|
88
|
+
// Strong id is the only thing that can rescue a drifted fingerprint
|
|
89
|
+
expect(js).toContain('hadStrongId');
|
|
90
|
+
// Reidentify searches live DOM with the same fingerprint shape the
|
|
91
|
+
// snapshot / find writers emit — id / testId / aria-label only.
|
|
92
|
+
expect(js).toContain('function reidentify');
|
|
93
|
+
expect(js).toContain('getElementById');
|
|
94
|
+
expect(js).toContain('[data-testid="');
|
|
95
|
+
expect(js).toContain('[aria-label="');
|
|
96
|
+
// Unique match required — never silently picks one of many candidates.
|
|
97
|
+
expect(js).toContain('candidates.length === 1');
|
|
98
|
+
// Recovered element is re-tagged + identity map refreshed so subsequent
|
|
99
|
+
// resolves land on 'exact' instead of re-walking the cascade.
|
|
100
|
+
expect(js).toContain("setAttribute('data-webcmd-ref', ref)");
|
|
101
|
+
expect(js).toContain('identity[ref] = fingerprintOf(recovered)');
|
|
102
|
+
});
|
|
103
|
+
it('reidentify runs both when data-webcmd-ref is missing AND when fingerprint is mismatched', () => {
|
|
104
|
+
const js = resolveTargetJs('9');
|
|
105
|
+
// Two call sites: one in the !el branch, one after classifyMatch returns mismatch.
|
|
106
|
+
const count = js.split('reidentify(fp)').length - 1;
|
|
107
|
+
expect(count).toBeGreaterThanOrEqual(2);
|
|
108
|
+
});
|
|
109
|
+
it('falls through to stale_ref only after reidentify exhausts', () => {
|
|
110
|
+
const js = resolveTargetJs('4');
|
|
111
|
+
// The stale_ref emit must sit *below* a reidentify attempt so the cascade
|
|
112
|
+
// is what produces the error — not the original strict check.
|
|
113
|
+
const reidentifyIdx = js.indexOf('const recovered = reidentify(fp);');
|
|
114
|
+
const staleIdx = js.indexOf("code: 'stale_ref'");
|
|
115
|
+
expect(reidentifyIdx).toBeGreaterThan(-1);
|
|
116
|
+
expect(staleIdx).toBeGreaterThan(reidentifyIdx);
|
|
117
|
+
});
|
|
118
|
+
});
|