@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,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::adapters::freepatentsonline-web::_shared
|
|
3
|
+
* @does Shared HTTP + HTML helpers for the KEYLESS FreePatentsOnline adapter. FPO ships zero JS gate and zero auth; we hit the SSR `result.html` listing and `<id>.html` detail pages directly. Kind codes are decoded from FPO's internal URL routing — `/y<YYYY>/<serial>.html` ↔ US published application (ST.16 kind `A1`), `/<id>.html` (compact ID) ↔ US grant (kind code unknown from URL alone — skip), `/<CCNNNNkc>.html` ↔ explicit kind code (use as-is).
|
|
4
|
+
* @needs src/engine/normalizer/patent-envelope.ts, src/types/patent.ts, node:fetch (global)
|
|
5
|
+
* @feeds src/adapters/freepatentsonline-web/search.ts, src/adapters/freepatentsonline-web/get.ts
|
|
6
|
+
* @breaks throws FpoHttpError on non-2xx; pure-HTML parse functions never throw, they return null on selector miss
|
|
7
|
+
* @invariants every outbound request carries a real-browser User-Agent; publication numbers either arrive with an explicit kind code OR are decoded from FPO's URL convention — adapters NEVER fabricate a kind code from era heuristics
|
|
8
|
+
* @side-effects HTTPS egress to www.freepatentsonline.com only
|
|
9
|
+
* @perf 50-150 KB per page; HTML parse is linear regex
|
|
10
|
+
* @concurrency safe — stateless
|
|
11
|
+
* @test verification proof in docs/skills/patent-cookbook.md
|
|
12
|
+
* @stability experimental
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
* @verification keyless-best-effort
|
|
15
|
+
*/
|
|
16
|
+
const FPO_UA = "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";
|
|
17
|
+
export const FPO_ORIGIN = "https://www.freepatentsonline.com";
|
|
18
|
+
export class FpoHttpError extends Error {
|
|
19
|
+
status;
|
|
20
|
+
url;
|
|
21
|
+
constructor(status, url, message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.status = status;
|
|
24
|
+
this.url = url;
|
|
25
|
+
this.name = "FpoHttpError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function fetchFpoHtml(url) {
|
|
29
|
+
const response = await fetch(url, {
|
|
30
|
+
method: "GET",
|
|
31
|
+
headers: {
|
|
32
|
+
"User-Agent": FPO_UA,
|
|
33
|
+
Accept: "text/html,application/xhtml+xml",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw new FpoHttpError(response.status, url, `FreePatentsOnline returned HTTP ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return await response.text();
|
|
40
|
+
}
|
|
41
|
+
export function buildFpoSearchUrl(query, page) {
|
|
42
|
+
const trimmed = query.trim().replace(/\s+/g, "+");
|
|
43
|
+
const safe = encodeURIComponent(trimmed).replace(/%2B/g, "+");
|
|
44
|
+
return `${FPO_ORIGIN}/result.html?p=${page}&sort=relevance&srch=xprtsrch&query_txt=${safe}&submitted=&patents_us=on&patents_other=on`;
|
|
45
|
+
}
|
|
46
|
+
export function buildFpoDetailUrl(publicationNumber) {
|
|
47
|
+
const compact = publicationNumber.replace(/-/g, "").toUpperCase();
|
|
48
|
+
// Heuristic for US published applications: `US20240220787` → `/y2024/0220787.html`
|
|
49
|
+
const usAppMatch = /^US(\d{4})(\d{7})$/.exec(compact);
|
|
50
|
+
if (usAppMatch) {
|
|
51
|
+
return `${FPO_ORIGIN}/y${usAppMatch[1]}/${usAppMatch[2]}.html`;
|
|
52
|
+
}
|
|
53
|
+
// EP / WO / etc with explicit kind code → /<full>.html
|
|
54
|
+
return `${FPO_ORIGIN}/${encodeURIComponent(compact)}.html`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Convert an MM/DD/YYYY date as FPO renders it into ISO-8601 YYYY-MM-DD.
|
|
58
|
+
* Returns undefined on shape mismatch — we never invent a date.
|
|
59
|
+
*/
|
|
60
|
+
export function fpoDateToIso(raw) {
|
|
61
|
+
if (!raw)
|
|
62
|
+
return undefined;
|
|
63
|
+
const match = /^\s*(\d{2})\/(\d{2})\/(\d{4})\s*$/.exec(raw);
|
|
64
|
+
if (!match)
|
|
65
|
+
return undefined;
|
|
66
|
+
return `${match[3]}-${match[1]}-${match[2]}`;
|
|
67
|
+
}
|
|
68
|
+
const TAG_RE = /<[^>]+>/g;
|
|
69
|
+
const ENTITY_MAP = {
|
|
70
|
+
"&": "&",
|
|
71
|
+
"<": "<",
|
|
72
|
+
">": ">",
|
|
73
|
+
""": '"',
|
|
74
|
+
"'": "'",
|
|
75
|
+
"…": "…",
|
|
76
|
+
" ": " ",
|
|
77
|
+
};
|
|
78
|
+
export function stripFpoHtml(input) {
|
|
79
|
+
if (!input)
|
|
80
|
+
return "";
|
|
81
|
+
return input
|
|
82
|
+
.replace(TAG_RE, " ")
|
|
83
|
+
.replace(/&(?:amp|lt|gt|quot|#39|hellip|nbsp);/g, (m) => ENTITY_MAP[m] ?? m)
|
|
84
|
+
.replace(/\s+/g, " ")
|
|
85
|
+
.trim();
|
|
86
|
+
}
|
|
87
|
+
const LISTING_TABLE_RE = /<table[^>]*class="listing_table"[^>]*>([\s\S]*?)<\/table>/i;
|
|
88
|
+
const ROW_RE = /<tr[^>]*>([\s\S]*?)<\/tr>/gi;
|
|
89
|
+
const CELL_RE = /<td[^>]*>([\s\S]*?)<\/td>/gi;
|
|
90
|
+
const HREF_RE = /<a[^>]+href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/i;
|
|
91
|
+
/**
|
|
92
|
+
* Map an FPO listing link path to a canonical ST.16 publication number when
|
|
93
|
+
* the route encodes enough information. Returns undefined when the route
|
|
94
|
+
* is structurally ambiguous (e.g. bare grant numbers without a CC prefix).
|
|
95
|
+
*/
|
|
96
|
+
export function canonicaliseFpoLink(link, rawPubNo) {
|
|
97
|
+
// Already segmented? e.g. "EP3716153A1" or "WO2024012345A1"
|
|
98
|
+
const explicit = /^([A-Z]{2})(\d+)([A-Z]\d?)$/.exec(rawPubNo.replace(/\s+/g, "").toUpperCase());
|
|
99
|
+
if (explicit) {
|
|
100
|
+
return `${explicit[1]}-${explicit[2]}-${explicit[3]}`;
|
|
101
|
+
}
|
|
102
|
+
// US application route: /y<YYYY>/<NNNNNNN>.html ↔ US-YYYYNNNNNNN-A1
|
|
103
|
+
const usAppMatch = /^\/y(\d{4})\/(\d{7})\.html$/i.exec(link);
|
|
104
|
+
if (usAppMatch) {
|
|
105
|
+
return `US-${usAppMatch[1]}${usAppMatch[2]}-A1`;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
export function parseFpoListing(html) {
|
|
110
|
+
const tableMatch = LISTING_TABLE_RE.exec(html);
|
|
111
|
+
if (!tableMatch)
|
|
112
|
+
return [];
|
|
113
|
+
const body = tableMatch[1];
|
|
114
|
+
ROW_RE.lastIndex = 0;
|
|
115
|
+
const out = [];
|
|
116
|
+
let rowMatch;
|
|
117
|
+
while ((rowMatch = ROW_RE.exec(body)) !== null) {
|
|
118
|
+
const cells = [];
|
|
119
|
+
CELL_RE.lastIndex = 0;
|
|
120
|
+
let cellMatch;
|
|
121
|
+
while ((cellMatch = CELL_RE.exec(rowMatch[1])) !== null) {
|
|
122
|
+
cells.push(cellMatch[1]);
|
|
123
|
+
}
|
|
124
|
+
// FPO 2026 layout: <tr> has 4 <td> cells —
|
|
125
|
+
// cells[0] = match index ("1", "2", ...)
|
|
126
|
+
// cells[1] = publication number text (e.g. "US20240220787")
|
|
127
|
+
// cells[2] = <a href>title</a> <br/> abstract-snippet
|
|
128
|
+
// cells[3] = relevance score
|
|
129
|
+
if (cells.length < 3)
|
|
130
|
+
continue;
|
|
131
|
+
const rawPubNo = stripFpoHtml(cells[1]);
|
|
132
|
+
const titleCell = cells[2];
|
|
133
|
+
const link = HREF_RE.exec(titleCell);
|
|
134
|
+
if (!rawPubNo || !link)
|
|
135
|
+
continue;
|
|
136
|
+
const title = stripFpoHtml(link[2]);
|
|
137
|
+
// Abstract snippet is the remainder of cells[2] after the </a> tag —
|
|
138
|
+
// FPO emits it inline after a and a <br/>. Strip the <a>…</a>
|
|
139
|
+
// block plus the trailing <br/> and treat what's left as the snippet.
|
|
140
|
+
const afterAnchor = titleCell
|
|
141
|
+
.replace(HREF_RE, "")
|
|
142
|
+
.replace(/<br\s*\/?>/i, "");
|
|
143
|
+
const abstractSnippet = stripFpoHtml(afterAnchor);
|
|
144
|
+
out.push({
|
|
145
|
+
publication_number_raw: rawPubNo,
|
|
146
|
+
publication_number_canonical: canonicaliseFpoLink(link[1], rawPubNo),
|
|
147
|
+
title,
|
|
148
|
+
abstract: abstractSnippet || undefined,
|
|
149
|
+
detail_url: link[1].startsWith("http")
|
|
150
|
+
? link[1]
|
|
151
|
+
: `${FPO_ORIGIN}${link[1]}`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
const KIND_CODE_RE = /<div[^>]*disp_elm_name_kcode[^>]*>[\s\S]*?Kind\s*Code:[\s\S]*?<\/div>\s*<div[^>]*float_left[^>]*>\s*([A-Z0-9]+)\s*<\/div>/i;
|
|
157
|
+
const DOC_TYPE_RE = /<div[^>]*disp_elm_text[^>]*style="[^"]*clear:\s*none[^"]*"[^>]*>\s*<label[^>]*>\s*([^<]+?)\s*<\/label>/i;
|
|
158
|
+
function extractLabelValue(html, label) {
|
|
159
|
+
const re = new RegExp(`<div[^>]*disp_elm_title[^>]*>\\s*${label}\\s*:?\\s*<\\/div>\\s*<div[^>]*disp_elm_text[^>]*>([\\s\\S]*?)<\\/div>`, "i");
|
|
160
|
+
const match = re.exec(html);
|
|
161
|
+
if (!match)
|
|
162
|
+
return undefined;
|
|
163
|
+
const value = stripFpoHtml(match[1]);
|
|
164
|
+
return value || undefined;
|
|
165
|
+
}
|
|
166
|
+
export function parseFpoDetail(html) {
|
|
167
|
+
const title = extractLabelValue(html, "Title");
|
|
168
|
+
const abstractRaw = extractLabelValue(html, "Abstract");
|
|
169
|
+
const applicationNumber = extractLabelValue(html, "Application Number");
|
|
170
|
+
const publicationDate = fpoDateToIso(extractLabelValue(html, "Publication Date"));
|
|
171
|
+
const filingDate = fpoDateToIso(extractLabelValue(html, "Filing Date"));
|
|
172
|
+
const assignee = extractLabelValue(html, "Assignee");
|
|
173
|
+
const kindMatch = KIND_CODE_RE.exec(html);
|
|
174
|
+
const kindCode = kindMatch ? kindMatch[1].toUpperCase() : undefined;
|
|
175
|
+
const docTypeMatch = DOC_TYPE_RE.exec(html);
|
|
176
|
+
const docTypeLabel = docTypeMatch ? docTypeMatch[1].trim() : undefined;
|
|
177
|
+
return {
|
|
178
|
+
title,
|
|
179
|
+
abstract: abstractRaw,
|
|
180
|
+
application_number: applicationNumber,
|
|
181
|
+
publication_date: publicationDate,
|
|
182
|
+
filing_date: filingDate,
|
|
183
|
+
assignee,
|
|
184
|
+
kind_code: kindCode,
|
|
185
|
+
doc_type_label: docTypeLabel,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Combine the bib label `United States Patent Application 20240220787` and
|
|
190
|
+
* the kind code `A1` extracted separately into the canonical ST.16 form
|
|
191
|
+
* `US-20240220787-A1`. Returns undefined if either piece is missing.
|
|
192
|
+
*/
|
|
193
|
+
export function reconstructCanonicalPubNo(docTypeLabel, kindCode) {
|
|
194
|
+
if (!docTypeLabel || !kindCode)
|
|
195
|
+
return undefined;
|
|
196
|
+
// Pull the trailing identifier off the label. The label is one of:
|
|
197
|
+
// "United States Patent Application 20240220787" (11-digit US app id)
|
|
198
|
+
// "European Patent Application EP3716153" (CC-prefixed)
|
|
199
|
+
// "United States Patent 12602228" (7-9 digit US grant)
|
|
200
|
+
const idMatch = /([A-Z]{2}\d+|\d{7,})\s*$/.exec(docTypeLabel.trim());
|
|
201
|
+
if (!idMatch)
|
|
202
|
+
return undefined;
|
|
203
|
+
const rawId = idMatch[1];
|
|
204
|
+
// Prefix? `US…`, `EP…`, etc. — strip then re-emit
|
|
205
|
+
const prefixMatch = /^([A-Z]{2})(\d+)$/.exec(rawId);
|
|
206
|
+
if (prefixMatch) {
|
|
207
|
+
return `${prefixMatch[1]}-${prefixMatch[2]}-${kindCode}`;
|
|
208
|
+
}
|
|
209
|
+
// Bare numeric — could be a 7-9 digit US grant or an 11-digit US
|
|
210
|
+
// published-application identifier. Both belong to the US namespace.
|
|
211
|
+
if (/^\d{7,11}$/.test(rawId)) {
|
|
212
|
+
return `US-${rawId}-${kindCode}`;
|
|
213
|
+
}
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=_shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../../src/adapters/freepatentsonline-web/_shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::adapters::freepatentsonline-web::get
|
|
3
|
+
* @does Keyless single-publication detail fetch from FreePatentsOnline — parses the SSR detail page label/value blocks plus the disp_elm_name_kcode kind-code island so we can canonicalise the publication number even for bare-id US grants where the search-listing URL alone was ambiguous.
|
|
4
|
+
* @needs src/adapters/freepatentsonline-web/_shared.ts, src/engine/normalizer/patent-envelope.ts, src/registry.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (capability tag patent.get)
|
|
6
|
+
* @breaks PATENT_NOT_FOUND when the detail page returns 200 but no Title is parseable; PATENT_INVALID_NUMBER for empty input; PATENT_API_DEPRECATED on non-2xx HTTP
|
|
7
|
+
* @invariants output is a single canonical PatentRecord whenever both the document-type label and kind code are present; otherwise emit PATENT_SCHEMA_DRIFT rather than canonicalise from an era heuristic
|
|
8
|
+
* @side-effects HTTPS egress to www.freepatentsonline.com only
|
|
9
|
+
* @perf single page fetch (~130 KB); regex parse linear in document length
|
|
10
|
+
* @concurrency safe — stateless
|
|
11
|
+
* @test verification proof in docs/skills/patent-cookbook.md
|
|
12
|
+
* @stability experimental
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
* @verification keyless-best-effort
|
|
15
|
+
*/
|
|
16
|
+
interface GetArgs {
|
|
17
|
+
publication_number?: unknown;
|
|
18
|
+
}
|
|
19
|
+
export declare function runFreePatentsOnlineGet(kwargs: GetArgs): Promise<unknown[]>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=get.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/adapters/freepatentsonline-web/get.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH,UAAU,OAAO;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,OAAO,EAAE,CAAC,CA8EpB"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::adapters::freepatentsonline-web::get
|
|
3
|
+
* @does Keyless single-publication detail fetch from FreePatentsOnline — parses the SSR detail page label/value blocks plus the disp_elm_name_kcode kind-code island so we can canonicalise the publication number even for bare-id US grants where the search-listing URL alone was ambiguous.
|
|
4
|
+
* @needs src/adapters/freepatentsonline-web/_shared.ts, src/engine/normalizer/patent-envelope.ts, src/registry.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (capability tag patent.get)
|
|
6
|
+
* @breaks PATENT_NOT_FOUND when the detail page returns 200 but no Title is parseable; PATENT_INVALID_NUMBER for empty input; PATENT_API_DEPRECATED on non-2xx HTTP
|
|
7
|
+
* @invariants output is a single canonical PatentRecord whenever both the document-type label and kind code are present; otherwise emit PATENT_SCHEMA_DRIFT rather than canonicalise from an era heuristic
|
|
8
|
+
* @side-effects HTTPS egress to www.freepatentsonline.com only
|
|
9
|
+
* @perf single page fetch (~130 KB); regex parse linear in document length
|
|
10
|
+
* @concurrency safe — stateless
|
|
11
|
+
* @test verification proof in docs/skills/patent-cookbook.md
|
|
12
|
+
* @stability experimental
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
* @verification keyless-best-effort
|
|
15
|
+
*/
|
|
16
|
+
import { cli, Strategy } from "../../registry.js";
|
|
17
|
+
import { assemblePatentRecord } from "../../engine/normalizer/patent-envelope.js";
|
|
18
|
+
import { buildPatentEnvelope } from "../../engine/normalizer/patent-envelope.js";
|
|
19
|
+
import { FpoHttpError, buildFpoDetailUrl, fetchFpoHtml, parseFpoDetail, reconstructCanonicalPubNo, } from "./_shared.js";
|
|
20
|
+
const ADAPTER_PATH = "src/adapters/freepatentsonline-web/get.ts";
|
|
21
|
+
export async function runFreePatentsOnlineGet(kwargs) {
|
|
22
|
+
const raw = String(kwargs.publication_number ?? "").trim();
|
|
23
|
+
if (raw.length === 0) {
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
envelope: buildPatentEnvelope({
|
|
27
|
+
code: "PATENT_INVALID_NUMBER",
|
|
28
|
+
adapter_path: ADAPTER_PATH,
|
|
29
|
+
step: "validate",
|
|
30
|
+
suggestion: "freepatentsonline-web get requires a publication_number",
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
const url = buildFpoDetailUrl(raw);
|
|
36
|
+
let html;
|
|
37
|
+
try {
|
|
38
|
+
html = await fetchFpoHtml(url);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof FpoHttpError) {
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
envelope: buildPatentEnvelope({
|
|
45
|
+
code: err.status === 404 ? "PATENT_NOT_FOUND" : "PATENT_API_DEPRECATED",
|
|
46
|
+
adapter_path: ADAPTER_PATH,
|
|
47
|
+
step: "fetch",
|
|
48
|
+
suggestion: `FreePatentsOnline returned HTTP ${err.status} for ${err.url}`,
|
|
49
|
+
alternatives: ["google-patents-web", "espacenet"],
|
|
50
|
+
}),
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
56
|
+
const detail = parseFpoDetail(html);
|
|
57
|
+
if (!detail.title) {
|
|
58
|
+
return [
|
|
59
|
+
{
|
|
60
|
+
envelope: buildPatentEnvelope({
|
|
61
|
+
code: "PATENT_NOT_FOUND",
|
|
62
|
+
adapter_path: ADAPTER_PATH,
|
|
63
|
+
step: "select",
|
|
64
|
+
suggestion: `freepatentsonline-web detail page for "${raw}" yielded no Title field`,
|
|
65
|
+
alternatives: ["google-patents-web", "espacenet"],
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
const canonical = reconstructCanonicalPubNo(detail.doc_type_label, detail.kind_code) ?? raw;
|
|
71
|
+
try {
|
|
72
|
+
return [
|
|
73
|
+
assemblePatentRecord({
|
|
74
|
+
publication_number: canonical,
|
|
75
|
+
application_number: detail.application_number || undefined,
|
|
76
|
+
title: detail.title,
|
|
77
|
+
abstract: detail.abstract,
|
|
78
|
+
assignees: detail.assignee ? [{ name: detail.assignee }] : undefined,
|
|
79
|
+
filing_date: detail.filing_date,
|
|
80
|
+
publication_date: detail.publication_date,
|
|
81
|
+
source_adapter: "freepatentsonline-web",
|
|
82
|
+
source_url: url,
|
|
83
|
+
}),
|
|
84
|
+
];
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return [
|
|
88
|
+
{
|
|
89
|
+
envelope: buildPatentEnvelope({
|
|
90
|
+
code: "PATENT_SCHEMA_DRIFT",
|
|
91
|
+
adapter_path: ADAPTER_PATH,
|
|
92
|
+
step: "normalize",
|
|
93
|
+
suggestion: `freepatentsonline-web detail page for "${raw}" did not yield a canonicalisable publication_number (doc_type=${detail.doc_type_label}; kind_code=${detail.kind_code})`,
|
|
94
|
+
alternatives: ["google-patents-web", "espacenet"],
|
|
95
|
+
}),
|
|
96
|
+
},
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
cli({
|
|
101
|
+
site: "freepatentsonline-web",
|
|
102
|
+
name: "get",
|
|
103
|
+
description: "Retrieve a single FreePatentsOnline bibliographic record (keyless, no Chrome)",
|
|
104
|
+
domain: "www.freepatentsonline.com",
|
|
105
|
+
strategy: Strategy.PUBLIC,
|
|
106
|
+
adapter_path: ADAPTER_PATH,
|
|
107
|
+
args: [
|
|
108
|
+
{
|
|
109
|
+
name: "publication_number",
|
|
110
|
+
type: "str",
|
|
111
|
+
required: true,
|
|
112
|
+
positional: true,
|
|
113
|
+
description: "ST.16 publication number, compact or segmented (e.g. US20240220787 or EP3716153A1)",
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
columns: [
|
|
117
|
+
"publication_number",
|
|
118
|
+
"title",
|
|
119
|
+
"publication_date",
|
|
120
|
+
"assignees",
|
|
121
|
+
"source_url",
|
|
122
|
+
],
|
|
123
|
+
capabilities: ["http.fetch", "patent.get"],
|
|
124
|
+
minimum_capability: "http.fetch",
|
|
125
|
+
func: async (_page, kwargs) => runFreePatentsOnlineGet(kwargs),
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/adapters/freepatentsonline-web/get.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::adapters::freepatentsonline-web::search
|
|
3
|
+
* @does Keyless patent search via www.freepatentsonline.com's SSR `result.html` listing — older site, still maintained, no JS gate, no auth. Complements google-patents-web as a second day-zero source.
|
|
4
|
+
* @needs src/adapters/freepatentsonline-web/_shared.ts, src/engine/normalizer/patent-envelope.ts, src/registry.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (capability tag patent.search)
|
|
6
|
+
* @breaks PATENT_API_DEPRECATED on non-2xx HTTP; PATENT_NOT_FOUND on empty listing; PATENT_SCHEMA_DRIFT when the listing_table selector no longer matches
|
|
7
|
+
* @invariants output rows are canonical PatentRecord; publication_number is decoded from the FPO link path (URL-encoded structural signal) — rows whose link does not encode a kind code are dropped, never fabricated
|
|
8
|
+
* @side-effects HTTPS egress to www.freepatentsonline.com only
|
|
9
|
+
* @perf single page fetch (~50 KB); FPO returns 50 results per page
|
|
10
|
+
* @concurrency safe — stateless
|
|
11
|
+
* @test verification proof in docs/skills/patent-cookbook.md
|
|
12
|
+
* @stability experimental
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
* @verification keyless-best-effort
|
|
15
|
+
*/
|
|
16
|
+
interface SearchArgs {
|
|
17
|
+
query?: unknown;
|
|
18
|
+
limit?: unknown;
|
|
19
|
+
}
|
|
20
|
+
export declare function runFreePatentsOnlineSearch(kwargs: SearchArgs): Promise<unknown[]>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/adapters/freepatentsonline-web/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAQD,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,OAAO,EAAE,CAAC,CAkGpB"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::adapters::freepatentsonline-web::search
|
|
3
|
+
* @does Keyless patent search via www.freepatentsonline.com's SSR `result.html` listing — older site, still maintained, no JS gate, no auth. Complements google-patents-web as a second day-zero source.
|
|
4
|
+
* @needs src/adapters/freepatentsonline-web/_shared.ts, src/engine/normalizer/patent-envelope.ts, src/registry.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (capability tag patent.search)
|
|
6
|
+
* @breaks PATENT_API_DEPRECATED on non-2xx HTTP; PATENT_NOT_FOUND on empty listing; PATENT_SCHEMA_DRIFT when the listing_table selector no longer matches
|
|
7
|
+
* @invariants output rows are canonical PatentRecord; publication_number is decoded from the FPO link path (URL-encoded structural signal) — rows whose link does not encode a kind code are dropped, never fabricated
|
|
8
|
+
* @side-effects HTTPS egress to www.freepatentsonline.com only
|
|
9
|
+
* @perf single page fetch (~50 KB); FPO returns 50 results per page
|
|
10
|
+
* @concurrency safe — stateless
|
|
11
|
+
* @test verification proof in docs/skills/patent-cookbook.md
|
|
12
|
+
* @stability experimental
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
* @verification keyless-best-effort
|
|
15
|
+
*/
|
|
16
|
+
import { cli, Strategy } from "../../registry.js";
|
|
17
|
+
import { assemblePatentRecord } from "../../engine/normalizer/patent-envelope.js";
|
|
18
|
+
import { buildPatentEnvelope } from "../../engine/normalizer/patent-envelope.js";
|
|
19
|
+
import { FpoHttpError, buildFpoSearchUrl, fetchFpoHtml, parseFpoListing, } from "./_shared.js";
|
|
20
|
+
const ADAPTER_PATH = "src/adapters/freepatentsonline-web/search.ts";
|
|
21
|
+
function clampLimit(raw) {
|
|
22
|
+
const num = typeof raw === "number" ? raw : Number(raw);
|
|
23
|
+
if (!Number.isFinite(num) || num <= 0)
|
|
24
|
+
return 25;
|
|
25
|
+
return Math.min(50, Math.max(1, Math.floor(num)));
|
|
26
|
+
}
|
|
27
|
+
export async function runFreePatentsOnlineSearch(kwargs) {
|
|
28
|
+
const query = String(kwargs.query ?? "").trim();
|
|
29
|
+
if (query.length === 0) {
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
envelope: buildPatentEnvelope({
|
|
33
|
+
code: "PATENT_UNSUPPORTED_QUERY",
|
|
34
|
+
adapter_path: ADAPTER_PATH,
|
|
35
|
+
step: "validate",
|
|
36
|
+
suggestion: "freepatentsonline-web search requires a non-empty query",
|
|
37
|
+
alternatives: ["google-patents-web"],
|
|
38
|
+
}),
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
const limit = clampLimit(kwargs.limit);
|
|
43
|
+
const url = buildFpoSearchUrl(query, 1);
|
|
44
|
+
let html;
|
|
45
|
+
try {
|
|
46
|
+
html = await fetchFpoHtml(url);
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err instanceof FpoHttpError) {
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
envelope: buildPatentEnvelope({
|
|
53
|
+
code: err.status === 429
|
|
54
|
+
? "PATENT_RATE_LIMIT"
|
|
55
|
+
: "PATENT_API_DEPRECATED",
|
|
56
|
+
adapter_path: ADAPTER_PATH,
|
|
57
|
+
step: "fetch",
|
|
58
|
+
suggestion: `FreePatentsOnline returned HTTP ${err.status} for ${err.url}; retry with --sources google-patents-web`,
|
|
59
|
+
alternatives: ["google-patents-web", "espacenet"],
|
|
60
|
+
retryable: err.status === 429,
|
|
61
|
+
}),
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
const rows = parseFpoListing(html);
|
|
68
|
+
if (rows.length === 0) {
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
envelope: buildPatentEnvelope({
|
|
72
|
+
code: html.includes('class="listing_table"')
|
|
73
|
+
? "PATENT_NOT_FOUND"
|
|
74
|
+
: "PATENT_SCHEMA_DRIFT",
|
|
75
|
+
adapter_path: ADAPTER_PATH,
|
|
76
|
+
step: "select",
|
|
77
|
+
suggestion: html.includes('class="listing_table"')
|
|
78
|
+
? `freepatentsonline-web returned no listing rows for "${query}"`
|
|
79
|
+
: "freepatentsonline-web no longer ships listing_table — the parseFpoListing extractor needs updating",
|
|
80
|
+
alternatives: ["google-patents-web", "espacenet"],
|
|
81
|
+
}),
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
const out = [];
|
|
86
|
+
for (const row of rows.slice(0, limit)) {
|
|
87
|
+
const canonical = row.publication_number_canonical;
|
|
88
|
+
if (!canonical) {
|
|
89
|
+
// Row's link path did not encode a kind code (e.g. bare US grant
|
|
90
|
+
// number). Skip rather than fabricate.
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
out.push(assemblePatentRecord({
|
|
95
|
+
publication_number: canonical,
|
|
96
|
+
title: row.title || undefined,
|
|
97
|
+
abstract: row.abstract || undefined,
|
|
98
|
+
source_adapter: "freepatentsonline-web",
|
|
99
|
+
source_url: row.detail_url,
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// Defensive: skip rows that fail canonicalisation rather than
|
|
104
|
+
// synthesise.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (out.length === 0) {
|
|
108
|
+
return [
|
|
109
|
+
{
|
|
110
|
+
envelope: buildPatentEnvelope({
|
|
111
|
+
code: "PATENT_NOT_FOUND",
|
|
112
|
+
adapter_path: ADAPTER_PATH,
|
|
113
|
+
step: "normalize",
|
|
114
|
+
suggestion: `freepatentsonline-web returned ${rows.length} listing rows but none had a structurally decodable kind code; run \`unicli freepatentsonline-web get <pub_no>\` against an individual hit to retrieve its kind code from the detail page`,
|
|
115
|
+
alternatives: ["google-patents-web", "espacenet"],
|
|
116
|
+
}),
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
cli({
|
|
123
|
+
site: "freepatentsonline-web",
|
|
124
|
+
name: "search",
|
|
125
|
+
description: "Keyless FreePatentsOnline search via the public SSR listing (no API key, no Chrome)",
|
|
126
|
+
domain: "www.freepatentsonline.com",
|
|
127
|
+
strategy: Strategy.PUBLIC,
|
|
128
|
+
adapter_path: ADAPTER_PATH,
|
|
129
|
+
args: [
|
|
130
|
+
{
|
|
131
|
+
name: "query",
|
|
132
|
+
type: "str",
|
|
133
|
+
required: true,
|
|
134
|
+
positional: true,
|
|
135
|
+
description: "Free-text query (FreePatentsOnline xprtsrch syntax)",
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "limit",
|
|
139
|
+
type: "int",
|
|
140
|
+
default: 25,
|
|
141
|
+
description: "Max results to return (1-50, FPO paginates at 50)",
|
|
142
|
+
},
|
|
143
|
+
],
|
|
144
|
+
columns: ["publication_number", "title", "abstract", "source_url"],
|
|
145
|
+
capabilities: ["http.fetch", "patent.search"],
|
|
146
|
+
minimum_capability: "http.fetch",
|
|
147
|
+
func: async (_page, kwargs) => runFreePatentsOnlineSearch(kwargs),
|
|
148
|
+
});
|
|
149
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/adapters/freepatentsonline-web/search.ts"],"names":[],"mappings":"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"}
|