@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
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::adapters::cnipa::search
|
|
3
|
+
* @does Browser-driven search of CNIPA 公众查询 system at pss-system.cponline.cnipa.gov.cn — the only programmatic route for CN patents (CNIPA has no open API today). Drives a real Chrome session via the mcp-browser transport, extracts result rows, normalizes through assemblePatentRecord.
|
|
4
|
+
* @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/types/patent.ts, src/adapters/cnipa/_shared.ts, src/registry.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (meta-command discovers via patent.search capability tag)
|
|
6
|
+
* @breaks emits PATENT_BROWSER_CAPTCHA envelope when zero rows return from a navigation that did not error (CNIPA almost always shows a captcha gate); emits PATENT_API_DEPRECATED with MCP_BUS_MISSING context when no outbound MCP transport is registered
|
|
7
|
+
* @invariants result rows always include source_adapter='cnipa'; publication_number canonicalized via assemblePatentRecord; never returns a synthetic row when extraction fails
|
|
8
|
+
* @side-effects controls the user's Chrome browser via MCP; reads no env vars
|
|
9
|
+
* @perf single navigation + one evaluate; ~2-5 s wall-clock when active
|
|
10
|
+
* @concurrency safe — every call opens a fresh tab via mcpBrowserNavigate
|
|
11
|
+
* @test tests/unit/adapters/cnipa/search.test.ts
|
|
12
|
+
* @stability experimental
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
* @verification browser-only — no upstream API; gated on a live mcp-browser transport
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { cli, Strategy } from "../../registry.js";
|
|
18
|
+
import { TransportError } from "../../engine/transport/mcp-browser.js";
|
|
19
|
+
import { assemblePatentRecord } from "../../engine/normalizer/patent-envelope.js";
|
|
20
|
+
import {
|
|
21
|
+
cnipaEnvelope,
|
|
22
|
+
looksLikeCaptcha,
|
|
23
|
+
navigateAndExtract,
|
|
24
|
+
transportErrorToEnvelope,
|
|
25
|
+
} from "./_shared.js";
|
|
26
|
+
|
|
27
|
+
const ADAPTER_PATH = "src/adapters/cnipa/search.ts";
|
|
28
|
+
const CNIPA_SEARCH_URL =
|
|
29
|
+
"https://pss-system.cponline.cnipa.gov.cn/conventionalSearch";
|
|
30
|
+
|
|
31
|
+
interface CnipaRow {
|
|
32
|
+
publication_number: string;
|
|
33
|
+
application_number?: string;
|
|
34
|
+
title?: string;
|
|
35
|
+
applicant?: string;
|
|
36
|
+
publication_date?: string;
|
|
37
|
+
filing_date?: string;
|
|
38
|
+
source_url?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface CnipaExtractResult {
|
|
42
|
+
rows: CnipaRow[];
|
|
43
|
+
html_marker?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* DOM extractor executed inside the page via mcp-browser. The selectors are
|
|
48
|
+
* the documented ones for the CNIPA 公众查询 result table; when CNIPA
|
|
49
|
+
* changes the markup an agent reads the failure envelope and updates the
|
|
50
|
+
* selector here (rule 02 self-repair).
|
|
51
|
+
*/
|
|
52
|
+
const EXTRACTOR = `(() => {
|
|
53
|
+
const rows = Array.from(
|
|
54
|
+
document.querySelectorAll('table.result-table tbody tr, .result-list .result-item')
|
|
55
|
+
).map((el) => {
|
|
56
|
+
const text = (sel) => {
|
|
57
|
+
const node = el.querySelector(sel);
|
|
58
|
+
return node ? (node.textContent || '').trim() : '';
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
publication_number: text('.publication-number, [data-field="pubNo"]'),
|
|
62
|
+
application_number: text('.application-number, [data-field="appNo"]'),
|
|
63
|
+
title: text('.title, [data-field="title"]'),
|
|
64
|
+
applicant: text('.applicant, [data-field="applicant"]'),
|
|
65
|
+
publication_date: text('.publication-date, [data-field="pubDate"]'),
|
|
66
|
+
filing_date: text('.filing-date, [data-field="appDate"]'),
|
|
67
|
+
source_url: (el.querySelector('a[href]') || {}).href || '',
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
const html_marker = (document.body && document.body.innerText
|
|
71
|
+
? document.body.innerText.slice(0, 200)
|
|
72
|
+
: '');
|
|
73
|
+
return { rows, html_marker };
|
|
74
|
+
})()`;
|
|
75
|
+
|
|
76
|
+
function buildSearchUrl(query: string, limit: number, offset: number): string {
|
|
77
|
+
const params = new URLSearchParams({
|
|
78
|
+
q: query,
|
|
79
|
+
pageSize: String(limit),
|
|
80
|
+
pageNo: String(Math.floor(offset / Math.max(1, limit)) + 1),
|
|
81
|
+
});
|
|
82
|
+
return `${CNIPA_SEARCH_URL}?${params.toString()}`;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export async function runCnipaSearch(kwargs: {
|
|
86
|
+
query: string;
|
|
87
|
+
limit?: number;
|
|
88
|
+
offset?: number;
|
|
89
|
+
}): Promise<unknown[]> {
|
|
90
|
+
const limit =
|
|
91
|
+
typeof kwargs.limit === "number" && Number.isFinite(kwargs.limit)
|
|
92
|
+
? Math.max(1, Math.min(100, Math.floor(kwargs.limit)))
|
|
93
|
+
: 25;
|
|
94
|
+
const offset =
|
|
95
|
+
typeof kwargs.offset === "number" && Number.isFinite(kwargs.offset)
|
|
96
|
+
? Math.max(0, Math.floor(kwargs.offset))
|
|
97
|
+
: 0;
|
|
98
|
+
const query = String(kwargs.query ?? "").trim();
|
|
99
|
+
if (query.length === 0) {
|
|
100
|
+
return [
|
|
101
|
+
{
|
|
102
|
+
envelope: cnipaEnvelope(
|
|
103
|
+
"PATENT_UNSUPPORTED_QUERY",
|
|
104
|
+
ADAPTER_PATH,
|
|
105
|
+
"validate",
|
|
106
|
+
"cnipa search requires a non-empty query string",
|
|
107
|
+
),
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
const url = buildSearchUrl(query, limit, offset);
|
|
112
|
+
let extract: CnipaExtractResult;
|
|
113
|
+
try {
|
|
114
|
+
const result = await navigateAndExtract<CnipaExtractResult>(url, EXTRACTOR);
|
|
115
|
+
if (!result.data) {
|
|
116
|
+
return [
|
|
117
|
+
{
|
|
118
|
+
envelope: cnipaEnvelope(
|
|
119
|
+
"PATENT_SCHEMA_DRIFT",
|
|
120
|
+
ADAPTER_PATH,
|
|
121
|
+
"evaluate",
|
|
122
|
+
"mcp-browser evaluate returned no data; check selector schema in src/adapters/cnipa/search.ts",
|
|
123
|
+
),
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
}
|
|
127
|
+
extract = result.data;
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (err instanceof TransportError) {
|
|
130
|
+
return [
|
|
131
|
+
{
|
|
132
|
+
envelope: transportErrorToEnvelope(err, ADAPTER_PATH, "navigate"),
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
}
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (looksLikeCaptcha(extract.rows.length, extract.html_marker)) {
|
|
140
|
+
return [
|
|
141
|
+
{
|
|
142
|
+
envelope: cnipaEnvelope(
|
|
143
|
+
"PATENT_BROWSER_CAPTCHA",
|
|
144
|
+
ADAPTER_PATH,
|
|
145
|
+
"evaluate",
|
|
146
|
+
"CNIPA returned no rows for a non-empty query; solve the 验证码 in the open browser tab and re-run",
|
|
147
|
+
["espacenet", "lens"],
|
|
148
|
+
),
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const out: unknown[] = [];
|
|
154
|
+
for (const row of extract.rows.slice(0, limit)) {
|
|
155
|
+
if (!row.publication_number) continue;
|
|
156
|
+
try {
|
|
157
|
+
out.push(
|
|
158
|
+
assemblePatentRecord({
|
|
159
|
+
publication_number: row.publication_number,
|
|
160
|
+
application_number: row.application_number || undefined,
|
|
161
|
+
title: row.title || undefined,
|
|
162
|
+
assignees: row.applicant
|
|
163
|
+
? [{ name: row.applicant, country: "CN" }]
|
|
164
|
+
: undefined,
|
|
165
|
+
publication_date: row.publication_date || undefined,
|
|
166
|
+
filing_date: row.filing_date || undefined,
|
|
167
|
+
source_adapter: "cnipa",
|
|
168
|
+
source_url: row.source_url || url,
|
|
169
|
+
} as Parameters<typeof assemblePatentRecord>[0]),
|
|
170
|
+
);
|
|
171
|
+
} catch {
|
|
172
|
+
// Skip malformed row rather than synthesize — rule 02.
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (out.length === 0) {
|
|
176
|
+
out.push({
|
|
177
|
+
envelope: cnipaEnvelope(
|
|
178
|
+
"PATENT_NOT_FOUND",
|
|
179
|
+
ADAPTER_PATH,
|
|
180
|
+
"normalize",
|
|
181
|
+
"cnipa returned rows but none carried a publication_number; report as schema drift",
|
|
182
|
+
["espacenet"],
|
|
183
|
+
),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
cli({
|
|
190
|
+
site: "cnipa",
|
|
191
|
+
name: "search",
|
|
192
|
+
description:
|
|
193
|
+
"Search CNIPA via the public 公众查询 browser interface (no API)",
|
|
194
|
+
domain: "pss-system.cponline.cnipa.gov.cn",
|
|
195
|
+
strategy: Strategy.PUBLIC,
|
|
196
|
+
adapter_path: ADAPTER_PATH,
|
|
197
|
+
args: [
|
|
198
|
+
{
|
|
199
|
+
name: "query",
|
|
200
|
+
type: "str",
|
|
201
|
+
required: true,
|
|
202
|
+
positional: true,
|
|
203
|
+
description: "Free-text query — matched against title/abstract/claims",
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: "limit",
|
|
207
|
+
type: "int",
|
|
208
|
+
default: 25,
|
|
209
|
+
description: "Maximum results to return (1-100)",
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: "offset",
|
|
213
|
+
type: "int",
|
|
214
|
+
default: 0,
|
|
215
|
+
description: "Result offset for pagination",
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
columns: ["publication_number", "title", "publication_date", "source_url"],
|
|
219
|
+
capabilities: [
|
|
220
|
+
"mcp-browser.navigate",
|
|
221
|
+
"mcp-browser.evaluate",
|
|
222
|
+
"patent.search",
|
|
223
|
+
],
|
|
224
|
+
minimum_capability: "mcp-browser.evaluate",
|
|
225
|
+
func: async (_page, kwargs) =>
|
|
226
|
+
runCnipaSearch(
|
|
227
|
+
kwargs as { query: string; limit?: number; offset?: number },
|
|
228
|
+
),
|
|
229
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @owner src::adapters::dpma::get
|
|
2
|
+
# @does Fetch a German patent record by publication number via DPMAconnectPlus REST.
|
|
3
|
+
# @needs src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts
|
|
4
|
+
# @feeds src/commands/patent.ts
|
|
5
|
+
# @breaks throws PipelineError on 401/403, 404, 5xx
|
|
6
|
+
# @invariants output row conforms to PatentRecord
|
|
7
|
+
# @side-effects reads env DPMA_AUTHORIZATION; HTTPS egress to dpmaconnect.dpma.de
|
|
8
|
+
# @perf single request
|
|
9
|
+
# @concurrency safe
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-subscription
|
|
14
|
+
site: dpma
|
|
15
|
+
name: get
|
|
16
|
+
description: Fetch a German patent record by publication number (subscription)
|
|
17
|
+
domain: dpmaconnect.dpma.de
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args:
|
|
23
|
+
publication_number:
|
|
24
|
+
type: str
|
|
25
|
+
required: true
|
|
26
|
+
positional: true
|
|
27
|
+
description: German publication number (e.g. DE102023012345)
|
|
28
|
+
|
|
29
|
+
pipeline:
|
|
30
|
+
- fetch:
|
|
31
|
+
url: "https://dpmaconnect.dpma.de/dpmaconnectplus/rest/document/${{ args.publication_number | urlencode }}"
|
|
32
|
+
method: GET
|
|
33
|
+
headers:
|
|
34
|
+
Accept: application/xml
|
|
35
|
+
Authorization: "${{ env.DPMA_AUTHORIZATION || '' }}"
|
|
36
|
+
|
|
37
|
+
- select-xml:
|
|
38
|
+
xpath: "//record"
|
|
39
|
+
unwrap_single: true
|
|
40
|
+
|
|
41
|
+
- map:
|
|
42
|
+
publication_number: "${{ 'DE-' + (item.publicationNumber || args.publication_number || '') + '-' + (item.kindCode || '') }}"
|
|
43
|
+
application_number: "${{ item.applicationNumber || '' }}"
|
|
44
|
+
title: "${{ item.title || item.titleDe || item.titleEn || '' }}"
|
|
45
|
+
abstract: "${{ item.abstract || item.abstractDe || item.abstractEn || '' }}"
|
|
46
|
+
kind_code: "${{ item.kindCode || '' }}"
|
|
47
|
+
filing_date: "${{ item.filingDate || '' }}"
|
|
48
|
+
publication_date: "${{ item.publicationDate || '' }}"
|
|
49
|
+
grant_date: "${{ item.grantDate || '' }}"
|
|
50
|
+
priority_date: "${{ item.priorityDate || '' }}"
|
|
51
|
+
legal_status: "${{ item.legalStatus || item.status || '' }}"
|
|
52
|
+
inventors: "${{ JSON.stringify((function(){ var i=item.inventor || item.inventors; if(!i) return []; var arr = Array.isArray(i) ? i : [i]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
|
|
53
|
+
assignees: "${{ JSON.stringify((function(){ var a=item.applicant || item.applicants; if(!a) return []; var arr = Array.isArray(a) ? a : [a]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
|
|
54
|
+
classifications: "${{ JSON.stringify((function(){ var c=item.ipc || item.classifications; if(!c) return []; var arr = Array.isArray(c) ? c : [c]; return arr.map(x => ({ scheme: 'ipc', code: typeof x === 'string' ? x : (x.code || '') })).filter(x => x.code); })()) }}"
|
|
55
|
+
source_adapter: dpma
|
|
56
|
+
source_url: "${{ 'https://register.dpma.de/DPMAregister/pat/register?AKZ=' + (item.applicationNumber || '') }}"
|
|
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,77 @@
|
|
|
1
|
+
# @owner src::adapters::dpma::search
|
|
2
|
+
# @does Search German patents via the DPMAconnectPlus REST API (XML / OAI-PMH-style envelope).
|
|
3
|
+
# @needs src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts, src/engine/steps/limit.ts
|
|
4
|
+
# @feeds src/commands/patent.ts
|
|
5
|
+
# @breaks throws PipelineError on 401/403 (missing DPMA_AUTHORIZATION precomputed `Basic <base64>` header), 4xx, 5xx
|
|
6
|
+
# @invariants output rows conform to PatentRecord; publication_number is `DE-<doc>-<kind>`
|
|
7
|
+
# @side-effects reads env DPMA_AUTHORIZATION (precomputed `Basic <base64(user:pass)>`); HTTPS egress to dpmaconnect.dpma.de
|
|
8
|
+
# @perf single request
|
|
9
|
+
# @concurrency safe
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-subscription — DPMAconnectPlus requires a paid connection contract (~200 EUR setup). Adapter ships so contracted users can run it; precompute `DPMA_AUTHORIZATION="Basic $(printf '%s:%s' "$USER" "$PASS" | base64)"` before invocation.
|
|
14
|
+
site: dpma
|
|
15
|
+
name: search
|
|
16
|
+
description: Search German patents via DPMAconnectPlus REST (subscription)
|
|
17
|
+
domain: dpmaconnect.dpma.de
|
|
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: DPMA query (free-text, mapped to title/abstract)
|
|
28
|
+
limit:
|
|
29
|
+
type: int
|
|
30
|
+
default: 25
|
|
31
|
+
description: Maximum results
|
|
32
|
+
|
|
33
|
+
pipeline:
|
|
34
|
+
- fetch:
|
|
35
|
+
url: "https://dpmaconnect.dpma.de/dpmaconnectplus/rest/search/published"
|
|
36
|
+
method: GET
|
|
37
|
+
headers:
|
|
38
|
+
Accept: application/xml
|
|
39
|
+
Authorization: "${{ env.DPMA_AUTHORIZATION || '' }}"
|
|
40
|
+
params:
|
|
41
|
+
query: "${{ args.query }}"
|
|
42
|
+
maximumRecords: "${{ args.limit }}"
|
|
43
|
+
startRecord: "1"
|
|
44
|
+
|
|
45
|
+
- select-xml:
|
|
46
|
+
xpath: "//record"
|
|
47
|
+
|
|
48
|
+
# DPMAconnectPlus XML mirrors INPI / EPO field naming; preserve German
|
|
49
|
+
# script in title / abstract.
|
|
50
|
+
- map:
|
|
51
|
+
publication_number: "${{ 'DE-' + (item.publicationNumber || '') + '-' + (item.kindCode || '') }}"
|
|
52
|
+
application_number: "${{ item.applicationNumber || '' }}"
|
|
53
|
+
title: "${{ item.title || item.titleDe || item.titleEn || '' }}"
|
|
54
|
+
abstract: "${{ item.abstract || item.abstractDe || item.abstractEn || '' }}"
|
|
55
|
+
kind_code: "${{ item.kindCode || '' }}"
|
|
56
|
+
filing_date: "${{ item.filingDate || '' }}"
|
|
57
|
+
publication_date: "${{ item.publicationDate || '' }}"
|
|
58
|
+
grant_date: "${{ item.grantDate || '' }}"
|
|
59
|
+
priority_date: "${{ item.priorityDate || '' }}"
|
|
60
|
+
inventors: "${{ JSON.stringify((function(){ var i=item.inventor || item.inventors; if(!i) return []; var arr = Array.isArray(i) ? i : [i]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
|
|
61
|
+
assignees: "${{ JSON.stringify((function(){ var a=item.applicant || item.applicants; if(!a) return []; var arr = Array.isArray(a) ? a : [a]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
|
|
62
|
+
classifications: "${{ JSON.stringify((function(){ var c=item.ipc || item.classifications; if(!c) return []; var arr = Array.isArray(c) ? c : [c]; return arr.map(x => ({ scheme: 'ipc', code: typeof x === 'string' ? x : (x.code || '') })).filter(x => x.code); })()) }}"
|
|
63
|
+
source_adapter: dpma
|
|
64
|
+
source_url: "${{ 'https://register.dpma.de/DPMAregister/pat/register?AKZ=' + (item.applicationNumber || '') }}"
|
|
65
|
+
retrieved_at: ""
|
|
66
|
+
|
|
67
|
+
- limit: "${{ args.limit }}"
|
|
68
|
+
|
|
69
|
+
columns: [publication_number, title, filing_date, publication_date]
|
|
70
|
+
|
|
71
|
+
# schema-v2 metadata
|
|
72
|
+
capabilities: ["http.fetch", "patent.search"]
|
|
73
|
+
minimum_capability: http.fetch
|
|
74
|
+
trust: public
|
|
75
|
+
confidentiality: public
|
|
76
|
+
quarantine: false
|
|
77
|
+
schema_version: v2
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# DuckDuckGo Search — keyless HTML lite endpoint.
|
|
2
|
+
#
|
|
3
|
+
# verification_status: keyless-best-effort
|
|
4
|
+
#
|
|
5
|
+
# DuckDuckGo runs an Instant-Answer JSON API at api.duckduckgo.com that
|
|
6
|
+
# returns disambiguation pages and zero web results, plus a lite HTML
|
|
7
|
+
# search at https://html.duckduckgo.com/html that returns SSR result rows
|
|
8
|
+
# without JS. We use the lite HTML path so a fresh user gets web results
|
|
9
|
+
# with no token of any kind. DDG rate-limits aggressive scraping; the
|
|
10
|
+
# adapter is for human-scale interactive use.
|
|
11
|
+
site: duckduckgo
|
|
12
|
+
name: search
|
|
13
|
+
description: Search the public web via DuckDuckGo (no API key needed)
|
|
14
|
+
type: web-api
|
|
15
|
+
domain: html.duckduckgo.com
|
|
16
|
+
strategy: public
|
|
17
|
+
lint_listing_detail: skip
|
|
18
|
+
|
|
19
|
+
args:
|
|
20
|
+
query:
|
|
21
|
+
type: str
|
|
22
|
+
required: true
|
|
23
|
+
positional: true
|
|
24
|
+
description: Free-text web search query
|
|
25
|
+
limit:
|
|
26
|
+
type: int
|
|
27
|
+
default: 10
|
|
28
|
+
description: Maximum results returned (DDG lite caps at ~30 per page)
|
|
29
|
+
|
|
30
|
+
pipeline:
|
|
31
|
+
- fetch_text:
|
|
32
|
+
url: "https://html.duckduckgo.com/html/?q=${{ args.query | url_encode }}"
|
|
33
|
+
headers:
|
|
34
|
+
User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
|
|
35
|
+
Accept: "text/html,application/xhtml+xml"
|
|
36
|
+
|
|
37
|
+
- extract:
|
|
38
|
+
selector: "div.result"
|
|
39
|
+
fields:
|
|
40
|
+
title: "h2.result__title a"
|
|
41
|
+
url: "h2.result__title a@href"
|
|
42
|
+
snippet: "a.result__snippet"
|
|
43
|
+
|
|
44
|
+
- limit: ${{ args.limit }}
|
|
45
|
+
|
|
46
|
+
columns: [title, url, snippet]
|
|
47
|
+
|
|
48
|
+
# schema-v2 metadata
|
|
49
|
+
capabilities: ["http.fetch"]
|
|
50
|
+
minimum_capability: http.fetch
|
|
51
|
+
trust: public
|
|
52
|
+
confidentiality: public
|
|
53
|
+
quarantine: false
|
|
54
|
+
schema_version: v2
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# DuckDuckGo Autocomplete — keyless JSON endpoint.
|
|
2
|
+
#
|
|
3
|
+
# verification_status: keyless-best-effort
|
|
4
|
+
#
|
|
5
|
+
# The autocomplete endpoint at https://duckduckgo.com/ac is the JSON used
|
|
6
|
+
# by the DDG search box. No auth, no rate-limit gate at low volumes, and
|
|
7
|
+
# returns a flat list of suggested completions for a prefix.
|
|
8
|
+
site: duckduckgo
|
|
9
|
+
name: suggest
|
|
10
|
+
description: Get query autocompletion suggestions from DuckDuckGo
|
|
11
|
+
type: web-api
|
|
12
|
+
domain: duckduckgo.com
|
|
13
|
+
strategy: public
|
|
14
|
+
lint_listing_detail: skip
|
|
15
|
+
|
|
16
|
+
args:
|
|
17
|
+
query:
|
|
18
|
+
type: str
|
|
19
|
+
required: true
|
|
20
|
+
positional: true
|
|
21
|
+
description: Partial query prefix to autocomplete
|
|
22
|
+
limit:
|
|
23
|
+
type: int
|
|
24
|
+
default: 10
|
|
25
|
+
description: Maximum suggestions returned
|
|
26
|
+
|
|
27
|
+
pipeline:
|
|
28
|
+
- fetch:
|
|
29
|
+
url: "https://duckduckgo.com/ac/"
|
|
30
|
+
params:
|
|
31
|
+
q: "${{ args.query }}"
|
|
32
|
+
type: list
|
|
33
|
+
headers:
|
|
34
|
+
User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
|
|
35
|
+
Accept: "application/json"
|
|
36
|
+
|
|
37
|
+
- select: "1"
|
|
38
|
+
|
|
39
|
+
- map:
|
|
40
|
+
phrase: "${{ item }}"
|
|
41
|
+
|
|
42
|
+
- limit: ${{ args.limit }}
|
|
43
|
+
|
|
44
|
+
columns: [phrase]
|
|
45
|
+
|
|
46
|
+
# schema-v2 metadata
|
|
47
|
+
capabilities: ["http.fetch"]
|
|
48
|
+
minimum_capability: http.fetch
|
|
49
|
+
trust: public
|
|
50
|
+
confidentiality: public
|
|
51
|
+
quarantine: false
|
|
52
|
+
schema_version: v2
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @owner src::adapters::epo::family
|
|
2
|
+
# @does Fetch INPADOC simple family for a publication via EPO Open Patent Services v3.2.
|
|
3
|
+
# @needs src/engine/steps/oauth2-token.ts, src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts
|
|
4
|
+
# @feeds src/commands/patent.ts
|
|
5
|
+
# @breaks throws PipelineError on token failure, 404, 401/403, 5xx
|
|
6
|
+
# @invariants output rows are family members in PatentRecord shape with `family_id` populated
|
|
7
|
+
# @side-effects reads EPO OAuth2 credentials; HTTPS to ops.epo.org
|
|
8
|
+
# @perf two HTTPS requests
|
|
9
|
+
# @concurrency safe
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-key
|
|
14
|
+
site: epo
|
|
15
|
+
name: family
|
|
16
|
+
description: INPADOC simple family for an EPO publication
|
|
17
|
+
domain: ops.epo.org
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args:
|
|
23
|
+
publication_number:
|
|
24
|
+
type: str
|
|
25
|
+
required: true
|
|
26
|
+
positional: true
|
|
27
|
+
description: Publication number in epodoc format
|
|
28
|
+
|
|
29
|
+
pipeline:
|
|
30
|
+
- oauth2-token:
|
|
31
|
+
site: epo
|
|
32
|
+
token_url: https://ops.epo.org/3.2/auth/accesstoken
|
|
33
|
+
client_id_env: EPO_OPS_CLIENT_ID
|
|
34
|
+
client_secret_env: EPO_OPS_CLIENT_SECRET
|
|
35
|
+
|
|
36
|
+
- fetch:
|
|
37
|
+
url: "https://ops.epo.org/3.2/rest-services/family/publication/epodoc/${{ args.publication_number | urlencode }}"
|
|
38
|
+
method: GET
|
|
39
|
+
headers:
|
|
40
|
+
Authorization: "Bearer ${{ auth.bearer || '' }}"
|
|
41
|
+
Accept: application/xml
|
|
42
|
+
|
|
43
|
+
- select-xml:
|
|
44
|
+
xpath: "//ops:family-member"
|
|
45
|
+
namespaces:
|
|
46
|
+
ops: "http://ops.epo.org"
|
|
47
|
+
|
|
48
|
+
# Family endpoint returns ops:family-member nodes with publication-reference,
|
|
49
|
+
# application-reference, and a `@family-id` attribute on each.
|
|
50
|
+
- map:
|
|
51
|
+
publication_number: "${{ ((item['publication-reference'] && item['publication-reference']['document-id']) ? (item['publication-reference']['document-id'].country + '-' + item['publication-reference']['document-id']['doc-number'] + '-' + (item['publication-reference']['document-id'].kind || '')) : '') }}"
|
|
52
|
+
application_number: "${{ ((item['application-reference'] && item['application-reference']['document-id']) ? (item['application-reference']['document-id'].country + '-' + item['application-reference']['document-id']['doc-number'] + '-' + (item['application-reference']['document-id'].kind || '')) : '') }}"
|
|
53
|
+
kind_code: "${{ (item['publication-reference'] && item['publication-reference']['document-id']) ? (item['publication-reference']['document-id'].kind || '') : '' }}"
|
|
54
|
+
publication_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['publication-reference'] && item['publication-reference']['document-id']) ? item['publication-reference']['document-id'].date : '') }}"
|
|
55
|
+
filing_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['application-reference'] && item['application-reference']['document-id']) ? item['application-reference']['document-id'].date : '') }}"
|
|
56
|
+
family_id: "${{ item['@_family-id'] || '' }}"
|
|
57
|
+
source_adapter: epo
|
|
58
|
+
source_url: "${{ 'https://worldwide.espacenet.com/patent/search/family/' + (item['@_family-id'] || '') }}"
|
|
59
|
+
retrieved_at: ""
|
|
60
|
+
|
|
61
|
+
columns: [publication_number, family_id]
|
|
62
|
+
|
|
63
|
+
# schema-v2 metadata
|
|
64
|
+
capabilities: ["http.fetch", "patent.family"]
|
|
65
|
+
minimum_capability: http.fetch
|
|
66
|
+
trust: public
|
|
67
|
+
confidentiality: public
|
|
68
|
+
quarantine: false
|
|
69
|
+
schema_version: v2
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @owner src::adapters::epo::get
|
|
2
|
+
# @does Fetch DOCDB biblio for a single EPO publication number via Open Patent Services v3.2.
|
|
3
|
+
# @needs src/engine/steps/oauth2-token.ts, src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts
|
|
4
|
+
# @feeds src/commands/patent.ts
|
|
5
|
+
# @breaks throws PipelineError on token failure, 404 (unknown publication), 401/403, 5xx
|
|
6
|
+
# @invariants output row conforms to PatentRecord
|
|
7
|
+
# @side-effects reads EPO OAuth2 credentials; HTTPS to ops.epo.org
|
|
8
|
+
# @perf two HTTPS requests (token + data); cached token
|
|
9
|
+
# @concurrency safe
|
|
10
|
+
# @test none yet
|
|
11
|
+
# @stability stable
|
|
12
|
+
# @since 2026-05-18
|
|
13
|
+
# @verification blocked-by-key
|
|
14
|
+
site: epo
|
|
15
|
+
name: get
|
|
16
|
+
description: Fetch EPO DOCDB biblio for a single publication number
|
|
17
|
+
domain: ops.epo.org
|
|
18
|
+
type: web-api
|
|
19
|
+
strategy: public
|
|
20
|
+
lint_listing_detail: skip
|
|
21
|
+
|
|
22
|
+
args:
|
|
23
|
+
publication_number:
|
|
24
|
+
type: str
|
|
25
|
+
required: true
|
|
26
|
+
positional: true
|
|
27
|
+
description: Publication number in epodoc format (e.g. EP.4123456.A1 or US.20240123456.A1)
|
|
28
|
+
|
|
29
|
+
pipeline:
|
|
30
|
+
- oauth2-token:
|
|
31
|
+
site: epo
|
|
32
|
+
token_url: https://ops.epo.org/3.2/auth/accesstoken
|
|
33
|
+
client_id_env: EPO_OPS_CLIENT_ID
|
|
34
|
+
client_secret_env: EPO_OPS_CLIENT_SECRET
|
|
35
|
+
|
|
36
|
+
- fetch:
|
|
37
|
+
url: "https://ops.epo.org/3.2/rest-services/published-data/publication/epodoc/${{ args.publication_number | urlencode }}/biblio"
|
|
38
|
+
method: GET
|
|
39
|
+
headers:
|
|
40
|
+
Authorization: "Bearer ${{ auth.bearer || '' }}"
|
|
41
|
+
Accept: application/xml
|
|
42
|
+
|
|
43
|
+
- select-xml:
|
|
44
|
+
xpath: "//ops:exchange-document"
|
|
45
|
+
namespaces:
|
|
46
|
+
ops: "http://ops.epo.org"
|
|
47
|
+
|
|
48
|
+
# Same DOCDB envelope as search; richer biblio fields are present.
|
|
49
|
+
- map:
|
|
50
|
+
publication_number: "${{ ((item['bibliographic-data'] && item['bibliographic-data']['publication-reference'] && item['bibliographic-data']['publication-reference']['document-id']) ? (item['bibliographic-data']['publication-reference']['document-id'].country + '-' + item['bibliographic-data']['publication-reference']['document-id']['doc-number'] + '-' + (item['bibliographic-data']['publication-reference']['document-id'].kind || '')) : (args.publication_number || '')) }}"
|
|
51
|
+
application_number: "${{ ((item['bibliographic-data'] && item['bibliographic-data']['application-reference'] && item['bibliographic-data']['application-reference']['document-id']) ? (item['bibliographic-data']['application-reference']['document-id'].country + '-' + item['bibliographic-data']['application-reference']['document-id']['doc-number'] + '-' + (item['bibliographic-data']['application-reference']['document-id'].kind || '')) : '') }}"
|
|
52
|
+
title: "${{ (function(t){ if(!t) return ''; if(Array.isArray(t)){ var en=t.find(x=>x['@_lang']==='en'); return en ? (en['#text']||en) : (t[0]['#text']||t[0]); } return t['#text']||t; })(item['bibliographic-data'] ? item['bibliographic-data']['invention-title'] : null) }}"
|
|
53
|
+
abstract: "${{ (function(a){ if(!a) return ''; if(Array.isArray(a)){ var en=a.find(x=>x['@_lang']==='en'); return en ? ((en.p ? (en.p['#text']||en.p) : (en['#text']||en))) : ''; } return a.p ? (a.p['#text']||a.p) : (a['#text']||a); })(item.abstract) }}"
|
|
54
|
+
kind_code: "${{ (item['bibliographic-data'] && item['bibliographic-data']['publication-reference'] && item['bibliographic-data']['publication-reference']['document-id']) ? (item['bibliographic-data']['publication-reference']['document-id'].kind || '') : '' }}"
|
|
55
|
+
publication_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['bibliographic-data'] && item['bibliographic-data']['publication-reference'] && item['bibliographic-data']['publication-reference']['document-id']) ? item['bibliographic-data']['publication-reference']['document-id'].date : '') }}"
|
|
56
|
+
filing_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['bibliographic-data'] && item['bibliographic-data']['application-reference'] && item['bibliographic-data']['application-reference']['document-id']) ? item['bibliographic-data']['application-reference']['document-id'].date : '') }}"
|
|
57
|
+
priority_date: "${{ (function(){ var pc = item['bibliographic-data'] && item['bibliographic-data']['priority-claims']; if(!pc || !pc['priority-claim']) return ''; var arr = Array.isArray(pc['priority-claim']) ? pc['priority-claim'] : [pc['priority-claim']]; for (var i=0;i<arr.length;i++){ var did = arr[i]['document-id']; if(Array.isArray(did)){ for (var j=0;j<did.length;j++){ if(did[j].date){ var s=String(did[j].date); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; } } } else if(did && did.date){ var s=String(did.date); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; } } return ''; })() }}"
|
|
58
|
+
inventors: "${{ JSON.stringify((function(){ var p=item['bibliographic-data'] && item['bibliographic-data'].parties; if(!p || !p.inventors || !p.inventors.inventor) return []; var arr = Array.isArray(p.inventors.inventor) ? p.inventors.inventor : [p.inventors.inventor]; return arr.map(i => ({ name: (i['inventor-name'] && (i['inventor-name'].name || i['inventor-name']['#text'])) || '' })).filter(x => x.name); })()) }}"
|
|
59
|
+
assignees: "${{ JSON.stringify((function(){ var p=item['bibliographic-data'] && item['bibliographic-data'].parties; if(!p || !p.applicants || !p.applicants.applicant) return []; var arr = Array.isArray(p.applicants.applicant) ? p.applicants.applicant : [p.applicants.applicant]; return arr.map(i => ({ name: (i['applicant-name'] && (i['applicant-name'].name || i['applicant-name']['#text'])) || '' })).filter(x => x.name); })()) }}"
|
|
60
|
+
classifications: "${{ JSON.stringify((function(){ var bd = item['bibliographic-data']; if(!bd) return []; var out = []; var ipcr = bd['classifications-ipcr'] && bd['classifications-ipcr']['classification-ipcr']; if(ipcr){ var arr = Array.isArray(ipcr) ? ipcr : [ipcr]; for (var i=0;i<arr.length;i++) out.push({ scheme: 'ipc', code: arr[i].text || arr[i]['#text'] || '' }); } var pc = bd['patent-classifications'] && bd['patent-classifications']['patent-classification']; if(pc){ var arr2 = Array.isArray(pc) ? pc : [pc]; for (var i=0;i<arr2.length;i++){ var c=arr2[i]; var scheme=(c['classification-scheme'] && (c['classification-scheme']['@_scheme']||'')).toLowerCase()||'cpc'; var section=(c.section||'')+(c.class||'')+(c.subclass||''); var main=(c['main-group']||'')+(c['subgroup']?'/'+c.subgroup:''); out.push({ scheme: scheme, code: (section+main) }); } } return out.filter(x => x.code); })()) }}"
|
|
61
|
+
family_id: "${{ item['@_family-id'] || '' }}"
|
|
62
|
+
source_adapter: epo
|
|
63
|
+
source_url: "${{ 'https://worldwide.espacenet.com/patent/search/publication/' + (args.publication_number || '') }}"
|
|
64
|
+
retrieved_at: ""
|
|
65
|
+
|
|
66
|
+
columns: [publication_number, title]
|
|
67
|
+
|
|
68
|
+
# schema-v2 metadata
|
|
69
|
+
capabilities: ["http.fetch", "patent.get"]
|
|
70
|
+
minimum_capability: http.fetch
|
|
71
|
+
trust: public
|
|
72
|
+
confidentiality: public
|
|
73
|
+
quarantine: false
|
|
74
|
+
schema_version: v2
|