@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.
Files changed (471) hide show
  1. package/AGENTS.md +28 -6
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/dist/adapters/bilibili/comments.js +66 -4
  5. package/dist/adapters/bilibili/comments.js.map +1 -1
  6. package/dist/adapters/bilibili/compat.js +2 -2
  7. package/dist/adapters/bilibili/compat.js.map +1 -1
  8. package/dist/adapters/bilibili/download.js +4 -4
  9. package/dist/adapters/bilibili/download.js.map +1 -1
  10. package/dist/adapters/bilibili/wbi.d.ts.map +1 -1
  11. package/dist/adapters/bilibili/wbi.js +3 -3
  12. package/dist/adapters/bilibili/wbi.js.map +1 -1
  13. package/dist/adapters/cipo/_shared.d.ts +21 -0
  14. package/dist/adapters/cipo/_shared.d.ts.map +1 -0
  15. package/dist/adapters/cipo/_shared.js +67 -0
  16. package/dist/adapters/cipo/_shared.js.map +1 -0
  17. package/dist/adapters/cipo/get.d.ts +19 -0
  18. package/dist/adapters/cipo/get.d.ts.map +1 -0
  19. package/dist/adapters/cipo/get.js +140 -0
  20. package/dist/adapters/cipo/get.js.map +1 -0
  21. package/dist/adapters/cipo/legal-status.d.ts +19 -0
  22. package/dist/adapters/cipo/legal-status.d.ts.map +1 -0
  23. package/dist/adapters/cipo/legal-status.js +111 -0
  24. package/dist/adapters/cipo/legal-status.js.map +1 -0
  25. package/dist/adapters/cipo/search.d.ts +20 -0
  26. package/dist/adapters/cipo/search.d.ts.map +1 -0
  27. package/dist/adapters/cipo/search.js +148 -0
  28. package/dist/adapters/cipo/search.js.map +1 -0
  29. package/dist/adapters/cnipa/_shared.d.ts +47 -0
  30. package/dist/adapters/cnipa/_shared.d.ts.map +1 -0
  31. package/dist/adapters/cnipa/_shared.js +97 -0
  32. package/dist/adapters/cnipa/_shared.js.map +1 -0
  33. package/dist/adapters/cnipa/get.d.ts +19 -0
  34. package/dist/adapters/cnipa/get.d.ts.map +1 -0
  35. package/dist/adapters/cnipa/get.js +149 -0
  36. package/dist/adapters/cnipa/get.js.map +1 -0
  37. package/dist/adapters/cnipa/legal-status.d.ts +19 -0
  38. package/dist/adapters/cnipa/legal-status.d.ts.map +1 -0
  39. package/dist/adapters/cnipa/legal-status.js +119 -0
  40. package/dist/adapters/cnipa/legal-status.js.map +1 -0
  41. package/dist/adapters/cnipa/search.d.ts +21 -0
  42. package/dist/adapters/cnipa/search.d.ts.map +1 -0
  43. package/dist/adapters/cnipa/search.js +170 -0
  44. package/dist/adapters/cnipa/search.js.map +1 -0
  45. package/dist/adapters/espacenet/_shared.d.ts +21 -0
  46. package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
  47. package/dist/adapters/espacenet/_shared.js +67 -0
  48. package/dist/adapters/espacenet/_shared.js.map +1 -0
  49. package/dist/adapters/espacenet/family.d.ts +19 -0
  50. package/dist/adapters/espacenet/family.d.ts.map +1 -0
  51. package/dist/adapters/espacenet/family.js +118 -0
  52. package/dist/adapters/espacenet/family.js.map +1 -0
  53. package/dist/adapters/espacenet/get.d.ts +19 -0
  54. package/dist/adapters/espacenet/get.d.ts.map +1 -0
  55. package/dist/adapters/espacenet/get.js +130 -0
  56. package/dist/adapters/espacenet/get.js.map +1 -0
  57. package/dist/adapters/espacenet/legal-status.d.ts +19 -0
  58. package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
  59. package/dist/adapters/espacenet/legal-status.js +110 -0
  60. package/dist/adapters/espacenet/legal-status.js.map +1 -0
  61. package/dist/adapters/espacenet/search.d.ts +20 -0
  62. package/dist/adapters/espacenet/search.d.ts.map +1 -0
  63. package/dist/adapters/espacenet/search.js +165 -0
  64. package/dist/adapters/espacenet/search.js.map +1 -0
  65. package/dist/adapters/facebook/subtitles.d.ts +9 -0
  66. package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
  67. package/dist/adapters/facebook/subtitles.js +42 -0
  68. package/dist/adapters/facebook/subtitles.js.map +1 -0
  69. package/dist/adapters/fips/_shared.d.ts +21 -0
  70. package/dist/adapters/fips/_shared.d.ts.map +1 -0
  71. package/dist/adapters/fips/_shared.js +77 -0
  72. package/dist/adapters/fips/_shared.js.map +1 -0
  73. package/dist/adapters/fips/get.d.ts +19 -0
  74. package/dist/adapters/fips/get.d.ts.map +1 -0
  75. package/dist/adapters/fips/get.js +139 -0
  76. package/dist/adapters/fips/get.js.map +1 -0
  77. package/dist/adapters/fips/search.d.ts +20 -0
  78. package/dist/adapters/fips/search.d.ts.map +1 -0
  79. package/dist/adapters/fips/search.js +148 -0
  80. package/dist/adapters/fips/search.js.map +1 -0
  81. package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
  82. package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
  83. package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
  84. package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
  85. package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
  86. package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
  87. package/dist/adapters/freepatentsonline-web/get.js +127 -0
  88. package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
  89. package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
  90. package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
  91. package/dist/adapters/freepatentsonline-web/search.js +149 -0
  92. package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
  93. package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
  94. package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
  95. package/dist/adapters/google-patents-web/_shared.js +164 -0
  96. package/dist/adapters/google-patents-web/_shared.js.map +1 -0
  97. package/dist/adapters/google-patents-web/get.d.ts +36 -0
  98. package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
  99. package/dist/adapters/google-patents-web/get.js +187 -0
  100. package/dist/adapters/google-patents-web/get.js.map +1 -0
  101. package/dist/adapters/google-patents-web/search.d.ts +23 -0
  102. package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
  103. package/dist/adapters/google-patents-web/search.js +169 -0
  104. package/dist/adapters/google-patents-web/search.js.map +1 -0
  105. package/dist/adapters/inpi-br/_shared.d.ts +21 -0
  106. package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
  107. package/dist/adapters/inpi-br/_shared.js +67 -0
  108. package/dist/adapters/inpi-br/_shared.js.map +1 -0
  109. package/dist/adapters/inpi-br/get.d.ts +19 -0
  110. package/dist/adapters/inpi-br/get.d.ts.map +1 -0
  111. package/dist/adapters/inpi-br/get.js +142 -0
  112. package/dist/adapters/inpi-br/get.js.map +1 -0
  113. package/dist/adapters/inpi-br/search.d.ts +20 -0
  114. package/dist/adapters/inpi-br/search.d.ts.map +1 -0
  115. package/dist/adapters/inpi-br/search.js +154 -0
  116. package/dist/adapters/inpi-br/search.js.map +1 -0
  117. package/dist/adapters/instagram/subtitles.d.ts +9 -0
  118. package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
  119. package/dist/adapters/instagram/subtitles.js +42 -0
  120. package/dist/adapters/instagram/subtitles.js.map +1 -0
  121. package/dist/adapters/mastodon/statuses.d.ts +40 -0
  122. package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
  123. package/dist/adapters/mastodon/statuses.js +153 -0
  124. package/dist/adapters/mastodon/statuses.js.map +1 -0
  125. package/dist/adapters/reddit/comments.d.ts +9 -0
  126. package/dist/adapters/reddit/comments.d.ts.map +1 -0
  127. package/dist/adapters/reddit/comments.js +124 -0
  128. package/dist/adapters/reddit/comments.js.map +1 -0
  129. package/dist/adapters/threads/post.d.ts +32 -0
  130. package/dist/adapters/threads/post.d.ts.map +1 -0
  131. package/dist/adapters/threads/post.js +287 -0
  132. package/dist/adapters/threads/post.js.map +1 -0
  133. package/dist/adapters/tiktok/subtitles.d.ts +9 -0
  134. package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
  135. package/dist/adapters/tiktok/subtitles.js +42 -0
  136. package/dist/adapters/tiktok/subtitles.js.map +1 -0
  137. package/dist/adapters/twitter/accept.js +2 -2
  138. package/dist/adapters/twitter/accept.js.map +1 -1
  139. package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
  140. package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
  141. package/dist/adapters/twitter/browser-fallback.js +93 -0
  142. package/dist/adapters/twitter/browser-fallback.js.map +1 -0
  143. package/dist/adapters/twitter/browser-state.d.ts +11 -0
  144. package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
  145. package/dist/adapters/twitter/browser-state.js +46 -0
  146. package/dist/adapters/twitter/browser-state.js.map +1 -0
  147. package/dist/adapters/twitter/client.d.ts.map +1 -1
  148. package/dist/adapters/twitter/client.js +36 -13
  149. package/dist/adapters/twitter/client.js.map +1 -1
  150. package/dist/adapters/twitter/reply-dm.js +2 -2
  151. package/dist/adapters/twitter/reply-dm.js.map +1 -1
  152. package/dist/adapters/twitter/reply.js +1 -0
  153. package/dist/adapters/twitter/reply.js.map +1 -1
  154. package/dist/adapters/twitter/search.js +11 -18
  155. package/dist/adapters/twitter/search.js.map +1 -1
  156. package/dist/adapters/twitter/thread.d.ts +14 -0
  157. package/dist/adapters/twitter/thread.d.ts.map +1 -1
  158. package/dist/adapters/twitter/thread.js +28 -2
  159. package/dist/adapters/twitter/thread.js.map +1 -1
  160. package/dist/adapters/twitter/trending.js +13 -59
  161. package/dist/adapters/twitter/trending.js.map +1 -1
  162. package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
  163. package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
  164. package/dist/adapters/xiaohongshu/browser-state.js +67 -0
  165. package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
  166. package/dist/adapters/xiaohongshu/comments.js +28 -5
  167. package/dist/adapters/xiaohongshu/comments.js.map +1 -1
  168. package/dist/adapters/xiaohongshu/download.js +49 -11
  169. package/dist/adapters/xiaohongshu/download.js.map +1 -1
  170. package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
  171. package/dist/adapters/xiaohongshu/search.js +11 -5
  172. package/dist/adapters/xiaohongshu/search.js.map +1 -1
  173. package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
  174. package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
  175. package/dist/adapters/xiaohongshu/trending.js +94 -0
  176. package/dist/adapters/xiaohongshu/trending.js.map +1 -0
  177. package/dist/adapters/youtube/comments.d.ts +80 -0
  178. package/dist/adapters/youtube/comments.d.ts.map +1 -1
  179. package/dist/adapters/youtube/comments.js +108 -12
  180. package/dist/adapters/youtube/comments.js.map +1 -1
  181. package/dist/adapters/youtube/subtitles.d.ts +9 -0
  182. package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
  183. package/dist/adapters/youtube/subtitles.js +42 -0
  184. package/dist/adapters/youtube/subtitles.js.map +1 -0
  185. package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
  186. package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
  187. package/dist/adapters/yt-dlp/subtitles.js +41 -0
  188. package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
  189. package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
  190. package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
  191. package/dist/adapters/zhihu/answer-detail.js +204 -0
  192. package/dist/adapters/zhihu/answer-detail.js.map +1 -0
  193. package/dist/adapters/zhihu/comment.d.ts +9 -0
  194. package/dist/adapters/zhihu/comment.d.ts.map +1 -0
  195. package/dist/adapters/zhihu/comment.js +149 -0
  196. package/dist/adapters/zhihu/comment.js.map +1 -0
  197. package/dist/adapters/zhihu/recommend.d.ts +36 -0
  198. package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
  199. package/dist/adapters/zhihu/recommend.js +151 -0
  200. package/dist/adapters/zhihu/recommend.js.map +1 -0
  201. package/dist/browser/bridge.d.ts.map +1 -1
  202. package/dist/browser/bridge.js +14 -3
  203. package/dist/browser/bridge.js.map +1 -1
  204. package/dist/browser/daemon-client.d.ts +6 -0
  205. package/dist/browser/daemon-client.d.ts.map +1 -1
  206. package/dist/browser/daemon-client.js +75 -15
  207. package/dist/browser/daemon-client.js.map +1 -1
  208. package/dist/browser/daemon.js +39 -15
  209. package/dist/browser/daemon.js.map +1 -1
  210. package/dist/browser/protocol.d.ts +1 -0
  211. package/dist/browser/protocol.d.ts.map +1 -1
  212. package/dist/browser/protocol.js +1 -0
  213. package/dist/browser/protocol.js.map +1 -1
  214. package/dist/cli.d.ts.map +1 -1
  215. package/dist/cli.js +6 -0
  216. package/dist/cli.js.map +1 -1
  217. package/dist/commands/approvals.d.ts.map +1 -1
  218. package/dist/commands/approvals.js +1 -37
  219. package/dist/commands/approvals.js.map +1 -1
  220. package/dist/commands/browser/index.d.ts.map +1 -1
  221. package/dist/commands/browser/index.js +7 -2
  222. package/dist/commands/browser/index.js.map +1 -1
  223. package/dist/commands/daemon.d.ts.map +1 -1
  224. package/dist/commands/daemon.js +7 -3
  225. package/dist/commands/daemon.js.map +1 -1
  226. package/dist/commands/dispatch.d.ts.map +1 -1
  227. package/dist/commands/dispatch.js +27 -3
  228. package/dist/commands/dispatch.js.map +1 -1
  229. package/dist/commands/patent-doctor.d.ts +48 -0
  230. package/dist/commands/patent-doctor.d.ts.map +1 -0
  231. package/dist/commands/patent-doctor.js +109 -0
  232. package/dist/commands/patent-doctor.js.map +1 -0
  233. package/dist/commands/patent.d.ts +78 -0
  234. package/dist/commands/patent.d.ts.map +1 -0
  235. package/dist/commands/patent.js +919 -0
  236. package/dist/commands/patent.js.map +1 -0
  237. package/dist/commands/social.d.ts +19 -0
  238. package/dist/commands/social.d.ts.map +1 -0
  239. package/dist/commands/social.js +236 -0
  240. package/dist/commands/social.js.map +1 -0
  241. package/dist/core/registry.d.ts +1 -1
  242. package/dist/core/registry.d.ts.map +1 -1
  243. package/dist/core/registry.js +11 -2
  244. package/dist/core/registry.js.map +1 -1
  245. package/dist/discovery/loader.d.ts.map +1 -1
  246. package/dist/discovery/loader.js +4 -0
  247. package/dist/discovery/loader.js.map +1 -1
  248. package/dist/engine/approval-presenter.d.ts +10 -0
  249. package/dist/engine/approval-presenter.d.ts.map +1 -0
  250. package/dist/engine/approval-presenter.js +45 -0
  251. package/dist/engine/approval-presenter.js.map +1 -0
  252. package/dist/engine/approval-store.d.ts +4 -0
  253. package/dist/engine/approval-store.d.ts.map +1 -1
  254. package/dist/engine/approval-store.js +85 -11
  255. package/dist/engine/approval-store.js.map +1 -1
  256. package/dist/engine/auth/oauth2-cc.d.ts +67 -0
  257. package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
  258. package/dist/engine/auth/oauth2-cc.js +120 -0
  259. package/dist/engine/auth/oauth2-cc.js.map +1 -0
  260. package/dist/engine/cookies.d.ts +10 -0
  261. package/dist/engine/cookies.d.ts.map +1 -1
  262. package/dist/engine/cookies.js +64 -0
  263. package/dist/engine/cookies.js.map +1 -1
  264. package/dist/engine/download.d.ts +5 -0
  265. package/dist/engine/download.d.ts.map +1 -1
  266. package/dist/engine/download.js +11 -4
  267. package/dist/engine/download.js.map +1 -1
  268. package/dist/engine/executor.d.ts +1 -0
  269. package/dist/engine/executor.d.ts.map +1 -1
  270. package/dist/engine/executor.js +25 -0
  271. package/dist/engine/executor.js.map +1 -1
  272. package/dist/engine/framework.d.ts +5 -5
  273. package/dist/engine/framework.js +5 -5
  274. package/dist/engine/harden.d.ts +1 -1
  275. package/dist/engine/harden.js +1 -1
  276. package/dist/engine/kernel/stages.d.ts.map +1 -1
  277. package/dist/engine/kernel/stages.js +2 -1
  278. package/dist/engine/kernel/stages.js.map +1 -1
  279. package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
  280. package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
  281. package/dist/engine/normalizer/patent-envelope.js +132 -0
  282. package/dist/engine/normalizer/patent-envelope.js.map +1 -0
  283. package/dist/engine/research.d.ts +5 -7
  284. package/dist/engine/research.d.ts.map +1 -1
  285. package/dist/engine/research.js +6 -9
  286. package/dist/engine/research.js.map +1 -1
  287. package/dist/engine/steps/browser-helpers.d.ts +2 -2
  288. package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
  289. package/dist/engine/steps/browser-helpers.js +39 -16
  290. package/dist/engine/steps/browser-helpers.js.map +1 -1
  291. package/dist/engine/steps/download.d.ts +1 -0
  292. package/dist/engine/steps/download.d.ts.map +1 -1
  293. package/dist/engine/steps/download.js +3 -1
  294. package/dist/engine/steps/download.js.map +1 -1
  295. package/dist/engine/steps/index.d.ts +2 -0
  296. package/dist/engine/steps/index.d.ts.map +1 -1
  297. package/dist/engine/steps/index.js +2 -0
  298. package/dist/engine/steps/index.js.map +1 -1
  299. package/dist/engine/steps/oauth2-token.d.ts +41 -0
  300. package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
  301. package/dist/engine/steps/oauth2-token.js +115 -0
  302. package/dist/engine/steps/oauth2-token.js.map +1 -0
  303. package/dist/engine/steps/select-xml.d.ts +34 -0
  304. package/dist/engine/steps/select-xml.d.ts.map +1 -0
  305. package/dist/engine/steps/select-xml.js +222 -0
  306. package/dist/engine/steps/select-xml.js.map +1 -0
  307. package/dist/engine/template.d.ts.map +1 -1
  308. package/dist/engine/template.js +7 -0
  309. package/dist/engine/template.js.map +1 -1
  310. package/dist/engine/transport/mcp-browser.d.ts +128 -0
  311. package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
  312. package/dist/engine/transport/mcp-browser.js +120 -0
  313. package/dist/engine/transport/mcp-browser.js.map +1 -0
  314. package/dist/fast-path/handlers/approvals.d.ts +11 -0
  315. package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
  316. package/dist/fast-path/handlers/approvals.js +136 -0
  317. package/dist/fast-path/handlers/approvals.js.map +1 -0
  318. package/dist/fast-path/manifest.d.ts +1 -0
  319. package/dist/fast-path/manifest.d.ts.map +1 -1
  320. package/dist/fast-path/manifest.js.map +1 -1
  321. package/dist/fast-path.d.ts.map +1 -1
  322. package/dist/fast-path.js +3 -0
  323. package/dist/fast-path.js.map +1 -1
  324. package/dist/index.d.ts +23 -0
  325. package/dist/index.d.ts.map +1 -0
  326. package/dist/index.js +38 -0
  327. package/dist/index.js.map +1 -0
  328. package/dist/manifest-compact.txt +3 -3
  329. package/dist/manifest-search.json +1 -1
  330. package/dist/manifest.json +2239 -176
  331. package/dist/output/auth-guidance.d.ts +14 -0
  332. package/dist/output/auth-guidance.d.ts.map +1 -0
  333. package/dist/output/auth-guidance.js +50 -0
  334. package/dist/output/auth-guidance.js.map +1 -0
  335. package/dist/output/error-map.d.ts +1 -1
  336. package/dist/output/error-map.d.ts.map +1 -1
  337. package/dist/output/error-map.js +28 -4
  338. package/dist/output/error-map.js.map +1 -1
  339. package/dist/output/next-actions.d.ts.map +1 -1
  340. package/dist/output/next-actions.js +19 -3
  341. package/dist/output/next-actions.js.map +1 -1
  342. package/dist/registry.d.ts +18 -1
  343. package/dist/registry.d.ts.map +1 -1
  344. package/dist/registry.js +5 -0
  345. package/dist/registry.js.map +1 -1
  346. package/dist/social/browser-errors.d.ts +13 -0
  347. package/dist/social/browser-errors.d.ts.map +1 -0
  348. package/dist/social/browser-errors.js +36 -0
  349. package/dist/social/browser-errors.js.map +1 -0
  350. package/dist/social/capabilities.d.ts +29 -0
  351. package/dist/social/capabilities.d.ts.map +1 -0
  352. package/dist/social/capabilities.js +448 -0
  353. package/dist/social/capabilities.js.map +1 -0
  354. package/dist/social/comments.d.ts +26 -0
  355. package/dist/social/comments.d.ts.map +1 -0
  356. package/dist/social/comments.js +97 -0
  357. package/dist/social/comments.js.map +1 -0
  358. package/dist/social/video-text.d.ts +27 -0
  359. package/dist/social/video-text.d.ts.map +1 -0
  360. package/dist/social/video-text.js +140 -0
  361. package/dist/social/video-text.js.map +1 -0
  362. package/dist/types/patent.d.ts +160 -0
  363. package/dist/types/patent.d.ts.map +1 -0
  364. package/dist/types/patent.js +16 -0
  365. package/dist/types/patent.js.map +1 -0
  366. package/dist/types.d.ts +12 -0
  367. package/dist/types.d.ts.map +1 -1
  368. package/dist/types.js.map +1 -1
  369. package/package.json +9 -4
  370. package/server.json +3 -3
  371. package/skills/unicli/SKILL.md +1 -1
  372. package/skills/unicli-claude-code/SKILL.md +1 -1
  373. package/skills/unicli-hermes/SKILL.md +1 -1
  374. package/src/adapters/bilibili/comments-tree.test.ts +41 -0
  375. package/src/adapters/bilibili/comments.ts +78 -4
  376. package/src/adapters/bilibili/compat.ts +5 -2
  377. package/src/adapters/bilibili/download.ts +7 -4
  378. package/src/adapters/bilibili/wbi.ts +6 -3
  379. package/src/adapters/brave/search.yaml +53 -0
  380. package/src/adapters/cipo/_shared.ts +98 -0
  381. package/src/adapters/cipo/get.ts +188 -0
  382. package/src/adapters/cipo/legal-status.ts +148 -0
  383. package/src/adapters/cipo/search.ts +195 -0
  384. package/src/adapters/cnipa/_shared.ts +138 -0
  385. package/src/adapters/cnipa/get.ts +199 -0
  386. package/src/adapters/cnipa/legal-status.ts +162 -0
  387. package/src/adapters/cnipa/search.ts +229 -0
  388. package/src/adapters/dpma/get.yaml +67 -0
  389. package/src/adapters/dpma/search.yaml +77 -0
  390. package/src/adapters/duckduckgo/search.yaml +54 -0
  391. package/src/adapters/duckduckgo/suggest.yaml +52 -0
  392. package/src/adapters/epo/family.yaml +69 -0
  393. package/src/adapters/epo/get.yaml +74 -0
  394. package/src/adapters/epo/legal-status.yaml +63 -0
  395. package/src/adapters/epo/search.yaml +84 -0
  396. package/src/adapters/espacenet/_shared.ts +98 -0
  397. package/src/adapters/espacenet/family.ts +161 -0
  398. package/src/adapters/espacenet/get.ts +185 -0
  399. package/src/adapters/espacenet/legal-status.ts +151 -0
  400. package/src/adapters/espacenet/search.ts +229 -0
  401. package/src/adapters/facebook/subtitles.ts +44 -0
  402. package/src/adapters/fips/_shared.ts +109 -0
  403. package/src/adapters/fips/get.ts +186 -0
  404. package/src/adapters/fips/search.ts +195 -0
  405. package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
  406. package/src/adapters/freepatentsonline-web/get.ts +144 -0
  407. package/src/adapters/freepatentsonline-web/search.ts +170 -0
  408. package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
  409. package/src/adapters/google-patents-bq/search.yaml +97 -0
  410. package/src/adapters/google-patents-web/_shared.ts +242 -0
  411. package/src/adapters/google-patents-web/get.ts +224 -0
  412. package/src/adapters/google-patents-web/search.ts +196 -0
  413. package/src/adapters/inpi-br/_shared.ts +98 -0
  414. package/src/adapters/inpi-br/get.ts +193 -0
  415. package/src/adapters/inpi-br/search.ts +206 -0
  416. package/src/adapters/inpi-fr/get.yaml +62 -0
  417. package/src/adapters/inpi-fr/search.yaml +74 -0
  418. package/src/adapters/instagram/subtitles.ts +44 -0
  419. package/src/adapters/ipaustralia/get.yaml +67 -0
  420. package/src/adapters/ipaustralia/search.yaml +74 -0
  421. package/src/adapters/jpo/get.yaml +63 -0
  422. package/src/adapters/jpo/search.yaml +76 -0
  423. package/src/adapters/kipris/get.yaml +69 -0
  424. package/src/adapters/kipris/legal-status.yaml +58 -0
  425. package/src/adapters/kipris/search.yaml +79 -0
  426. package/src/adapters/lens/get.yaml +64 -0
  427. package/src/adapters/lens/search.yaml +82 -0
  428. package/src/adapters/mastodon/statuses.test.ts +82 -0
  429. package/src/adapters/mastodon/statuses.ts +208 -0
  430. package/src/adapters/patsnap/get.yaml +65 -0
  431. package/src/adapters/patsnap/search.yaml +77 -0
  432. package/src/adapters/pqai/prior-art.yaml +59 -0
  433. package/src/adapters/pqai/search.yaml +60 -0
  434. package/src/adapters/reddit/comments-tree.test.ts +79 -0
  435. package/src/adapters/reddit/comments.ts +159 -0
  436. package/src/adapters/threads/post.test.ts +64 -0
  437. package/src/adapters/threads/post.ts +366 -0
  438. package/src/adapters/threads/user.yaml +73 -0
  439. package/src/adapters/tiktok/subtitles.ts +44 -0
  440. package/src/adapters/twitter/accept.ts +5 -2
  441. package/src/adapters/twitter/browser-fallback.ts +138 -0
  442. package/src/adapters/twitter/browser-state.ts +74 -0
  443. package/src/adapters/twitter/client.ts +51 -21
  444. package/src/adapters/twitter/reply-dm.ts +5 -2
  445. package/src/adapters/twitter/reply.ts +1 -0
  446. package/src/adapters/twitter/search.ts +12 -38
  447. package/src/adapters/twitter/thread.test.ts +43 -0
  448. package/src/adapters/twitter/thread.ts +44 -2
  449. package/src/adapters/twitter/trending.ts +14 -95
  450. package/src/adapters/ukipo/info.yaml +43 -0
  451. package/src/adapters/uspto/get.yaml +67 -0
  452. package/src/adapters/uspto/legal-status.yaml +58 -0
  453. package/src/adapters/uspto/search.yaml +88 -0
  454. package/src/adapters/wipo-patentscope/info.yaml +43 -0
  455. package/src/adapters/xiaohongshu/browser-state.ts +95 -0
  456. package/src/adapters/xiaohongshu/comments.ts +29 -6
  457. package/src/adapters/xiaohongshu/download.ts +60 -11
  458. package/src/adapters/xiaohongshu/search.ts +18 -6
  459. package/src/adapters/xiaohongshu/trending.ts +112 -0
  460. package/src/adapters/yahoo/search.yaml +52 -0
  461. package/src/adapters/youtube/comments-microformat.test.ts +35 -0
  462. package/src/adapters/youtube/comments-tree.test.ts +74 -0
  463. package/src/adapters/youtube/comments.ts +166 -12
  464. package/src/adapters/youtube/subtitles.ts +44 -0
  465. package/src/adapters/yt-dlp/subtitles.ts +43 -0
  466. package/src/adapters/zhihu/answer-detail.test.ts +83 -0
  467. package/src/adapters/zhihu/answer-detail.ts +275 -0
  468. package/src/adapters/zhihu/comment-tree.test.ts +57 -0
  469. package/src/adapters/zhihu/comment.ts +186 -0
  470. package/src/adapters/zhihu/recommend.test.ts +65 -0
  471. package/src/adapters/zhihu/recommend.ts +207 -0
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @owner src::adapters::inpi-br::_shared
3
+ * @does Shared helpers for the INPI Brasil browser adapter — busca.inpi.gov.br/pePI/ has no programmatic API today (pre-API status); the browser route is the only path.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/types/patent.ts
5
+ * @feeds src/adapters/inpi-br/*.ts
6
+ * @breaks none — pure helpers
7
+ * @invariants every transport gap surfaces as a PatentEnvelope row
8
+ * @side-effects none
9
+ * @perf n/a
10
+ * @concurrency safe
11
+ * @test covered transitively
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
15
+ */
16
+
17
+ import {
18
+ TransportError,
19
+ initMcpBrowserTransport,
20
+ mcpBrowserEvaluate,
21
+ mcpBrowserNavigate,
22
+ type McpBrowserResult,
23
+ } from "../../engine/transport/mcp-browser.js";
24
+ import { buildPatentEnvelope } from "../../engine/normalizer/patent-envelope.js";
25
+ import type { PatentEnvelope, PatentErrorCode } from "../../types/patent.js";
26
+
27
+ export function inpiBrEnvelope(
28
+ code: PatentErrorCode,
29
+ adapter_path: string,
30
+ step: string,
31
+ suggestion: string,
32
+ alternatives: string[] = [],
33
+ ): PatentEnvelope {
34
+ return buildPatentEnvelope({
35
+ code,
36
+ adapter_path,
37
+ step,
38
+ suggestion,
39
+ alternatives,
40
+ retryable: false,
41
+ });
42
+ }
43
+
44
+ export function transportErrorToInpiBrEnvelope(
45
+ err: TransportError,
46
+ adapter_path: string,
47
+ step: string,
48
+ ): PatentEnvelope {
49
+ if (err.code === "MCP_BUS_MISSING") {
50
+ return buildPatentEnvelope({
51
+ code: "PATENT_API_DEPRECATED",
52
+ adapter_path,
53
+ step,
54
+ suggestion:
55
+ "engine has no outbound MCP transport wired into the bus today; INPI Brasil has no upstream API so the browser path is the only route — install an McpResolver to activate this adapter",
56
+ alternatives: ["espacenet", "lens"],
57
+ retryable: false,
58
+ });
59
+ }
60
+ return buildPatentEnvelope({
61
+ code: "PATENT_API_DEPRECATED",
62
+ adapter_path,
63
+ step,
64
+ suggestion: `mcp-browser transport error (${err.code}): ${err.message}`,
65
+ alternatives: ["espacenet"],
66
+ retryable: false,
67
+ });
68
+ }
69
+
70
+ export async function inpiBrNavigateAndExtract<T>(
71
+ url: string,
72
+ expression: string,
73
+ ): Promise<McpBrowserResult<T>> {
74
+ const init = await initMcpBrowserTransport();
75
+ if (init.active_server === "none") {
76
+ const code =
77
+ init.reason === "bus-missing" ? "MCP_BUS_MISSING" : "MCP_NO_SERVER";
78
+ throw new TransportError(code, `mcp-browser unavailable (${init.reason})`);
79
+ }
80
+ const navResult = await mcpBrowserNavigate({ url });
81
+ if (!navResult.ok) {
82
+ throw new TransportError(
83
+ navResult.code ?? "MCP_NAVIGATE_FAILED",
84
+ navResult.message ?? "navigate did not succeed",
85
+ );
86
+ }
87
+ const evalResult = await mcpBrowserEvaluate<T>({
88
+ expression,
89
+ tab: navResult.tab,
90
+ });
91
+ if (!evalResult.ok) {
92
+ throw new TransportError(
93
+ evalResult.code ?? "MCP_EVALUATE_FAILED",
94
+ evalResult.message ?? "evaluate did not succeed",
95
+ );
96
+ }
97
+ return evalResult;
98
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @owner src::adapters::inpi-br::get
3
+ * @does Browser-driven retrieval of an INPI Brasil patent record by application/publication number; extracts the bibliographic block from the pePI detail page.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/adapters/inpi-br/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.get)
6
+ * @breaks PATENT_INVALID_NUMBER, PATENT_NOT_FOUND, PATENT_API_DEPRECATED (MCP_BUS_MISSING)
7
+ * @invariants output row is a canonical PatentRecord
8
+ * @side-effects controls Chrome via MCP
9
+ * @perf single navigate + evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/inpi-br/search.test.ts (shared transport-error path)
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
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
+ inpiBrEnvelope,
22
+ inpiBrNavigateAndExtract,
23
+ transportErrorToInpiBrEnvelope,
24
+ } from "./_shared.js";
25
+
26
+ const ADAPTER_PATH = "src/adapters/inpi-br/get.ts";
27
+
28
+ interface InpiBrDetail {
29
+ publication_number?: string;
30
+ application_number?: string;
31
+ title?: string;
32
+ abstract?: string;
33
+ applicant?: string;
34
+ inventor?: string;
35
+ publication_date?: string;
36
+ filing_date?: string;
37
+ source_url?: string;
38
+ }
39
+
40
+ const DETAIL_EXTRACTOR = `(() => {
41
+ const text = (sel) => {
42
+ const node = document.querySelector(sel);
43
+ return node ? (node.textContent || '').trim() : '';
44
+ };
45
+ return {
46
+ publication_number: text('[data-field="numPedido"], .num-pedido, td.numero'),
47
+ application_number: text('[data-field="numAplicacao"], .num-aplicacao'),
48
+ title: text('[data-field="titulo"], .titulo, h1'),
49
+ abstract: text('[data-field="resumo"], .resumo'),
50
+ applicant: text('[data-field="depositante"], .depositante'),
51
+ inventor: text('[data-field="inventor"], .inventor'),
52
+ publication_date: text('[data-field="dataPub"], .data-pub'),
53
+ filing_date: text('[data-field="dataDep"], .data-dep'),
54
+ source_url: location.href,
55
+ };
56
+ })()`;
57
+
58
+ function detailUrlFor(pubNo: string): string {
59
+ const stripped = pubNo.replace(/^BR[-]?/, "");
60
+ const params = new URLSearchParams({
61
+ Action: "detail",
62
+ NumPedido: stripped,
63
+ });
64
+ return `https://busca.inpi.gov.br/pePI/servlet/PatenteServletController?${params.toString()}`;
65
+ }
66
+
67
+ export async function runInpiBrGet(kwargs: {
68
+ publication_number: string;
69
+ }): Promise<unknown[]> {
70
+ const pubNo = String(kwargs.publication_number ?? "").trim();
71
+ if (pubNo.length === 0) {
72
+ return [
73
+ {
74
+ envelope: inpiBrEnvelope(
75
+ "PATENT_INVALID_NUMBER",
76
+ ADAPTER_PATH,
77
+ "validate",
78
+ "inpi-br get requires a non-empty publication_number",
79
+ ),
80
+ },
81
+ ];
82
+ }
83
+ const url = detailUrlFor(pubNo);
84
+ let detail: InpiBrDetail;
85
+ try {
86
+ const result = await inpiBrNavigateAndExtract<InpiBrDetail>(
87
+ url,
88
+ DETAIL_EXTRACTOR,
89
+ );
90
+ if (!result.data) {
91
+ return [
92
+ {
93
+ envelope: inpiBrEnvelope(
94
+ "PATENT_SCHEMA_DRIFT",
95
+ ADAPTER_PATH,
96
+ "evaluate",
97
+ "inpi-br detail evaluate returned no data",
98
+ ),
99
+ },
100
+ ];
101
+ }
102
+ detail = result.data;
103
+ } catch (err) {
104
+ if (err instanceof TransportError) {
105
+ return [
106
+ {
107
+ envelope: transportErrorToInpiBrEnvelope(
108
+ err,
109
+ ADAPTER_PATH,
110
+ "navigate",
111
+ ),
112
+ },
113
+ ];
114
+ }
115
+ throw err;
116
+ }
117
+ if (!detail.publication_number && !detail.title) {
118
+ return [
119
+ {
120
+ envelope: inpiBrEnvelope(
121
+ "PATENT_NOT_FOUND",
122
+ ADAPTER_PATH,
123
+ "evaluate",
124
+ `inpi-br detail page for "${pubNo}" yielded no bibliographic fields`,
125
+ ["espacenet"],
126
+ ),
127
+ },
128
+ ];
129
+ }
130
+ const rawPubNo = detail.publication_number || pubNo;
131
+ const canonicalPubNo = /^BR[-]?/.test(rawPubNo) ? rawPubNo : `BR${rawPubNo}`;
132
+ try {
133
+ return [
134
+ assemblePatentRecord({
135
+ publication_number: canonicalPubNo,
136
+ application_number: detail.application_number || undefined,
137
+ title: detail.title || undefined,
138
+ abstract: detail.abstract || undefined,
139
+ assignees: detail.applicant
140
+ ? [{ name: detail.applicant, country: "BR" }]
141
+ : undefined,
142
+ inventors: detail.inventor
143
+ ? [{ name: detail.inventor, country: "BR" }]
144
+ : undefined,
145
+ publication_date: detail.publication_date || undefined,
146
+ filing_date: detail.filing_date || undefined,
147
+ source_adapter: "inpi-br",
148
+ source_url: detail.source_url || url,
149
+ } as Parameters<typeof assemblePatentRecord>[0]),
150
+ ];
151
+ } catch {
152
+ return [
153
+ {
154
+ envelope: inpiBrEnvelope(
155
+ "PATENT_NOT_FOUND",
156
+ ADAPTER_PATH,
157
+ "normalize",
158
+ `inpi-br detail page for "${pubNo}" did not yield a valid publication_number`,
159
+ ["espacenet"],
160
+ ),
161
+ },
162
+ ];
163
+ }
164
+ }
165
+
166
+ cli({
167
+ site: "inpi-br",
168
+ name: "get",
169
+ description: "Retrieve a single INPI Brasil patent record (browser-only)",
170
+ domain: "busca.inpi.gov.br",
171
+ strategy: Strategy.PUBLIC,
172
+ adapter_path: ADAPTER_PATH,
173
+ args: [
174
+ {
175
+ name: "publication_number",
176
+ type: "str",
177
+ required: true,
178
+ positional: true,
179
+ description: "Brazil patent application/publication number",
180
+ },
181
+ ],
182
+ columns: [
183
+ "publication_number",
184
+ "title",
185
+ "publication_date",
186
+ "filing_date",
187
+ "source_url",
188
+ ],
189
+ capabilities: ["mcp-browser.navigate", "mcp-browser.evaluate", "patent.get"],
190
+ minimum_capability: "mcp-browser.evaluate",
191
+ func: async (_page, kwargs) =>
192
+ runInpiBrGet(kwargs as { publication_number: string }),
193
+ });
@@ -0,0 +1,206 @@
1
+ /**
2
+ * @owner src::adapters::inpi-br::search
3
+ * @does Browser-driven INPI Brasil search at busca.inpi.gov.br/pePI/ — Brazil's patent office has no open API (pre-API status); the public web search is the only programmatic surface.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/adapters/inpi-br/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.search)
6
+ * @breaks PATENT_UNSUPPORTED_QUERY (empty), PATENT_NOT_FOUND (no rows), PATENT_API_DEPRECATED with MCP_BUS_MISSING
7
+ * @invariants output rows canonicalized into PatentRecord with source_adapter='inpi-br'
8
+ * @side-effects controls Chrome via MCP
9
+ * @perf single navigate + evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/inpi-br/search.test.ts
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
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
+ inpiBrEnvelope,
22
+ inpiBrNavigateAndExtract,
23
+ transportErrorToInpiBrEnvelope,
24
+ } from "./_shared.js";
25
+
26
+ const ADAPTER_PATH = "src/adapters/inpi-br/search.ts";
27
+ const INPI_BR_SEARCH_URL =
28
+ "https://busca.inpi.gov.br/pePI/servlet/PatenteServletController";
29
+
30
+ interface InpiBrRow {
31
+ publication_number: string;
32
+ title?: string;
33
+ applicant?: string;
34
+ publication_date?: string;
35
+ filing_date?: string;
36
+ source_url?: string;
37
+ }
38
+
39
+ const EXTRACTOR = `(() => {
40
+ const rows = Array.from(
41
+ document.querySelectorAll('table.tabela tr.linha, table tr[bgcolor]')
42
+ ).map((el) => {
43
+ const text = (sel) => {
44
+ const node = el.querySelector(sel);
45
+ return node ? (node.textContent || '').trim() : '';
46
+ };
47
+ const cells = Array.from(el.querySelectorAll('td')).map((td) => (td.textContent || '').trim());
48
+ const linkEl = el.querySelector('a[href]');
49
+ return {
50
+ publication_number: text('td.num-pedido, td:first-child') || (cells[0] || ''),
51
+ title: text('td.titulo, td:nth-child(3)') || (cells[2] || ''),
52
+ applicant: text('td.depositante, td:nth-child(4)') || (cells[3] || ''),
53
+ publication_date: text('td.data-pub, td:nth-child(5)') || (cells[4] || ''),
54
+ filing_date: text('td.data-dep, td:nth-child(2)') || (cells[1] || ''),
55
+ source_url: linkEl ? linkEl.href : '',
56
+ };
57
+ });
58
+ return { rows };
59
+ })()`;
60
+
61
+ function buildSearchUrl(query: string): string {
62
+ const params = new URLSearchParams({
63
+ Action: "searchPatente",
64
+ ExpressaoPesquisa: query,
65
+ });
66
+ return `${INPI_BR_SEARCH_URL}?${params.toString()}`;
67
+ }
68
+
69
+ export async function runInpiBrSearch(kwargs: {
70
+ query: string;
71
+ limit?: number;
72
+ }): Promise<unknown[]> {
73
+ const limit =
74
+ typeof kwargs.limit === "number" && Number.isFinite(kwargs.limit)
75
+ ? Math.max(1, Math.min(100, Math.floor(kwargs.limit)))
76
+ : 25;
77
+ const query = String(kwargs.query ?? "").trim();
78
+ if (query.length === 0) {
79
+ return [
80
+ {
81
+ envelope: inpiBrEnvelope(
82
+ "PATENT_UNSUPPORTED_QUERY",
83
+ ADAPTER_PATH,
84
+ "validate",
85
+ "inpi-br search requires a non-empty query",
86
+ ),
87
+ },
88
+ ];
89
+ }
90
+ const url = buildSearchUrl(query);
91
+ let extract: { rows: InpiBrRow[] };
92
+ try {
93
+ const result = await inpiBrNavigateAndExtract<{ rows: InpiBrRow[] }>(
94
+ url,
95
+ EXTRACTOR,
96
+ );
97
+ if (!result.data) {
98
+ return [
99
+ {
100
+ envelope: inpiBrEnvelope(
101
+ "PATENT_SCHEMA_DRIFT",
102
+ ADAPTER_PATH,
103
+ "evaluate",
104
+ "inpi-br evaluate returned no data; selectors likely drifted",
105
+ ),
106
+ },
107
+ ];
108
+ }
109
+ extract = result.data;
110
+ } catch (err) {
111
+ if (err instanceof TransportError) {
112
+ return [
113
+ {
114
+ envelope: transportErrorToInpiBrEnvelope(
115
+ err,
116
+ ADAPTER_PATH,
117
+ "navigate",
118
+ ),
119
+ },
120
+ ];
121
+ }
122
+ throw err;
123
+ }
124
+ if (extract.rows.length === 0) {
125
+ return [
126
+ {
127
+ envelope: inpiBrEnvelope(
128
+ "PATENT_NOT_FOUND",
129
+ ADAPTER_PATH,
130
+ "evaluate",
131
+ `inpi-br returned no rows for query "${query}"`,
132
+ ["espacenet", "lens"],
133
+ ),
134
+ },
135
+ ];
136
+ }
137
+ const out: unknown[] = [];
138
+ for (const row of extract.rows.slice(0, limit)) {
139
+ if (!row.publication_number) continue;
140
+ const normalizedPub = /^BR[-]?/.test(row.publication_number)
141
+ ? row.publication_number
142
+ : `BR${row.publication_number}`;
143
+ try {
144
+ out.push(
145
+ assemblePatentRecord({
146
+ publication_number: normalizedPub,
147
+ title: row.title || undefined,
148
+ assignees: row.applicant
149
+ ? [{ name: row.applicant, country: "BR" }]
150
+ : undefined,
151
+ publication_date: row.publication_date || undefined,
152
+ filing_date: row.filing_date || undefined,
153
+ source_adapter: "inpi-br",
154
+ source_url: row.source_url || url,
155
+ } as Parameters<typeof assemblePatentRecord>[0]),
156
+ );
157
+ } catch {
158
+ // Skip malformed rows.
159
+ }
160
+ }
161
+ if (out.length === 0) {
162
+ out.push({
163
+ envelope: inpiBrEnvelope(
164
+ "PATENT_NOT_FOUND",
165
+ ADAPTER_PATH,
166
+ "normalize",
167
+ "inpi-br returned rows but none normalized to a valid publication_number",
168
+ ["espacenet"],
169
+ ),
170
+ });
171
+ }
172
+ return out;
173
+ }
174
+
175
+ cli({
176
+ site: "inpi-br",
177
+ name: "search",
178
+ description: "Search INPI Brasil patents (browser-only, no upstream API)",
179
+ domain: "busca.inpi.gov.br",
180
+ strategy: Strategy.PUBLIC,
181
+ adapter_path: ADAPTER_PATH,
182
+ args: [
183
+ {
184
+ name: "query",
185
+ type: "str",
186
+ required: true,
187
+ positional: true,
188
+ description: "Free-text query for INPI Brasil patent search",
189
+ },
190
+ {
191
+ name: "limit",
192
+ type: "int",
193
+ default: 25,
194
+ description: "Max results (1-100)",
195
+ },
196
+ ],
197
+ columns: ["publication_number", "title", "publication_date", "source_url"],
198
+ capabilities: [
199
+ "mcp-browser.navigate",
200
+ "mcp-browser.evaluate",
201
+ "patent.search",
202
+ ],
203
+ minimum_capability: "mcp-browser.evaluate",
204
+ func: async (_page, kwargs) =>
205
+ runInpiBrSearch(kwargs as { query: string; limit?: number }),
206
+ });
@@ -0,0 +1,62 @@
1
+ # @owner src::adapters::inpi-fr::get
2
+ # @does Fetch a French patent record by publication number via the INPI public open-data API.
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/map.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on 404 or 5xx; some legal-status / inventor fields require an INPI session-login this adapter does not perform
6
+ # @invariants output row conforms to PatentRecord
7
+ # @side-effects HTTPS egress to api-recherche.inpi.fr
8
+ # @perf single request
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key — session-cookie auth not implemented; only the open public-record subset is reachable
14
+ site: inpi-fr
15
+ name: get
16
+ description: Fetch a French patent record by publication number (open subset)
17
+ domain: api.inpi.fr
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: French publication number (e.g. FR3098765)
28
+
29
+ pipeline:
30
+ - fetch:
31
+ url: "https://api-recherche.inpi.fr/services/patents/${{ args.publication_number | urlencode }}"
32
+ method: GET
33
+ headers:
34
+ Accept: application/json
35
+
36
+ - map:
37
+ publication_number: "${{ 'FR-' + (item.publicationNumber || args.publication_number || '') + '-' + (item.kindCode || '') }}"
38
+ application_number: "${{ item.applicationNumber || '' }}"
39
+ title: "${{ item.title || item.titleFr || item.titleEn || '' }}"
40
+ abstract: "${{ item.abstract || item.abstractFr || item.abstractEn || '' }}"
41
+ kind_code: "${{ item.kindCode || '' }}"
42
+ filing_date: "${{ item.filingDate || item.applicationDate || '' }}"
43
+ publication_date: "${{ item.publicationDate || '' }}"
44
+ grant_date: "${{ item.grantDate || '' }}"
45
+ priority_date: "${{ item.priorityDate || '' }}"
46
+ legal_status: "${{ item.legalStatus || item.status || '' }}"
47
+ inventors: "${{ JSON.stringify((function(){ var i=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: 'FR' })).filter(x => x.name); })()) }}"
48
+ assignees: "${{ JSON.stringify((function(){ var a=item.applicants || item.holders; if(!a) return []; var arr = Array.isArray(a) ? a : [a]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'FR' })).filter(x => x.name); })()) }}"
49
+ 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); })()) }}"
50
+ source_adapter: inpi-fr
51
+ source_url: "${{ 'https://data.inpi.fr/brevets/' + (args.publication_number || '') }}"
52
+ retrieved_at: ""
53
+
54
+ columns: [publication_number, title, filing_date, publication_date]
55
+
56
+ # schema-v2 metadata
57
+ capabilities: ["http.fetch", "patent.get"]
58
+ minimum_capability: http.fetch
59
+ trust: public
60
+ confidentiality: public
61
+ quarantine: false
62
+ schema_version: v2
@@ -0,0 +1,74 @@
1
+ # @owner src::adapters::inpi-fr::search
2
+ # @does Search French patents (FR brevets) via the public INPI search API (open subset, no login).
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/select.ts, src/engine/steps/map.ts, src/engine/steps/limit.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on 5xx or rate limit; INPI's full-feature endpoints require an authenticated session — this adapter implements only the public open-data subset
6
+ # @invariants output rows conform to PatentRecord; publication_number is `FR-<doc>-<kind>`
7
+ # @side-effects HTTPS egress to api.inpi.fr / api-recherche.inpi.fr; no env reads
8
+ # @perf single request
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key — INPI public search API throttles anonymous traffic and the full record endpoints require a session cookie. Session-cookie login flow is not implemented in this adapter; the search endpoint exercised here is the open subset documented at data.inpi.fr.
14
+ site: inpi-fr
15
+ name: search
16
+ description: Search French patents via the INPI public open-data search API
17
+ domain: api.inpi.fr
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ query:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: Free-text query
28
+ limit:
29
+ type: int
30
+ default: 25
31
+ description: Maximum results
32
+
33
+ pipeline:
34
+ - fetch:
35
+ url: "https://api-recherche.inpi.fr/services/patents/search"
36
+ method: GET
37
+ headers:
38
+ Accept: application/json
39
+ params:
40
+ q: "${{ args.query }}"
41
+ nbResultsParPage: "${{ args.limit }}"
42
+ page: "1"
43
+
44
+ - select: results
45
+
46
+ # INPI open-data JSON; field names mirror INPI's documented schema.
47
+ - map:
48
+ publication_number: "${{ 'FR-' + (item.publicationNumber || item.applicationNumber || '') + '-' + (item.kindCode || '') }}"
49
+ application_number: "${{ item.applicationNumber || '' }}"
50
+ title: "${{ item.title || item.titleFr || item.titleEn || '' }}"
51
+ abstract: "${{ item.abstract || item.abstractFr || item.abstractEn || '' }}"
52
+ kind_code: "${{ item.kindCode || '' }}"
53
+ filing_date: "${{ item.filingDate || item.applicationDate || '' }}"
54
+ publication_date: "${{ item.publicationDate || '' }}"
55
+ grant_date: "${{ item.grantDate || '' }}"
56
+ priority_date: "${{ item.priorityDate || '' }}"
57
+ inventors: "${{ JSON.stringify((function(){ var i=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: 'FR' })).filter(x => x.name); })()) }}"
58
+ assignees: "${{ JSON.stringify((function(){ var a=item.applicants || item.holders; if(!a) return []; var arr = Array.isArray(a) ? a : [a]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'FR' })).filter(x => x.name); })()) }}"
59
+ 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); })()) }}"
60
+ source_adapter: inpi-fr
61
+ source_url: "${{ 'https://data.inpi.fr/brevets/' + (item.publicationNumber || item.applicationNumber || '') }}"
62
+ retrieved_at: ""
63
+
64
+ - limit: "${{ args.limit }}"
65
+
66
+ columns: [publication_number, title, filing_date, publication_date]
67
+
68
+ # schema-v2 metadata
69
+ capabilities: ["http.fetch", "patent.search"]
70
+ minimum_capability: http.fetch
71
+ trust: public
72
+ confidentiality: public
73
+ quarantine: false
74
+ schema_version: v2
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @owner Instagram subtitle adapter.
3
+ * @does Extracts LLM-readable subtitle text from public Instagram reel and video URLs.
4
+ * @needs `yt-dlp` on PATH and an accessible video subtitle track.
5
+ * @feeds Cross-platform social video analysis workflows.
6
+ * @breaks Instagram or yt-dlp extractor changes can alter subtitle availability.
7
+ */
8
+
9
+ import { cli, Strategy } from "../../registry.js";
10
+ import { runVideoSubtitleExtraction } from "../../social/video-text.js";
11
+
12
+ cli({
13
+ site: "instagram",
14
+ name: "subtitles",
15
+ description:
16
+ "Extract LLM-readable subtitles from an Instagram reel or video URL with optional browser-cookie reuse",
17
+ domain: "www.instagram.com",
18
+ strategy: Strategy.PUBLIC,
19
+ args: [
20
+ {
21
+ name: "url",
22
+ type: "str",
23
+ required: true,
24
+ positional: true,
25
+ description: "Instagram reel or video URL",
26
+ format: "uri",
27
+ },
28
+ {
29
+ name: "languages",
30
+ type: "str",
31
+ default: "zh-Hans,zh,en",
32
+ description: "Comma-separated subtitle languages",
33
+ },
34
+ {
35
+ name: "cookies-from-browser",
36
+ type: "str",
37
+ description: "Browser name for yt-dlp --cookies-from-browser",
38
+ },
39
+ ],
40
+ columns: ["language", "text", "path"],
41
+ socialCapabilities: ["read", "media", "subtitles"],
42
+ defaultFormat: "json",
43
+ func: async (_page, kwargs) => runVideoSubtitleExtraction(kwargs),
44
+ });