@zenalexa/unicli 0.220.1 → 0.221.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/AGENTS.md +28 -6
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/dist/adapters/bilibili/comments.js +66 -4
- package/dist/adapters/bilibili/comments.js.map +1 -1
- package/dist/adapters/bilibili/compat.js +2 -2
- package/dist/adapters/bilibili/compat.js.map +1 -1
- package/dist/adapters/bilibili/download.js +4 -4
- package/dist/adapters/bilibili/download.js.map +1 -1
- package/dist/adapters/bilibili/wbi.d.ts.map +1 -1
- package/dist/adapters/bilibili/wbi.js +3 -3
- package/dist/adapters/bilibili/wbi.js.map +1 -1
- package/dist/adapters/cipo/_shared.d.ts +21 -0
- package/dist/adapters/cipo/_shared.d.ts.map +1 -0
- package/dist/adapters/cipo/_shared.js +67 -0
- package/dist/adapters/cipo/_shared.js.map +1 -0
- package/dist/adapters/cipo/get.d.ts +19 -0
- package/dist/adapters/cipo/get.d.ts.map +1 -0
- package/dist/adapters/cipo/get.js +140 -0
- package/dist/adapters/cipo/get.js.map +1 -0
- package/dist/adapters/cipo/legal-status.d.ts +19 -0
- package/dist/adapters/cipo/legal-status.d.ts.map +1 -0
- package/dist/adapters/cipo/legal-status.js +111 -0
- package/dist/adapters/cipo/legal-status.js.map +1 -0
- package/dist/adapters/cipo/search.d.ts +20 -0
- package/dist/adapters/cipo/search.d.ts.map +1 -0
- package/dist/adapters/cipo/search.js +148 -0
- package/dist/adapters/cipo/search.js.map +1 -0
- package/dist/adapters/cnipa/_shared.d.ts +47 -0
- package/dist/adapters/cnipa/_shared.d.ts.map +1 -0
- package/dist/adapters/cnipa/_shared.js +97 -0
- package/dist/adapters/cnipa/_shared.js.map +1 -0
- package/dist/adapters/cnipa/get.d.ts +19 -0
- package/dist/adapters/cnipa/get.d.ts.map +1 -0
- package/dist/adapters/cnipa/get.js +149 -0
- package/dist/adapters/cnipa/get.js.map +1 -0
- package/dist/adapters/cnipa/legal-status.d.ts +19 -0
- package/dist/adapters/cnipa/legal-status.d.ts.map +1 -0
- package/dist/adapters/cnipa/legal-status.js +119 -0
- package/dist/adapters/cnipa/legal-status.js.map +1 -0
- package/dist/adapters/cnipa/search.d.ts +21 -0
- package/dist/adapters/cnipa/search.d.ts.map +1 -0
- package/dist/adapters/cnipa/search.js +170 -0
- package/dist/adapters/cnipa/search.js.map +1 -0
- package/dist/adapters/espacenet/_shared.d.ts +21 -0
- package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
- package/dist/adapters/espacenet/_shared.js +67 -0
- package/dist/adapters/espacenet/_shared.js.map +1 -0
- package/dist/adapters/espacenet/family.d.ts +19 -0
- package/dist/adapters/espacenet/family.d.ts.map +1 -0
- package/dist/adapters/espacenet/family.js +118 -0
- package/dist/adapters/espacenet/family.js.map +1 -0
- package/dist/adapters/espacenet/get.d.ts +19 -0
- package/dist/adapters/espacenet/get.d.ts.map +1 -0
- package/dist/adapters/espacenet/get.js +130 -0
- package/dist/adapters/espacenet/get.js.map +1 -0
- package/dist/adapters/espacenet/legal-status.d.ts +19 -0
- package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
- package/dist/adapters/espacenet/legal-status.js +110 -0
- package/dist/adapters/espacenet/legal-status.js.map +1 -0
- package/dist/adapters/espacenet/search.d.ts +20 -0
- package/dist/adapters/espacenet/search.d.ts.map +1 -0
- package/dist/adapters/espacenet/search.js +165 -0
- package/dist/adapters/espacenet/search.js.map +1 -0
- package/dist/adapters/facebook/subtitles.d.ts +9 -0
- package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
- package/dist/adapters/facebook/subtitles.js +42 -0
- package/dist/adapters/facebook/subtitles.js.map +1 -0
- package/dist/adapters/fips/_shared.d.ts +21 -0
- package/dist/adapters/fips/_shared.d.ts.map +1 -0
- package/dist/adapters/fips/_shared.js +77 -0
- package/dist/adapters/fips/_shared.js.map +1 -0
- package/dist/adapters/fips/get.d.ts +19 -0
- package/dist/adapters/fips/get.d.ts.map +1 -0
- package/dist/adapters/fips/get.js +139 -0
- package/dist/adapters/fips/get.js.map +1 -0
- package/dist/adapters/fips/search.d.ts +20 -0
- package/dist/adapters/fips/search.d.ts.map +1 -0
- package/dist/adapters/fips/search.js +148 -0
- package/dist/adapters/fips/search.js.map +1 -0
- package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
- package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
- package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
- package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
- package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
- package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
- package/dist/adapters/freepatentsonline-web/get.js +127 -0
- package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
- package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
- package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
- package/dist/adapters/freepatentsonline-web/search.js +149 -0
- package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
- package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
- package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
- package/dist/adapters/google-patents-web/_shared.js +164 -0
- package/dist/adapters/google-patents-web/_shared.js.map +1 -0
- package/dist/adapters/google-patents-web/get.d.ts +36 -0
- package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
- package/dist/adapters/google-patents-web/get.js +187 -0
- package/dist/adapters/google-patents-web/get.js.map +1 -0
- package/dist/adapters/google-patents-web/search.d.ts +23 -0
- package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
- package/dist/adapters/google-patents-web/search.js +169 -0
- package/dist/adapters/google-patents-web/search.js.map +1 -0
- package/dist/adapters/inpi-br/_shared.d.ts +21 -0
- package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
- package/dist/adapters/inpi-br/_shared.js +67 -0
- package/dist/adapters/inpi-br/_shared.js.map +1 -0
- package/dist/adapters/inpi-br/get.d.ts +19 -0
- package/dist/adapters/inpi-br/get.d.ts.map +1 -0
- package/dist/adapters/inpi-br/get.js +142 -0
- package/dist/adapters/inpi-br/get.js.map +1 -0
- package/dist/adapters/inpi-br/search.d.ts +20 -0
- package/dist/adapters/inpi-br/search.d.ts.map +1 -0
- package/dist/adapters/inpi-br/search.js +154 -0
- package/dist/adapters/inpi-br/search.js.map +1 -0
- package/dist/adapters/instagram/subtitles.d.ts +9 -0
- package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
- package/dist/adapters/instagram/subtitles.js +42 -0
- package/dist/adapters/instagram/subtitles.js.map +1 -0
- package/dist/adapters/mastodon/statuses.d.ts +40 -0
- package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
- package/dist/adapters/mastodon/statuses.js +153 -0
- package/dist/adapters/mastodon/statuses.js.map +1 -0
- package/dist/adapters/reddit/comments.d.ts +9 -0
- package/dist/adapters/reddit/comments.d.ts.map +1 -0
- package/dist/adapters/reddit/comments.js +124 -0
- package/dist/adapters/reddit/comments.js.map +1 -0
- package/dist/adapters/threads/post.d.ts +32 -0
- package/dist/adapters/threads/post.d.ts.map +1 -0
- package/dist/adapters/threads/post.js +287 -0
- package/dist/adapters/threads/post.js.map +1 -0
- package/dist/adapters/tiktok/subtitles.d.ts +9 -0
- package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
- package/dist/adapters/tiktok/subtitles.js +42 -0
- package/dist/adapters/tiktok/subtitles.js.map +1 -0
- package/dist/adapters/twitter/accept.js +2 -2
- package/dist/adapters/twitter/accept.js.map +1 -1
- package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
- package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
- package/dist/adapters/twitter/browser-fallback.js +93 -0
- package/dist/adapters/twitter/browser-fallback.js.map +1 -0
- package/dist/adapters/twitter/browser-state.d.ts +11 -0
- package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
- package/dist/adapters/twitter/browser-state.js +46 -0
- package/dist/adapters/twitter/browser-state.js.map +1 -0
- package/dist/adapters/twitter/client.d.ts.map +1 -1
- package/dist/adapters/twitter/client.js +36 -13
- package/dist/adapters/twitter/client.js.map +1 -1
- package/dist/adapters/twitter/reply-dm.js +2 -2
- package/dist/adapters/twitter/reply-dm.js.map +1 -1
- package/dist/adapters/twitter/reply.js +1 -0
- package/dist/adapters/twitter/reply.js.map +1 -1
- package/dist/adapters/twitter/search.js +11 -18
- package/dist/adapters/twitter/search.js.map +1 -1
- package/dist/adapters/twitter/thread.d.ts +14 -0
- package/dist/adapters/twitter/thread.d.ts.map +1 -1
- package/dist/adapters/twitter/thread.js +28 -2
- package/dist/adapters/twitter/thread.js.map +1 -1
- package/dist/adapters/twitter/trending.js +13 -59
- package/dist/adapters/twitter/trending.js.map +1 -1
- package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
- package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
- package/dist/adapters/xiaohongshu/browser-state.js +67 -0
- package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
- package/dist/adapters/xiaohongshu/comments.js +28 -5
- package/dist/adapters/xiaohongshu/comments.js.map +1 -1
- package/dist/adapters/xiaohongshu/download.js +49 -11
- package/dist/adapters/xiaohongshu/download.js.map +1 -1
- package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
- package/dist/adapters/xiaohongshu/search.js +11 -5
- package/dist/adapters/xiaohongshu/search.js.map +1 -1
- package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
- package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
- package/dist/adapters/xiaohongshu/trending.js +94 -0
- package/dist/adapters/xiaohongshu/trending.js.map +1 -0
- package/dist/adapters/youtube/comments.d.ts +80 -0
- package/dist/adapters/youtube/comments.d.ts.map +1 -1
- package/dist/adapters/youtube/comments.js +108 -12
- package/dist/adapters/youtube/comments.js.map +1 -1
- package/dist/adapters/youtube/subtitles.d.ts +9 -0
- package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
- package/dist/adapters/youtube/subtitles.js +42 -0
- package/dist/adapters/youtube/subtitles.js.map +1 -0
- package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
- package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
- package/dist/adapters/yt-dlp/subtitles.js +41 -0
- package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
- package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
- package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
- package/dist/adapters/zhihu/answer-detail.js +204 -0
- package/dist/adapters/zhihu/answer-detail.js.map +1 -0
- package/dist/adapters/zhihu/comment.d.ts +9 -0
- package/dist/adapters/zhihu/comment.d.ts.map +1 -0
- package/dist/adapters/zhihu/comment.js +149 -0
- package/dist/adapters/zhihu/comment.js.map +1 -0
- package/dist/adapters/zhihu/recommend.d.ts +36 -0
- package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
- package/dist/adapters/zhihu/recommend.js +151 -0
- package/dist/adapters/zhihu/recommend.js.map +1 -0
- package/dist/browser/bridge.d.ts.map +1 -1
- package/dist/browser/bridge.js +14 -3
- package/dist/browser/bridge.js.map +1 -1
- package/dist/browser/daemon-client.d.ts +6 -0
- package/dist/browser/daemon-client.d.ts.map +1 -1
- package/dist/browser/daemon-client.js +75 -15
- package/dist/browser/daemon-client.js.map +1 -1
- package/dist/browser/daemon.js +39 -15
- package/dist/browser/daemon.js.map +1 -1
- package/dist/browser/protocol.d.ts +1 -0
- package/dist/browser/protocol.d.ts.map +1 -1
- package/dist/browser/protocol.js +1 -0
- package/dist/browser/protocol.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/approvals.d.ts.map +1 -1
- package/dist/commands/approvals.js +1 -37
- package/dist/commands/approvals.js.map +1 -1
- package/dist/commands/browser/index.d.ts.map +1 -1
- package/dist/commands/browser/index.js +7 -2
- package/dist/commands/browser/index.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +7 -3
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/dispatch.js +27 -3
- package/dist/commands/dispatch.js.map +1 -1
- package/dist/commands/patent-doctor.d.ts +48 -0
- package/dist/commands/patent-doctor.d.ts.map +1 -0
- package/dist/commands/patent-doctor.js +109 -0
- package/dist/commands/patent-doctor.js.map +1 -0
- package/dist/commands/patent.d.ts +78 -0
- package/dist/commands/patent.d.ts.map +1 -0
- package/dist/commands/patent.js +919 -0
- package/dist/commands/patent.js.map +1 -0
- package/dist/commands/social.d.ts +19 -0
- package/dist/commands/social.d.ts.map +1 -0
- package/dist/commands/social.js +236 -0
- package/dist/commands/social.js.map +1 -0
- package/dist/core/registry.d.ts +1 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +11 -2
- package/dist/core/registry.js.map +1 -1
- package/dist/discovery/loader.d.ts.map +1 -1
- package/dist/discovery/loader.js +4 -0
- package/dist/discovery/loader.js.map +1 -1
- package/dist/engine/approval-presenter.d.ts +10 -0
- package/dist/engine/approval-presenter.d.ts.map +1 -0
- package/dist/engine/approval-presenter.js +45 -0
- package/dist/engine/approval-presenter.js.map +1 -0
- package/dist/engine/approval-store.d.ts +4 -0
- package/dist/engine/approval-store.d.ts.map +1 -1
- package/dist/engine/approval-store.js +85 -11
- package/dist/engine/approval-store.js.map +1 -1
- package/dist/engine/auth/oauth2-cc.d.ts +67 -0
- package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
- package/dist/engine/auth/oauth2-cc.js +120 -0
- package/dist/engine/auth/oauth2-cc.js.map +1 -0
- package/dist/engine/cookies.d.ts +10 -0
- package/dist/engine/cookies.d.ts.map +1 -1
- package/dist/engine/cookies.js +64 -0
- package/dist/engine/cookies.js.map +1 -1
- package/dist/engine/download.d.ts +5 -0
- package/dist/engine/download.d.ts.map +1 -1
- package/dist/engine/download.js +11 -4
- package/dist/engine/download.js.map +1 -1
- package/dist/engine/executor.d.ts +1 -0
- package/dist/engine/executor.d.ts.map +1 -1
- package/dist/engine/executor.js +25 -0
- package/dist/engine/executor.js.map +1 -1
- package/dist/engine/framework.d.ts +5 -5
- package/dist/engine/framework.js +5 -5
- package/dist/engine/harden.d.ts +1 -1
- package/dist/engine/harden.js +1 -1
- package/dist/engine/kernel/stages.d.ts.map +1 -1
- package/dist/engine/kernel/stages.js +2 -1
- package/dist/engine/kernel/stages.js.map +1 -1
- package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
- package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
- package/dist/engine/normalizer/patent-envelope.js +132 -0
- package/dist/engine/normalizer/patent-envelope.js.map +1 -0
- package/dist/engine/research.d.ts +5 -7
- package/dist/engine/research.d.ts.map +1 -1
- package/dist/engine/research.js +6 -9
- package/dist/engine/research.js.map +1 -1
- package/dist/engine/steps/browser-helpers.d.ts +2 -2
- package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
- package/dist/engine/steps/browser-helpers.js +39 -16
- package/dist/engine/steps/browser-helpers.js.map +1 -1
- package/dist/engine/steps/download.d.ts +1 -0
- package/dist/engine/steps/download.d.ts.map +1 -1
- package/dist/engine/steps/download.js +3 -1
- package/dist/engine/steps/download.js.map +1 -1
- package/dist/engine/steps/index.d.ts +2 -0
- package/dist/engine/steps/index.d.ts.map +1 -1
- package/dist/engine/steps/index.js +2 -0
- package/dist/engine/steps/index.js.map +1 -1
- package/dist/engine/steps/oauth2-token.d.ts +41 -0
- package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
- package/dist/engine/steps/oauth2-token.js +115 -0
- package/dist/engine/steps/oauth2-token.js.map +1 -0
- package/dist/engine/steps/select-xml.d.ts +34 -0
- package/dist/engine/steps/select-xml.d.ts.map +1 -0
- package/dist/engine/steps/select-xml.js +222 -0
- package/dist/engine/steps/select-xml.js.map +1 -0
- package/dist/engine/template.d.ts.map +1 -1
- package/dist/engine/template.js +7 -0
- package/dist/engine/template.js.map +1 -1
- package/dist/engine/transport/mcp-browser.d.ts +128 -0
- package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
- package/dist/engine/transport/mcp-browser.js +120 -0
- package/dist/engine/transport/mcp-browser.js.map +1 -0
- package/dist/fast-path/handlers/approvals.d.ts +11 -0
- package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
- package/dist/fast-path/handlers/approvals.js +136 -0
- package/dist/fast-path/handlers/approvals.js.map +1 -0
- package/dist/fast-path/manifest.d.ts +1 -0
- package/dist/fast-path/manifest.d.ts.map +1 -1
- package/dist/fast-path/manifest.js.map +1 -1
- package/dist/fast-path.d.ts.map +1 -1
- package/dist/fast-path.js +3 -0
- package/dist/fast-path.js.map +1 -1
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-compact.txt +3 -3
- package/dist/manifest-search.json +1 -1
- package/dist/manifest.json +2239 -176
- package/dist/output/auth-guidance.d.ts +14 -0
- package/dist/output/auth-guidance.d.ts.map +1 -0
- package/dist/output/auth-guidance.js +50 -0
- package/dist/output/auth-guidance.js.map +1 -0
- package/dist/output/error-map.d.ts +1 -1
- package/dist/output/error-map.d.ts.map +1 -1
- package/dist/output/error-map.js +28 -4
- package/dist/output/error-map.js.map +1 -1
- package/dist/output/next-actions.d.ts.map +1 -1
- package/dist/output/next-actions.js +19 -3
- package/dist/output/next-actions.js.map +1 -1
- package/dist/registry.d.ts +18 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +5 -0
- package/dist/registry.js.map +1 -1
- package/dist/social/browser-errors.d.ts +13 -0
- package/dist/social/browser-errors.d.ts.map +1 -0
- package/dist/social/browser-errors.js +36 -0
- package/dist/social/browser-errors.js.map +1 -0
- package/dist/social/capabilities.d.ts +29 -0
- package/dist/social/capabilities.d.ts.map +1 -0
- package/dist/social/capabilities.js +448 -0
- package/dist/social/capabilities.js.map +1 -0
- package/dist/social/comments.d.ts +26 -0
- package/dist/social/comments.d.ts.map +1 -0
- package/dist/social/comments.js +97 -0
- package/dist/social/comments.js.map +1 -0
- package/dist/social/video-text.d.ts +27 -0
- package/dist/social/video-text.d.ts.map +1 -0
- package/dist/social/video-text.js +140 -0
- package/dist/social/video-text.js.map +1 -0
- package/dist/types/patent.d.ts +160 -0
- package/dist/types/patent.d.ts.map +1 -0
- package/dist/types/patent.js +16 -0
- package/dist/types/patent.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +9 -4
- package/server.json +3 -3
- package/skills/unicli/SKILL.md +1 -1
- package/skills/unicli-claude-code/SKILL.md +1 -1
- package/skills/unicli-hermes/SKILL.md +1 -1
- package/src/adapters/bilibili/comments-tree.test.ts +41 -0
- package/src/adapters/bilibili/comments.ts +78 -4
- package/src/adapters/bilibili/compat.ts +5 -2
- package/src/adapters/bilibili/download.ts +7 -4
- package/src/adapters/bilibili/wbi.ts +6 -3
- package/src/adapters/brave/search.yaml +53 -0
- package/src/adapters/cipo/_shared.ts +98 -0
- package/src/adapters/cipo/get.ts +188 -0
- package/src/adapters/cipo/legal-status.ts +148 -0
- package/src/adapters/cipo/search.ts +195 -0
- package/src/adapters/cnipa/_shared.ts +138 -0
- package/src/adapters/cnipa/get.ts +199 -0
- package/src/adapters/cnipa/legal-status.ts +162 -0
- package/src/adapters/cnipa/search.ts +229 -0
- package/src/adapters/dpma/get.yaml +67 -0
- package/src/adapters/dpma/search.yaml +77 -0
- package/src/adapters/duckduckgo/search.yaml +54 -0
- package/src/adapters/duckduckgo/suggest.yaml +52 -0
- package/src/adapters/epo/family.yaml +69 -0
- package/src/adapters/epo/get.yaml +74 -0
- package/src/adapters/epo/legal-status.yaml +63 -0
- package/src/adapters/epo/search.yaml +84 -0
- package/src/adapters/espacenet/_shared.ts +98 -0
- package/src/adapters/espacenet/family.ts +161 -0
- package/src/adapters/espacenet/get.ts +185 -0
- package/src/adapters/espacenet/legal-status.ts +151 -0
- package/src/adapters/espacenet/search.ts +229 -0
- package/src/adapters/facebook/subtitles.ts +44 -0
- package/src/adapters/fips/_shared.ts +109 -0
- package/src/adapters/fips/get.ts +186 -0
- package/src/adapters/fips/search.ts +195 -0
- package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
- package/src/adapters/freepatentsonline-web/get.ts +144 -0
- package/src/adapters/freepatentsonline-web/search.ts +170 -0
- package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
- package/src/adapters/google-patents-bq/search.yaml +97 -0
- package/src/adapters/google-patents-web/_shared.ts +242 -0
- package/src/adapters/google-patents-web/get.ts +224 -0
- package/src/adapters/google-patents-web/search.ts +196 -0
- package/src/adapters/inpi-br/_shared.ts +98 -0
- package/src/adapters/inpi-br/get.ts +193 -0
- package/src/adapters/inpi-br/search.ts +206 -0
- package/src/adapters/inpi-fr/get.yaml +62 -0
- package/src/adapters/inpi-fr/search.yaml +74 -0
- package/src/adapters/instagram/subtitles.ts +44 -0
- package/src/adapters/ipaustralia/get.yaml +67 -0
- package/src/adapters/ipaustralia/search.yaml +74 -0
- package/src/adapters/jpo/get.yaml +63 -0
- package/src/adapters/jpo/search.yaml +76 -0
- package/src/adapters/kipris/get.yaml +69 -0
- package/src/adapters/kipris/legal-status.yaml +58 -0
- package/src/adapters/kipris/search.yaml +79 -0
- package/src/adapters/lens/get.yaml +64 -0
- package/src/adapters/lens/search.yaml +82 -0
- package/src/adapters/mastodon/statuses.test.ts +82 -0
- package/src/adapters/mastodon/statuses.ts +208 -0
- package/src/adapters/patsnap/get.yaml +65 -0
- package/src/adapters/patsnap/search.yaml +77 -0
- package/src/adapters/pqai/prior-art.yaml +59 -0
- package/src/adapters/pqai/search.yaml +60 -0
- package/src/adapters/reddit/comments-tree.test.ts +79 -0
- package/src/adapters/reddit/comments.ts +159 -0
- package/src/adapters/threads/post.test.ts +64 -0
- package/src/adapters/threads/post.ts +366 -0
- package/src/adapters/threads/user.yaml +73 -0
- package/src/adapters/tiktok/subtitles.ts +44 -0
- package/src/adapters/twitter/accept.ts +5 -2
- package/src/adapters/twitter/browser-fallback.ts +138 -0
- package/src/adapters/twitter/browser-state.ts +74 -0
- package/src/adapters/twitter/client.ts +51 -21
- package/src/adapters/twitter/reply-dm.ts +5 -2
- package/src/adapters/twitter/reply.ts +1 -0
- package/src/adapters/twitter/search.ts +12 -38
- package/src/adapters/twitter/thread.test.ts +43 -0
- package/src/adapters/twitter/thread.ts +44 -2
- package/src/adapters/twitter/trending.ts +14 -95
- package/src/adapters/ukipo/info.yaml +43 -0
- package/src/adapters/uspto/get.yaml +67 -0
- package/src/adapters/uspto/legal-status.yaml +58 -0
- package/src/adapters/uspto/search.yaml +88 -0
- package/src/adapters/wipo-patentscope/info.yaml +43 -0
- package/src/adapters/xiaohongshu/browser-state.ts +95 -0
- package/src/adapters/xiaohongshu/comments.ts +29 -6
- package/src/adapters/xiaohongshu/download.ts +60 -11
- package/src/adapters/xiaohongshu/search.ts +18 -6
- package/src/adapters/xiaohongshu/trending.ts +112 -0
- package/src/adapters/yahoo/search.yaml +52 -0
- package/src/adapters/youtube/comments-microformat.test.ts +35 -0
- package/src/adapters/youtube/comments-tree.test.ts +74 -0
- package/src/adapters/youtube/comments.ts +166 -12
- package/src/adapters/youtube/subtitles.ts +44 -0
- package/src/adapters/yt-dlp/subtitles.ts +43 -0
- package/src/adapters/zhihu/answer-detail.test.ts +83 -0
- package/src/adapters/zhihu/answer-detail.ts +275 -0
- package/src/adapters/zhihu/comment-tree.test.ts +57 -0
- package/src/adapters/zhihu/comment.ts +186 -0
- package/src/adapters/zhihu/recommend.test.ts +65 -0
- package/src/adapters/zhihu/recommend.ts +207 -0
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { cli } from "../../registry.js";
|
|
6
6
|
import { Strategy } from "../../types.js";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
const GUIDE_URL = "https://x.com/i/api/2/guide.json";
|
|
7
|
+
import { browserTrendingTopics } from "./browser-fallback.js";
|
|
8
|
+
import type { IPage } from "../../types.js";
|
|
10
9
|
|
|
11
10
|
cli({
|
|
12
11
|
site: "twitter",
|
|
@@ -14,99 +13,19 @@ cli({
|
|
|
14
13
|
description: "Get trending topics",
|
|
15
14
|
domain: "x.com",
|
|
16
15
|
strategy: Strategy.COOKIE,
|
|
16
|
+
browser: true,
|
|
17
|
+
browserSession: "user",
|
|
18
|
+
args: [
|
|
19
|
+
{
|
|
20
|
+
name: "limit",
|
|
21
|
+
type: "int",
|
|
22
|
+
default: 20,
|
|
23
|
+
description: "Number of trends",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
17
26
|
columns: ["name", "tweet_count", "description", "url"],
|
|
18
|
-
func: async (
|
|
27
|
+
func: async (page, kwargs) => {
|
|
19
28
|
const count = (kwargs.limit as number) ?? 20;
|
|
20
|
-
|
|
21
|
-
const data = (await twitterGuideFetch(GUIDE_URL, {
|
|
22
|
-
count: String(count),
|
|
23
|
-
include_page_configuration: "false",
|
|
24
|
-
})) as Record<string, unknown>;
|
|
25
|
-
|
|
26
|
-
// Navigate: data.timeline.instructions[0].addEntries.entries
|
|
27
|
-
const timeline = data.timeline as Record<string, unknown> | undefined;
|
|
28
|
-
const instructions = (timeline?.instructions as unknown[]) ?? [];
|
|
29
|
-
|
|
30
|
-
const trends: Array<{
|
|
31
|
-
name: string;
|
|
32
|
-
tweet_count: string;
|
|
33
|
-
description: string;
|
|
34
|
-
url: string;
|
|
35
|
-
}> = [];
|
|
36
|
-
|
|
37
|
-
for (const instruction of instructions) {
|
|
38
|
-
const inst = instruction as Record<string, unknown>;
|
|
39
|
-
const addEntries = inst.addEntries as Record<string, unknown> | undefined;
|
|
40
|
-
if (!addEntries) continue;
|
|
41
|
-
|
|
42
|
-
const entries = (addEntries.entries as unknown[]) ?? [];
|
|
43
|
-
|
|
44
|
-
for (const entry of entries) {
|
|
45
|
-
const e = entry as Record<string, unknown>;
|
|
46
|
-
const content = e.content as Record<string, unknown> | undefined;
|
|
47
|
-
if (!content) continue;
|
|
48
|
-
|
|
49
|
-
// Trend items are nested in timelineModule or timelineItem
|
|
50
|
-
const items =
|
|
51
|
-
(content.items as unknown[]) ??
|
|
52
|
-
(content.item ? [{ item: content.item }] : []);
|
|
53
|
-
|
|
54
|
-
for (const item of items) {
|
|
55
|
-
const i = item as Record<string, unknown>;
|
|
56
|
-
const itemObj = (i.item ?? i) as Record<string, unknown>;
|
|
57
|
-
const clientEventInfo = itemObj.clientEventInfo as
|
|
58
|
-
| Record<string, unknown>
|
|
59
|
-
| undefined;
|
|
60
|
-
const details = clientEventInfo?.details as
|
|
61
|
-
| Record<string, unknown>
|
|
62
|
-
| undefined;
|
|
63
|
-
const guideDetails = details?.guideDetails as
|
|
64
|
-
| Record<string, unknown>
|
|
65
|
-
| undefined;
|
|
66
|
-
const transparentGuideDetails =
|
|
67
|
-
guideDetails?.transparentGuideDetails as
|
|
68
|
-
| Record<string, unknown>
|
|
69
|
-
| undefined;
|
|
70
|
-
const trendMetadata = transparentGuideDetails?.trendMetadata as
|
|
71
|
-
| Record<string, unknown>
|
|
72
|
-
| undefined;
|
|
73
|
-
|
|
74
|
-
// Also try direct content path
|
|
75
|
-
const itemContent = (
|
|
76
|
-
itemObj as Record<string, Record<string, unknown>>
|
|
77
|
-
).content;
|
|
78
|
-
const trend = itemContent?.trend as
|
|
79
|
-
| Record<string, unknown>
|
|
80
|
-
| undefined;
|
|
81
|
-
|
|
82
|
-
const name =
|
|
83
|
-
(trendMetadata?.trendName as string) ??
|
|
84
|
-
(trend?.name as string) ??
|
|
85
|
-
"";
|
|
86
|
-
if (!name) continue;
|
|
87
|
-
|
|
88
|
-
const tweetCount =
|
|
89
|
-
(trendMetadata?.metaDescription as string) ??
|
|
90
|
-
(trend?.tweetCount as string) ??
|
|
91
|
-
"";
|
|
92
|
-
const desc =
|
|
93
|
-
(trend?.description as string) ??
|
|
94
|
-
(trendMetadata?.metaDescription as string) ??
|
|
95
|
-
"";
|
|
96
|
-
const trendUrl = trend?.url as Record<string, unknown> | undefined;
|
|
97
|
-
|
|
98
|
-
trends.push({
|
|
99
|
-
name,
|
|
100
|
-
tweet_count: tweetCount,
|
|
101
|
-
description: desc,
|
|
102
|
-
url:
|
|
103
|
-
(trendUrl?.url as string) ??
|
|
104
|
-
`https://x.com/search?q=${encodeURIComponent(name)}`,
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return trends.slice(0, count);
|
|
29
|
+
return browserTrendingTopics(page as IPage, count);
|
|
111
30
|
},
|
|
112
31
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @owner src::adapters::ukipo::info
|
|
2
|
+
# @does Registry placeholder for the UK Intellectual Property Office — surfaces a structured PATENT_API_DEPRECATED envelope until UK IPO ships the OneIPO programmatic API listed on its 2026 roadmap.
|
|
3
|
+
# @needs src/engine/steps/assert.ts
|
|
4
|
+
# @feeds src/commands/patent.ts (meta-command discovery via `patent.*` capability)
|
|
5
|
+
# @breaks always throws PipelineError carrying a PATENT_API_DEPRECATED message; never silently returns rows
|
|
6
|
+
# @invariants no HTTPS egress; no env reads; no caller-visible state beyond the error envelope
|
|
7
|
+
# @side-effects none
|
|
8
|
+
# @perf n/a — fails before any I/O
|
|
9
|
+
# @concurrency safe (pure local assertion)
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability experimental — replace with a real adapter when UK IPO publishes the OneIPO API spec
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification waiting-for-api — UK IPO retired Ipsum on 2025-01; the OneIPOSearch web UI is live at https://www.search-for-intellectual-property.service.gov.uk/patent and a programmatic OneIPO API is listed on the 2026 roadmap with no fixed launch date. Until the API ships, callers can run searches manually through the OneIPOSearch UI.
|
|
14
|
+
site: ukipo
|
|
15
|
+
name: info
|
|
16
|
+
description: UK IPO registry placeholder — Ipsum retired 2025-01; OneIPO API on 2026 roadmap
|
|
17
|
+
domain: search-for-intellectual-property.service.gov.uk
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args: {}
|
|
23
|
+
|
|
24
|
+
pipeline:
|
|
25
|
+
# Fail closed with a structured envelope. The message points at the
|
|
26
|
+
# OneIPOSearch web UI so a caller has a concrete next step today, and
|
|
27
|
+
# names the OneIPO API roadmap so future repair loops know where the
|
|
28
|
+
# gap is going to close.
|
|
29
|
+
- assert:
|
|
30
|
+
condition: "false"
|
|
31
|
+
message: "PATENT_API_DEPRECATED: UK IPO retired Ipsum on 2025-01. Use the OneIPOSearch web UI at https://www.search-for-intellectual-property.service.gov.uk/patent for now; the OneIPO programmatic API is listed on the UK IPO 2026 roadmap (https://www.gov.uk/government/organisations/intellectual-property-office) but has not shipped."
|
|
32
|
+
|
|
33
|
+
columns: []
|
|
34
|
+
|
|
35
|
+
# schema-v2 metadata
|
|
36
|
+
# The patent.* capability lets `unicli patent doctor` discover this adapter
|
|
37
|
+
# so the gap surfaces in the doctor table; the runtime step is `assert`.
|
|
38
|
+
capabilities: ["assert", "patent.search", "patent.get"]
|
|
39
|
+
minimum_capability: assert
|
|
40
|
+
trust: public
|
|
41
|
+
confidentiality: public
|
|
42
|
+
quarantine: false
|
|
43
|
+
schema_version: v2
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @owner src::adapters::uspto::get
|
|
2
|
+
# @does Fetch a single USPTO patent/application by application number via the ODP detail endpoint.
|
|
3
|
+
# @needs src/engine/steps/fetch.ts, src/engine/steps/map.ts
|
|
4
|
+
# @feeds src/commands/patent.ts
|
|
5
|
+
# @breaks throws PipelineError on 401/403 (missing/invalid X-API-KEY), 404 (number not found) or 5xx
|
|
6
|
+
# @invariants output row conforms to PatentRecord; publication_number is canonicalized to ST.16 form
|
|
7
|
+
# @side-effects reads env USPTO_ODP_API_KEY; HTTPS egress to api.uspto.gov
|
|
8
|
+
# @perf single request
|
|
9
|
+
# @concurrency safe
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-key — needs USPTO_ODP_API_KEY
|
|
14
|
+
site: uspto
|
|
15
|
+
name: get
|
|
16
|
+
description: Fetch a USPTO patent/application by application number
|
|
17
|
+
domain: api.uspto.gov
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args:
|
|
23
|
+
application_number:
|
|
24
|
+
type: str
|
|
25
|
+
required: true
|
|
26
|
+
positional: true
|
|
27
|
+
description: USPTO application number (e.g. 16/123,456 with or without slash)
|
|
28
|
+
|
|
29
|
+
pipeline:
|
|
30
|
+
- fetch:
|
|
31
|
+
url: "https://api.uspto.gov/api/v1/patent/applications/${{ args.application_number | replace('/', '') | replace(',', '') }}"
|
|
32
|
+
method: GET
|
|
33
|
+
headers:
|
|
34
|
+
Accept: application/json
|
|
35
|
+
X-API-KEY: "${{ env.USPTO_ODP_API_KEY || '' }}"
|
|
36
|
+
|
|
37
|
+
# ODP single-record detail endpoint returns the same `applicationMetaData`
|
|
38
|
+
# envelope as search, plus a richer `patentTermAdjustment` / `inventor` /
|
|
39
|
+
# `applicant` set on the detail path. Every field reference below maps to a
|
|
40
|
+
# documented ODP path; adapters do not synthesise.
|
|
41
|
+
- map:
|
|
42
|
+
publication_number: "${{ item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber ? ('US-' + item.applicationMetaData.earliestPublicationNumber) : ('US-' + (item.applicationNumberText || '')) }}"
|
|
43
|
+
application_number: "${{ item.applicationNumberText || '' }}"
|
|
44
|
+
title: "${{ item.applicationMetaData ? (item.applicationMetaData.inventionTitle || '') : '' }}"
|
|
45
|
+
abstract: "${{ item.applicationMetaData ? (item.applicationMetaData.abstractText || '') : '' }}"
|
|
46
|
+
filing_date: "${{ item.applicationMetaData ? (item.applicationMetaData.filingDate || '') : '' }}"
|
|
47
|
+
publication_date: "${{ item.applicationMetaData ? (item.applicationMetaData.earliestPublicationDate || '') : '' }}"
|
|
48
|
+
grant_date: "${{ item.applicationMetaData ? (item.applicationMetaData.grantDate || '') : '' }}"
|
|
49
|
+
priority_date: "${{ item.applicationMetaData ? (item.applicationMetaData.firstInventorToFileIndicator ? item.applicationMetaData.filingDate : (item.applicationMetaData.earliestPriorityDate || '')) : '' }}"
|
|
50
|
+
kind_code: "${{ (item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber) ? (item.applicationMetaData.earliestPublicationNumber.match(/[A-Z]\\d?$/) || [''])[0] : '' }}"
|
|
51
|
+
inventors: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.inventorBag) ? item.applicationMetaData.inventorBag.map(p => ({ name: p.inventorNameText || ((p.firstName || '') + ' ' + (p.lastName || '')).trim(), country: p.countryCode || undefined })) : []) }}"
|
|
52
|
+
assignees: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.applicantBag) ? item.applicationMetaData.applicantBag.map(p => ({ name: p.applicantNameText || p.organizationNameText || '', country: p.countryCode || undefined })) : []) }}"
|
|
53
|
+
classifications: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.cpcClassificationBag) ? item.applicationMetaData.cpcClassificationBag.map(c => ({ scheme: 'cpc', code: c.cpcSymbol || c })) : []) }}"
|
|
54
|
+
legal_status: "${{ item.applicationMetaData ? (item.applicationMetaData.applicationStatusDescriptionText || '') : '' }}"
|
|
55
|
+
source_adapter: uspto
|
|
56
|
+
source_url: "${{ 'https://ppubs.uspto.gov/dirsearch-public/patents/' + (item.applicationNumberText || '') }}"
|
|
57
|
+
retrieved_at: ""
|
|
58
|
+
|
|
59
|
+
columns: [publication_number, title, filing_date, publication_date]
|
|
60
|
+
|
|
61
|
+
# schema-v2 metadata
|
|
62
|
+
capabilities: ["http.fetch", "patent.get"]
|
|
63
|
+
minimum_capability: http.fetch
|
|
64
|
+
trust: public
|
|
65
|
+
confidentiality: public
|
|
66
|
+
quarantine: false
|
|
67
|
+
schema_version: v2
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @owner src::adapters::uspto::legal-status
|
|
2
|
+
# @does Fetch USPTO transaction history (PAIR) for an application — used to derive legal-status (issued, abandoned, pending, etc.).
|
|
3
|
+
# @needs src/engine/steps/fetch.ts, src/engine/steps/select.ts, src/engine/steps/map.ts
|
|
4
|
+
# @feeds src/commands/patent.ts
|
|
5
|
+
# @breaks throws PipelineError on 401/403/404
|
|
6
|
+
# @invariants output rows conform to PatentRecord; legal_status carries the latest transaction description
|
|
7
|
+
# @side-effects reads env USPTO_ODP_API_KEY; HTTPS egress to api.uspto.gov
|
|
8
|
+
# @perf single request
|
|
9
|
+
# @concurrency safe
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-key — needs USPTO_ODP_API_KEY
|
|
14
|
+
site: uspto
|
|
15
|
+
name: legal-status
|
|
16
|
+
description: Legal-status / transaction history of a USPTO application
|
|
17
|
+
domain: api.uspto.gov
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args:
|
|
23
|
+
application_number:
|
|
24
|
+
type: str
|
|
25
|
+
required: true
|
|
26
|
+
positional: true
|
|
27
|
+
description: USPTO application number
|
|
28
|
+
|
|
29
|
+
pipeline:
|
|
30
|
+
- fetch:
|
|
31
|
+
url: "https://api.uspto.gov/api/v1/patent/applications/${{ args.application_number | replace('/', '') | replace(',', '') }}/transactions"
|
|
32
|
+
method: GET
|
|
33
|
+
headers:
|
|
34
|
+
Accept: application/json
|
|
35
|
+
X-API-KEY: "${{ env.USPTO_ODP_API_KEY || '' }}"
|
|
36
|
+
|
|
37
|
+
- select: eventDataBag
|
|
38
|
+
|
|
39
|
+
# Each row is a transaction event; the ODP `transactions` endpoint returns
|
|
40
|
+
# eventCode + eventDescriptionText + eventDate per transaction.
|
|
41
|
+
- map:
|
|
42
|
+
publication_number: "${{ 'US-' + (args.application_number || '') }}"
|
|
43
|
+
application_number: "${{ args.application_number }}"
|
|
44
|
+
legal_status: "${{ (item.eventCode || '') + (item.eventDescriptionText ? (' ' + item.eventDescriptionText) : '') }}"
|
|
45
|
+
filing_date: "${{ item.eventDate || '' }}"
|
|
46
|
+
source_adapter: uspto
|
|
47
|
+
source_url: "${{ 'https://ppubs.uspto.gov/dirsearch-public/patents/' + (args.application_number || '') }}"
|
|
48
|
+
retrieved_at: ""
|
|
49
|
+
|
|
50
|
+
columns: [publication_number, legal_status, filing_date]
|
|
51
|
+
|
|
52
|
+
# schema-v2 metadata
|
|
53
|
+
capabilities: ["http.fetch", "patent.legal-status"]
|
|
54
|
+
minimum_capability: http.fetch
|
|
55
|
+
trust: public
|
|
56
|
+
confidentiality: public
|
|
57
|
+
quarantine: false
|
|
58
|
+
schema_version: v2
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @owner src::adapters::uspto::search
|
|
2
|
+
# @does Search USPTO patents/applications via the Open Data Portal (ODP) `applications/search` endpoint.
|
|
3
|
+
# @needs src/engine/steps/fetch.ts, src/engine/steps/select.ts, src/engine/steps/map.ts, src/engine/steps/limit.ts
|
|
4
|
+
# @feeds src/commands/patent.ts (meta-command aggregator)
|
|
5
|
+
# @breaks throws PipelineError on 401/403 (missing/invalid X-API-KEY) or 5xx; ODP enforces a 6 MB response cap — narrow the query if hit
|
|
6
|
+
# @invariants output rows conform to PatentRecord; publication_number is canonicalized to ST.16 form `US-<doc>-<kind>`
|
|
7
|
+
# @side-effects reads env USPTO_ODP_API_KEY; HTTPS egress to api.uspto.gov
|
|
8
|
+
# @perf single request, ODP returns up to 500 records per page
|
|
9
|
+
# @concurrency single-call; no shared mutable state
|
|
10
|
+
# @test none yet (adapter ships; live verification gated on key)
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-key — needs USPTO_ODP_API_KEY (free tier at developer.uspto.gov)
|
|
14
|
+
site: uspto
|
|
15
|
+
name: search
|
|
16
|
+
description: Search USPTO patents/applications via the Open Data Portal (ODP)
|
|
17
|
+
domain: api.uspto.gov
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args:
|
|
23
|
+
query:
|
|
24
|
+
type: str
|
|
25
|
+
required: true
|
|
26
|
+
positional: true
|
|
27
|
+
description: Free-text query (mapped to ODP `q` field, matches title/abstract/claims)
|
|
28
|
+
limit:
|
|
29
|
+
type: int
|
|
30
|
+
default: 25
|
|
31
|
+
description: Maximum results to return (ODP allows up to 500 per page)
|
|
32
|
+
offset:
|
|
33
|
+
type: int
|
|
34
|
+
default: 0
|
|
35
|
+
description: Result offset for pagination
|
|
36
|
+
|
|
37
|
+
pipeline:
|
|
38
|
+
- fetch:
|
|
39
|
+
url: "https://api.uspto.gov/api/v1/patent/applications/search"
|
|
40
|
+
method: GET
|
|
41
|
+
headers:
|
|
42
|
+
Accept: application/json
|
|
43
|
+
X-API-KEY: "${{ env.USPTO_ODP_API_KEY || '' }}"
|
|
44
|
+
params:
|
|
45
|
+
q: "${{ args.query }}"
|
|
46
|
+
limit: "${{ args.limit }}"
|
|
47
|
+
offset: "${{ args.offset }}"
|
|
48
|
+
|
|
49
|
+
- select: patentFileWrapperDataBag
|
|
50
|
+
|
|
51
|
+
# Field mapping references data.uspto.gov/swagger v1 patent applications schema.
|
|
52
|
+
# Every field below maps to a documented ODP response path — adapters must
|
|
53
|
+
# not synthesise values upstream did not return.
|
|
54
|
+
- map:
|
|
55
|
+
publication_number: "${{ item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber ? ('US-' + item.applicationMetaData.earliestPublicationNumber) : ('US-' + (item.applicationNumberText || '')) }}"
|
|
56
|
+
application_number: "${{ item.applicationNumberText || '' }}"
|
|
57
|
+
title: "${{ item.applicationMetaData ? (item.applicationMetaData.inventionTitle || '') : '' }}"
|
|
58
|
+
abstract: "${{ item.applicationMetaData ? (item.applicationMetaData.abstractText || '') : '' }}"
|
|
59
|
+
filing_date: "${{ item.applicationMetaData ? (item.applicationMetaData.filingDate || '') : '' }}"
|
|
60
|
+
publication_date: "${{ item.applicationMetaData ? (item.applicationMetaData.earliestPublicationDate || '') : '' }}"
|
|
61
|
+
grant_date: "${{ item.applicationMetaData ? (item.applicationMetaData.grantDate || '') : '' }}"
|
|
62
|
+
# ODP `applicationMetaData.earliestPublicationNumber` is the compact form
|
|
63
|
+
# (`20240123456A1`); the trailing A1/A2/B1/B2 IS the ST.16 kind code.
|
|
64
|
+
kind_code: "${{ (item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber) ? (item.applicationMetaData.earliestPublicationNumber.match(/[A-Z]\\d?$/) || [''])[0] : '' }}"
|
|
65
|
+
# ODP `inventorBag[]` and `applicantBag[]` carry per-party records.
|
|
66
|
+
# We serialise via JSON.stringify so the array survives the template
|
|
67
|
+
# engine's string projection; coerceToPatentRecords parses it back.
|
|
68
|
+
inventors: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.inventorBag) ? item.applicationMetaData.inventorBag.map(p => ({ name: p.inventorNameText || ((p.firstName || '') + ' ' + (p.lastName || '')).trim(), country: p.countryCode || undefined })) : []) }}"
|
|
69
|
+
assignees: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.applicantBag) ? item.applicationMetaData.applicantBag.map(p => ({ name: p.applicantNameText || p.organizationNameText || '', country: p.countryCode || undefined })) : []) }}"
|
|
70
|
+
# `cpcClassificationBag[]` is the ODP path for Cooperative Patent Classification codes.
|
|
71
|
+
classifications: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.cpcClassificationBag) ? item.applicationMetaData.cpcClassificationBag.map(c => ({ scheme: 'cpc', code: c.cpcSymbol || c })) : []) }}"
|
|
72
|
+
legal_status: "${{ item.applicationMetaData ? (item.applicationMetaData.applicationStatusDescriptionText || '') : '' }}"
|
|
73
|
+
source_adapter: uspto
|
|
74
|
+
source_url: "${{ 'https://ppubs.uspto.gov/dirsearch-public/patents/' + (item.applicationNumberText || '') }}"
|
|
75
|
+
# retrieved_at is stamped by assemblePatentRecord in the normalizer; YAML emits the empty string
|
|
76
|
+
retrieved_at: ""
|
|
77
|
+
|
|
78
|
+
- limit: "${{ args.limit }}"
|
|
79
|
+
|
|
80
|
+
columns: [publication_number, title, filing_date, publication_date]
|
|
81
|
+
|
|
82
|
+
# schema-v2 metadata
|
|
83
|
+
capabilities: ["http.fetch", "patent.search"]
|
|
84
|
+
minimum_capability: http.fetch
|
|
85
|
+
trust: public
|
|
86
|
+
confidentiality: public
|
|
87
|
+
quarantine: false
|
|
88
|
+
schema_version: v2
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @owner src::adapters::wipo-patentscope::info
|
|
2
|
+
# @does Registry placeholder for WIPO PATENTSCOPE — surfaces a structured PATENT_API_DEPRECATED envelope so `unicli patent doctor` and `unicli list` advertise the gap, without claiming false coverage.
|
|
3
|
+
# @needs src/engine/steps/assert.ts
|
|
4
|
+
# @feeds src/commands/patent.ts (meta-command discovery via `patent.*` capability)
|
|
5
|
+
# @breaks always throws PipelineError carrying a PATENT_API_DEPRECATED message; never silently returns rows
|
|
6
|
+
# @invariants no HTTPS egress; no env reads; no caller-visible state beyond the error envelope
|
|
7
|
+
# @side-effects none — the assertion is purely local
|
|
8
|
+
# @perf n/a — fails before any I/O
|
|
9
|
+
# @concurrency safe (pure local assertion)
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability experimental — replace with a real adapter when WIPO ships a token-based REST/GraphQL API
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-subscription — PATENTSCOPE exposes only a SOAP web service that requires a paid subscription (~CHF 600/year per third-party gem README; see https://patentscope.wipo.int/search/en/sub_user.jsf). Until WIPO ships a token-based REST/GraphQL surface, this adapter is a registry placeholder.
|
|
14
|
+
site: wipo-patentscope
|
|
15
|
+
name: info
|
|
16
|
+
description: WIPO PATENTSCOPE registry placeholder — no public REST API; SOAP requires subscription
|
|
17
|
+
domain: patentscope.wipo.int
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args: {}
|
|
23
|
+
|
|
24
|
+
pipeline:
|
|
25
|
+
# Fail closed with a structured envelope that the agent can read and act on.
|
|
26
|
+
# The message names the upstream channel and the subscription URL so the
|
|
27
|
+
# caller has a concrete next step — no silent fallback, no fake row.
|
|
28
|
+
- assert:
|
|
29
|
+
condition: "false"
|
|
30
|
+
message: "PATENT_API_DEPRECATED: WIPO PATENTSCOPE exposes only a SOAP web service that requires a paid subscription. Subscribe at https://patentscope.wipo.int/search/en/sub_user.jsf, or fall back to Espacenet for WO-prefixed publications (EPO brokers PCT family lookups)."
|
|
31
|
+
|
|
32
|
+
columns: []
|
|
33
|
+
|
|
34
|
+
# schema-v2 metadata
|
|
35
|
+
# The patent.* capability is what makes `unicli patent doctor` discover this
|
|
36
|
+
# adapter so the gap is reported in the doctor table; assert.fail is the
|
|
37
|
+
# step the dispatcher actually invokes at runtime.
|
|
38
|
+
capabilities: ["assert", "patent.search", "patent.get"]
|
|
39
|
+
minimum_capability: assert
|
|
40
|
+
trust: public
|
|
41
|
+
confidentiality: public
|
|
42
|
+
quarantine: false
|
|
43
|
+
schema_version: v2
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner Xiaohongshu browser adapters.
|
|
3
|
+
* @does Detects login, risk-control, and rendered-feed state in XHS web pages.
|
|
4
|
+
* @needs Browser-backed IPage from Uni-CLI runtime.
|
|
5
|
+
* @feeds xiaohongshu.search and xiaohongshu.trending.
|
|
6
|
+
* @breaks XHS copy or route changes can require updating page-state detection.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { IPage } from "../../types.js";
|
|
10
|
+
import {
|
|
11
|
+
socialAuthError,
|
|
12
|
+
socialChallengeError,
|
|
13
|
+
} from "../../social/browser-errors.js";
|
|
14
|
+
|
|
15
|
+
interface XhsPageState {
|
|
16
|
+
url: string;
|
|
17
|
+
title: string;
|
|
18
|
+
text: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function readXhsPageState(page: IPage): Promise<XhsPageState> {
|
|
22
|
+
const raw = await page.evaluate(`
|
|
23
|
+
(() => ({
|
|
24
|
+
url: window.location.href,
|
|
25
|
+
title: document.title || '',
|
|
26
|
+
text: (document.body?.innerText || '').replace(/\\s+/g, ' ').slice(0, 2000)
|
|
27
|
+
}))()
|
|
28
|
+
`);
|
|
29
|
+
const state = raw as Partial<XhsPageState>;
|
|
30
|
+
return {
|
|
31
|
+
url: String(state.url ?? ""),
|
|
32
|
+
title: String(state.title ?? ""),
|
|
33
|
+
text: String(state.text ?? ""),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function assertXhsReadableState(
|
|
38
|
+
command: string,
|
|
39
|
+
state: XhsPageState,
|
|
40
|
+
): void {
|
|
41
|
+
const haystack = `${state.url}\n${state.title}\n${state.text}`;
|
|
42
|
+
if (
|
|
43
|
+
/website-login\/error|安全限制|IP存在风险|风险|风控|安全验证|验证码|人机验证|verify|captcha/i.test(
|
|
44
|
+
haystack,
|
|
45
|
+
)
|
|
46
|
+
) {
|
|
47
|
+
throw socialChallengeError(
|
|
48
|
+
"xiaohongshu",
|
|
49
|
+
command,
|
|
50
|
+
`Xiaohongshu is showing a risk-control or verification page: ${state.title || state.url}`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
if (/登录后查看|登录后|请先登录|login/i.test(haystack)) {
|
|
54
|
+
throw socialAuthError("xiaohongshu", command);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function assertXhsReadable(
|
|
59
|
+
page: IPage,
|
|
60
|
+
command: string,
|
|
61
|
+
): Promise<void> {
|
|
62
|
+
assertXhsReadableState(command, await readXhsPageState(page));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function fetchXhsFeedItems(page: IPage): Promise<unknown[]> {
|
|
66
|
+
const raw = await page.evaluate(`
|
|
67
|
+
(async () => {
|
|
68
|
+
const app = document.querySelector('#app')?.__vue_app__;
|
|
69
|
+
if (!app) throw new Error('Xiaohongshu Vue app not found');
|
|
70
|
+
const pinia = app.config?.globalProperties?.$pinia;
|
|
71
|
+
if (!pinia || !pinia._s?.has('feed')) throw new Error('Xiaohongshu feed store not found');
|
|
72
|
+
const store = pinia._s.get('feed');
|
|
73
|
+
const captured = [];
|
|
74
|
+
const originalFetch = window.fetch;
|
|
75
|
+
window.fetch = async (...args) => {
|
|
76
|
+
const response = await originalFetch(...args);
|
|
77
|
+
try {
|
|
78
|
+
const url = String(args[0]?.url || args[0] || '');
|
|
79
|
+
if (/homefeed|feed/i.test(url)) {
|
|
80
|
+
captured.push(await response.clone().json());
|
|
81
|
+
}
|
|
82
|
+
} catch {}
|
|
83
|
+
return response;
|
|
84
|
+
};
|
|
85
|
+
try {
|
|
86
|
+
await store.fetchFeeds();
|
|
87
|
+
} finally {
|
|
88
|
+
window.fetch = originalFetch;
|
|
89
|
+
}
|
|
90
|
+
const payload = captured.find((item) => item?.data?.items?.length) || captured[0];
|
|
91
|
+
return payload?.data?.items || [];
|
|
92
|
+
})()
|
|
93
|
+
`);
|
|
94
|
+
return Array.isArray(raw) ? raw : [];
|
|
95
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { cli, Strategy } from "../../registry.js";
|
|
9
9
|
import type { IPage } from "../../types.js";
|
|
10
|
+
import { normalizeCommentRows } from "../../social/comments.js";
|
|
10
11
|
import { buildNoteUrl } from "./note-helpers.js";
|
|
11
12
|
|
|
12
13
|
function parseCommentLimit(raw: unknown, fallback = 20): number {
|
|
@@ -42,7 +43,23 @@ cli({
|
|
|
42
43
|
description: "Include nested replies",
|
|
43
44
|
},
|
|
44
45
|
],
|
|
45
|
-
columns: [
|
|
46
|
+
columns: [
|
|
47
|
+
"rank",
|
|
48
|
+
"platform",
|
|
49
|
+
"content_id",
|
|
50
|
+
"comment_id",
|
|
51
|
+
"parent_id",
|
|
52
|
+
"depth",
|
|
53
|
+
"path",
|
|
54
|
+
"author",
|
|
55
|
+
"text",
|
|
56
|
+
"likes",
|
|
57
|
+
"replies",
|
|
58
|
+
"created",
|
|
59
|
+
"time",
|
|
60
|
+
"is_reply",
|
|
61
|
+
"reply_to",
|
|
62
|
+
],
|
|
46
63
|
func: async (page, kwargs) => {
|
|
47
64
|
const p = page as IPage;
|
|
48
65
|
const limit = parseCommentLimit(kwargs.limit);
|
|
@@ -100,7 +117,7 @@ cli({
|
|
|
100
117
|
const likes = parseLikes(item.querySelector('.count'))
|
|
101
118
|
const time = clean(item.querySelector('.date, .time'))
|
|
102
119
|
if (!text) continue
|
|
103
|
-
results.push({ author, text, likes, time, is_reply: false, reply_to: '' })
|
|
120
|
+
results.push({ author, text, likes, replies: 0, created: time, time, is_reply: false, reply_to: '' })
|
|
104
121
|
if (withReplies) {
|
|
105
122
|
await expandReplyThreads(p)
|
|
106
123
|
p.querySelectorAll('.reply-container .comment-item-sub, .sub-comment-list .comment-item').forEach(sub => {
|
|
@@ -109,7 +126,7 @@ cli({
|
|
|
109
126
|
const sLikes = parseLikes(sub.querySelector('.count'))
|
|
110
127
|
const sTime = clean(sub.querySelector('.date, .time'))
|
|
111
128
|
if (!sText) return
|
|
112
|
-
results.push({ author: sAuthor, text: sText, likes: sLikes, time: sTime, is_reply: true, reply_to: author })
|
|
129
|
+
results.push({ author: sAuthor, text: sText, likes: sLikes, replies: 0, created: sTime, time: sTime, is_reply: true, reply_to: author })
|
|
113
130
|
})
|
|
114
131
|
}
|
|
115
132
|
}
|
|
@@ -125,7 +142,7 @@ cli({
|
|
|
125
142
|
throw new Error("Note comments require login to www.xiaohongshu.com");
|
|
126
143
|
}
|
|
127
144
|
|
|
128
|
-
interface CommentRow {
|
|
145
|
+
interface CommentRow extends Record<string, unknown> {
|
|
129
146
|
author: string;
|
|
130
147
|
text: string;
|
|
131
148
|
likes: number;
|
|
@@ -144,9 +161,15 @@ cli({
|
|
|
144
161
|
if (topCount > limit) break;
|
|
145
162
|
limited.push(c);
|
|
146
163
|
}
|
|
147
|
-
return limited
|
|
164
|
+
return normalizeCommentRows(limited, {
|
|
165
|
+
platform: "xiaohongshu",
|
|
166
|
+
contentId: raw,
|
|
167
|
+
}).map((c, i) => ({ rank: i + 1, ...c }));
|
|
148
168
|
}
|
|
149
169
|
|
|
150
|
-
return all.slice(0, limit)
|
|
170
|
+
return normalizeCommentRows(all.slice(0, limit), {
|
|
171
|
+
platform: "xiaohongshu",
|
|
172
|
+
contentId: raw,
|
|
173
|
+
}).map((c, i) => ({ rank: i + 1, ...c }));
|
|
151
174
|
},
|
|
152
175
|
});
|