argo-search 1.0.1 → 2.9.8

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 (472) hide show
  1. package/LICENSE +201 -21
  2. package/README.en.md +735 -0
  3. package/README.es.md +777 -0
  4. package/README.ja.md +777 -0
  5. package/README.ko.md +777 -0
  6. package/README.md +778 -320
  7. package/SKILL.md +135 -0
  8. package/assets/readme/hero.svg +121 -0
  9. package/assets/readme/made-with-beautify.svg +10 -0
  10. package/assets/readme/proof-routes.svg +73 -0
  11. package/assets/readme/why-better.svg +104 -0
  12. package/assets/readme/workflow.svg +83 -0
  13. package/backends/domain_profiles.json +2356 -96
  14. package/backends/engine_registry.yaml +3428 -503
  15. package/backends/query_synonyms_cn.json +35 -0
  16. package/backends/quota_profiles.json +2488 -160
  17. package/backends/source_types_cn.json +109 -0
  18. package/backends/text_lexicon.json +44 -0
  19. package/bin/argo +772 -0
  20. package/bin/argo.js +102 -39
  21. package/config.yaml +5139 -367
  22. package/cordis.patch.yml +21 -0
  23. package/data/countries.json +40 -0
  24. package/data/lang_matrix/lang_capability.json +842 -0
  25. package/data/lang_matrix/matrix_2026-09-10.json +11921 -0
  26. package/data/regions_cn.json +1 -0
  27. package/docs/ADDING_NEW_ENGINE.md +184 -0
  28. package/docs/ARGO_INTRO.md +124 -0
  29. package/docs/DATA_SOURCE_GAPS.md +81 -0
  30. package/docs/DESIGN_LOCAL_DATA_FUSION.md +90 -0
  31. package/docs/ENGINE_CATALOG.md +575 -0
  32. package/docs/MCP_SETUP.md +108 -0
  33. package/docs/PLATFORM_PATHS.md +111 -0
  34. package/docs/RELEASE_NOTES_v2.8.0.md +71 -0
  35. package/docs/RELEASE_NOTES_v2.8.2.md +63 -0
  36. package/docs/RELEASE_NOTES_v2.8.3.md +55 -0
  37. package/docs/RELEASE_NOTES_v2.8.4.md +79 -0
  38. package/docs/RELEASE_NOTES_v2.8.5.md +102 -0
  39. package/docs/RELEASE_NOTES_v2.8.6.md +66 -0
  40. package/docs/RELEASE_NOTES_v2.8.7.md +65 -0
  41. package/docs/RELEASE_NOTES_v2.8.8.md +67 -0
  42. package/docs/RELEASE_NOTES_v2.8.9.md +67 -0
  43. package/docs/RELEASE_NOTES_v2.9.0.md +64 -0
  44. package/docs/RELEASE_NOTES_v2.9.8.md +73 -0
  45. package/docs/SEARCH_ARCHIVE.md +115 -0
  46. package/docs/assets/architecture.svg +104 -0
  47. package/docs/assets/hero.svg +98 -0
  48. package/docs/engines/bangumi.md +27 -0
  49. package/docs/engines/biorxiv.md +27 -0
  50. package/docs/engines/clawhub.md +27 -0
  51. package/docs/engines/crt_sh.md +27 -0
  52. package/docs/engines/datacite.md +27 -0
  53. package/docs/engines/deps_dev.md +27 -0
  54. package/docs/engines/douban_movie.md +27 -0
  55. package/docs/engines/endoflife.md +27 -0
  56. package/docs/engines/flk_law.md +27 -0
  57. package/docs/engines/fxtwitter.md +27 -0
  58. package/docs/engines/google_news.md +27 -0
  59. package/docs/engines/gov_regulations.md +27 -0
  60. package/docs/engines/guqian.md +27 -0
  61. package/docs/engines/hackernews.md +27 -0
  62. package/docs/engines/iplant.md +27 -0
  63. package/docs/engines/keenable.md +27 -0
  64. package/docs/engines/met_museum.md +27 -0
  65. package/docs/engines/nasa_images.md +27 -0
  66. package/docs/engines/netease_music.md +27 -0
  67. package/docs/engines/npm.md +27 -0
  68. package/docs/engines/nvd.md +27 -0
  69. package/docs/engines/openreview.md +27 -0
  70. package/docs/engines/openstd.md +27 -0
  71. package/docs/engines/parallel_free.md +27 -0
  72. package/docs/engines/people_daily.md +27 -0
  73. package/docs/engines/realtime_index.md +27 -0
  74. package/docs/engines/sec_edgar.md +27 -0
  75. package/docs/engines/seltz.md +27 -0
  76. package/docs/engines/skillsmp.md +27 -0
  77. package/docs/engines/sspai.md +27 -0
  78. package/docs/engines/std_samr.md +27 -0
  79. package/docs/engines/train.md +27 -0
  80. package/docs/engines/un_comtrade.md +27 -0
  81. package/docs/engines/wikisource.md +27 -0
  82. package/docs/engines/zdic.md +27 -0
  83. package/docs/engines/zenodo.md +27 -0
  84. package/docs/engines/zhihu_hot_app.md +27 -0
  85. package/docs//344/270/272/344/273/200/344/271/210/351/200/211/346/213/251argo.md +176 -0
  86. package/engines/README.md +10 -0
  87. package/engines/_template_cli.yaml +39 -0
  88. package/engines/_template_http.yaml +37 -0
  89. package/engines/plugins/_template_plugin.py +50 -0
  90. package/engines/specs/_cisa_kev.yaml +54 -0
  91. package/engines/specs/_osv.yaml +63 -0
  92. package/engines/specs/aljazeera.yaml +43 -0
  93. package/engines/specs/antara.yaml +43 -0
  94. package/engines/specs/artic.yaml +20 -0
  95. package/engines/specs/aviation_weather.yaml +39 -0
  96. package/engines/specs/bangumi.yaml +21 -0
  97. package/engines/specs/biorxiv.yaml +24 -0
  98. package/engines/specs/carbon_intensity.yaml +32 -0
  99. package/engines/specs/cfets.yaml +41 -0
  100. package/engines/specs/cinii.yaml +44 -0
  101. package/engines/specs/clawhub.yaml +49 -0
  102. package/engines/specs/cleveland.yaml +19 -0
  103. package/engines/specs/cn_ai_news.yaml +43 -0
  104. package/engines/specs/core.yaml +35 -0
  105. package/engines/specs/crt_sh.yaml +38 -0
  106. package/engines/specs/ct24.yaml +43 -0
  107. package/engines/specs/datacite.yaml +27 -0
  108. package/engines/specs/datagov_uk.yaml +41 -0
  109. package/engines/specs/ddgs_images.yaml +45 -0
  110. package/engines/specs/deepseek_search.yaml +74 -0
  111. package/engines/specs/deezer.yaml +20 -0
  112. package/engines/specs/defillama.yaml +38 -0
  113. package/engines/specs/deps_dev.yaml +21 -0
  114. package/engines/specs/digup.yaml +36 -0
  115. package/engines/specs/doi.yaml +39 -0
  116. package/engines/specs/douban_movie.yaml +22 -0
  117. package/engines/specs/dw_news.yaml +47 -0
  118. package/engines/specs/egov_law.yaml +21 -0
  119. package/engines/specs/elpais.yaml +43 -0
  120. package/engines/specs/endoflife.yaml +21 -0
  121. package/engines/specs/energy_charts.yaml +21 -0
  122. package/engines/specs/factcheck_org.yaml +52 -0
  123. package/engines/specs/faz.yaml +43 -0
  124. package/engines/specs/federal_register.yaml +57 -0
  125. package/engines/specs/firecrawl.yaml +53 -0
  126. package/engines/specs/flk_law.yaml +24 -0
  127. package/engines/specs/folha.yaml +43 -0
  128. package/engines/specs/france24.yaml +44 -0
  129. package/engines/specs/full_fact.yaml +47 -0
  130. package/engines/specs/fxtwitter.yaml +36 -0
  131. package/engines/specs/gbfs_nyc.yaml +32 -0
  132. package/engines/specs/gdacs.yaml +21 -0
  133. package/engines/specs/gdelt.yaml +64 -0
  134. package/engines/specs/gleif.yaml +55 -0
  135. package/engines/specs/google_news.yaml +22 -0
  136. package/engines/specs/gov_regulations.yaml +38 -0
  137. package/engines/specs/guardian_rss.yaml +59 -0
  138. package/engines/specs/hkex.yaml +40 -0
  139. package/engines/specs/hurriyet.yaml +43 -0
  140. package/engines/specs/iplant.yaml +25 -0
  141. package/engines/specs/jikan.yaml +24 -0
  142. package/engines/specs/jolpica.yaml +20 -0
  143. package/engines/specs/k10plus.yaml +20 -0
  144. package/engines/specs/keenable.yaml +44 -0
  145. package/engines/specs/keenable_free.yaml +36 -0
  146. package/engines/specs/lefigaro.yaml +43 -0
  147. package/engines/specs/listenbrainz.yaml +19 -0
  148. package/engines/specs/matichon.yaml +43 -0
  149. package/engines/specs/met_museum.yaml +21 -0
  150. package/engines/specs/nasa_images.yaml +45 -0
  151. package/engines/specs/netease_music.yaml +38 -0
  152. package/engines/specs/nhk.yaml +43 -0
  153. package/engines/specs/nhtsa_vpic.yaml +20 -0
  154. package/engines/specs/noaa_swpc.yaml +20 -0
  155. package/engines/specs/nvd.yaml +38 -0
  156. package/engines/specs/obis.yaml +20 -0
  157. package/engines/specs/opencitations.yaml +52 -0
  158. package/engines/specs/openf1.yaml +21 -0
  159. package/engines/specs/openfoodfacts.yaml +45 -0
  160. package/engines/specs/openligadb.yaml +20 -0
  161. package/engines/specs/openreview.yaml +37 -0
  162. package/engines/specs/openstd.yaml +21 -0
  163. package/engines/specs/people_daily.yaml +22 -0
  164. package/engines/specs/realtime_index.yaml +34 -0
  165. package/engines/specs/ror.yaml +20 -0
  166. package/engines/specs/satnogs.yaml +20 -0
  167. package/engines/specs/sec_edgar.yaml +46 -0
  168. package/engines/specs/shfe.yaml +39 -0
  169. package/engines/specs/skillsmp.yaml +50 -0
  170. package/engines/specs/sogou_weixin_browser.yaml +30 -0
  171. package/engines/specs/soilgrids.yaml +25 -0
  172. package/engines/specs/sspai.yaml +36 -0
  173. package/engines/specs/stackexchange.yaml +46 -0
  174. package/engines/specs/std_samr.yaml +21 -0
  175. package/engines/specs/tass.yaml +43 -0
  176. package/engines/specs/tavily_free.yaml +56 -0
  177. package/engines/specs/tle_mirror.yaml +21 -0
  178. package/engines/specs/train.yaml +37 -0
  179. package/engines/specs/tvmaze.yaml +20 -0
  180. package/engines/specs/twitter_syndication.yaml +31 -0
  181. package/engines/specs/un_comtrade.yaml +23 -0
  182. package/engines/specs/unpaywall.yaml +54 -0
  183. package/engines/specs/vnpress.yaml +43 -0
  184. package/engines/specs/weather.yaml +32 -0
  185. package/engines/specs/who_don.yaml +21 -0
  186. package/engines/specs/who_gho.yaml +20 -0
  187. package/engines/specs/wikimedia_commons.yaml +34 -0
  188. package/engines/specs/wikisource.yaml +22 -0
  189. package/engines/specs/worms.yaml +19 -0
  190. package/engines/specs/x_trending.yaml +34 -0
  191. package/engines/specs/yna.yaml +43 -0
  192. package/engines/specs/ynet.yaml +43 -0
  193. package/engines/specs/yuanbao.yaml +93 -0
  194. package/engines/specs/zbmath.yaml +40 -0
  195. package/engines/specs/zdic.yaml +22 -0
  196. package/engines/specs/zenodo.yaml +27 -0
  197. package/engines/specs/zhihu_hot_app.yaml +35 -0
  198. package/mcp/clients.yaml +106 -0
  199. package/package.json +55 -12
  200. package/packages/dsh-plugin/README.md +152 -0
  201. package/packages/dsh-plugin/cordis.patch.yml +48 -0
  202. package/packages/dsh-plugin/dsh/client.js +1533 -0
  203. package/packages/dsh-plugin/dsh/diagnostics.js +54 -0
  204. package/packages/dsh-plugin/dsh/index.js +527 -0
  205. package/packages/dsh-plugin/dsh/native-tools.mjs +749 -0
  206. package/packages/dsh-plugin/dsh/runner.js +666 -0
  207. package/packages/dsh-plugin/dsh/wide-research.js +878 -0
  208. package/packages/dsh-plugin/package.json +38 -0
  209. package/packages/dsh-plugin/scripts/sync-local.sh +70 -0
  210. package/packages/dsh-plugin/test/client.test.js +406 -0
  211. package/packages/dsh-plugin/test/config.test.js +30 -0
  212. package/packages/dsh-plugin/test/diagnostics.test.js +28 -0
  213. package/packages/dsh-plugin/test/index.test.js +1382 -0
  214. package/references/query-templates.md +96 -0
  215. package/references/query-templates.yaml +118 -0
  216. package/scripts/ab_eval.py +219 -0
  217. package/scripts/ab_eval_p0p1.py +266 -0
  218. package/scripts/adaptive.py +294 -70
  219. package/scripts/answer.py +154 -0
  220. package/scripts/archive_run.py +591 -0
  221. package/scripts/argo_engine_registry.py +172 -0
  222. package/scripts/argo_paths.py +728 -0
  223. package/scripts/article.py +136 -0
  224. package/scripts/article_meta.py +131 -0
  225. package/scripts/arxiv_source.py +201 -0
  226. package/scripts/badcase_ledger.py +252 -0
  227. package/scripts/batch_probe.py +241 -0
  228. package/scripts/benchmark.py +19 -0
  229. package/scripts/bounded_run.py +144 -0
  230. package/scripts/browser_auth.py +323 -0
  231. package/scripts/budget.py +247 -0
  232. package/scripts/budget_cli.py +93 -0
  233. package/scripts/build_release_assets.sh +65 -0
  234. package/scripts/burstiness_detector.py +147 -0
  235. package/scripts/cache.py +1066 -67
  236. package/scripts/cache_guard.py +271 -0
  237. package/scripts/cache_key_vdom.py +56 -0
  238. package/scripts/cache_similarity.py +170 -0
  239. package/scripts/caliber_isolation.py +195 -0
  240. package/scripts/calibrate_lowquality.py +210 -0
  241. package/scripts/candidate_envelope.py +366 -0
  242. package/scripts/chrome_cdp.py +871 -0
  243. package/scripts/ci_drift_gate.py +90 -0
  244. package/scripts/circuit_breaker.py +389 -0
  245. package/scripts/citations.py +334 -0
  246. package/scripts/cite_cli.py +59 -0
  247. package/scripts/cjk_tokens.py +95 -0
  248. package/scripts/clarify.py +47 -24
  249. package/scripts/cli_io.py +240 -0
  250. package/scripts/config.py +683 -45
  251. package/scripts/config_cache.py +402 -0
  252. package/scripts/conn_pool.py +220 -0
  253. package/scripts/content_boundary.py +46 -0
  254. package/scripts/content_security.py +685 -0
  255. package/scripts/content_signals.py +751 -0
  256. package/scripts/crawl.py +74 -35
  257. package/scripts/cross_lingual_trace.py +293 -0
  258. package/scripts/daemon.py +866 -0
  259. package/scripts/digup_bridge.py +214 -0
  260. package/scripts/dispatch_result.py +98 -0
  261. package/scripts/engine_admission.py +366 -0
  262. package/scripts/engine_dispatch.py +982 -0
  263. package/scripts/engine_env.py +539 -0
  264. package/scripts/engine_failure.py +411 -0
  265. package/scripts/engine_families.py +738 -0
  266. package/scripts/engine_policy.py +218 -0
  267. package/scripts/engine_requires.py +190 -0
  268. package/scripts/engine_status.py +322 -0
  269. package/scripts/engine_validate.py +638 -0
  270. package/scripts/engines.py +799 -294
  271. package/scripts/engines_base.py +1521 -0
  272. package/scripts/engines_builders.py +310 -0
  273. package/scripts/engines_builders_batch10.py +204 -0
  274. package/scripts/engines_builders_batch11.py +174 -0
  275. package/scripts/engines_builders_batch12.py +103 -0
  276. package/scripts/engines_builders_batch13.py +340 -0
  277. package/scripts/engines_builders_batch14.py +656 -0
  278. package/scripts/engines_builders_batch15.py +249 -0
  279. package/scripts/engines_builders_batch9.py +1468 -0
  280. package/scripts/engines_builders_cn.py +2283 -0
  281. package/scripts/engines_builders_data.py +2923 -0
  282. package/scripts/engines_builders_data_macro.py +775 -0
  283. package/scripts/engines_builders_feeds.py +255 -0
  284. package/scripts/engines_builders_intl.py +1239 -0
  285. package/scripts/engines_builders_keyless.py +111 -0
  286. package/scripts/engines_builders_search.py +440 -0
  287. package/scripts/engines_builders_tech.py +1359 -0
  288. package/scripts/evidence.py +620 -166
  289. package/scripts/evidence_loop.py +624 -0
  290. package/scripts/evidence_tier.py +298 -0
  291. package/scripts/except_sets.py +25 -0
  292. package/scripts/extract.py +55 -16
  293. package/scripts/fact_align.py +207 -0
  294. package/scripts/fact_crosscheck.py +230 -0
  295. package/scripts/fetch.py +25 -12
  296. package/scripts/fetch_browser.py +87 -0
  297. package/scripts/fetch_jsrun.py +122 -0
  298. package/scripts/fetch_quality.py +225 -0
  299. package/scripts/fetch_render_tinyfish.py +117 -0
  300. package/scripts/fetch_v3.py +1804 -0
  301. package/scripts/focus_extract.py +350 -0
  302. package/scripts/fulltext_store.py +169 -0
  303. package/scripts/fxtwitter_api.py +325 -0
  304. package/scripts/gen_engine_catalog.py +364 -0
  305. package/scripts/gen_native_tools.py +91 -0
  306. package/scripts/gen_routing_snapshot.py +195 -0
  307. package/scripts/health_check.py +140 -402
  308. package/scripts/health_probe.py +23 -8
  309. package/scripts/hot_state.py +134 -0
  310. package/scripts/http_client.py +1053 -0
  311. package/scripts/image_ops.py +430 -0
  312. package/scripts/image_vision/vision_probe.swift +126 -0
  313. package/scripts/install.ps1 +166 -0
  314. package/scripts/install.sh +221 -0
  315. package/scripts/job.py +1186 -0
  316. package/scripts/jump_resolver.py +235 -0
  317. package/scripts/lang_capability.py +150 -0
  318. package/scripts/lang_detect.py +289 -0
  319. package/scripts/lang_matrix_probe.py +329 -0
  320. package/scripts/lang_pref.py +311 -0
  321. package/scripts/link_source.py +340 -0
  322. package/scripts/local_image.py +970 -0
  323. package/scripts/local_seek.py +402 -0
  324. package/scripts/macro_countries.py +97 -0
  325. package/scripts/matrix_search_eval.py +1187 -0
  326. package/scripts/mcp_compact.py +234 -0
  327. package/scripts/mcp_diag.py +8 -3
  328. package/scripts/mcp_handlers.py +492 -0
  329. package/scripts/mcp_handlers_surface.py +157 -0
  330. package/scripts/mcp_launch.sh +124 -0
  331. package/scripts/mcp_local.py +241 -0
  332. package/scripts/mcp_server.py +125 -419
  333. package/scripts/mcp_setup.py +431 -0
  334. package/scripts/mcp_tools.py +331 -0
  335. package/scripts/mcp_transport.py +191 -0
  336. package/scripts/mcp_warm.py +127 -0
  337. package/scripts/min_version_scan.py +335 -0
  338. package/scripts/net_proxy.py +258 -0
  339. package/scripts/network_aware.py +152 -0
  340. package/scripts/output_transparency.py +200 -0
  341. package/scripts/paid_policy.py +98 -0
  342. package/scripts/paper.py +274 -0
  343. package/scripts/pdf_extract.py +518 -0
  344. package/scripts/phrase_filter.py +66 -0
  345. package/scripts/plan.py +422 -0
  346. package/scripts/postprocess_signals.py +150 -0
  347. package/scripts/pre-commit +48 -0
  348. package/scripts/query_enhance.py +157 -0
  349. package/scripts/query_operators.py +196 -0
  350. package/scripts/query_rewriter.py +116 -7
  351. package/scripts/query_signals.py +300 -0
  352. package/scripts/query_templates.py +167 -0
  353. package/scripts/query_understanding.py +411 -0
  354. package/scripts/query_variants.py +298 -0
  355. package/scripts/quota.py +633 -76
  356. package/scripts/rank_signals.py +775 -0
  357. package/scripts/ranking_eval.py +319 -0
  358. package/scripts/readability_extract.py +433 -0
  359. package/scripts/recompute.py +415 -0
  360. package/scripts/recovery.py +616 -0
  361. package/scripts/recovery_l0.py +160 -0
  362. package/scripts/recovery_runner.py +150 -0
  363. package/scripts/redskill/redskill_engine.py +332 -0
  364. package/scripts/regression_p0p1.py +318 -0
  365. package/scripts/replay_eval.py +658 -0
  366. package/scripts/rerank_tfidf.py +225 -0
  367. package/scripts/research.py +607 -403
  368. package/scripts/research_cli.py +361 -0
  369. package/scripts/research_dossier.py +492 -0
  370. package/scripts/research_expand.py +169 -0
  371. package/scripts/research_gates.py +272 -0
  372. package/scripts/research_report.py +209 -0
  373. package/scripts/research_strategy.py +37 -0
  374. package/scripts/research_work_packages.py +195 -0
  375. package/scripts/result_lang.py +311 -0
  376. package/scripts/retry_policy.py +76 -0
  377. package/scripts/robots_guard.py +259 -0
  378. package/scripts/route.py +921 -254
  379. package/scripts/route_bangs.py +40 -0
  380. package/scripts/route_cache.py +243 -0
  381. package/scripts/route_combo.py +917 -0
  382. package/scripts/route_domains.py +341 -0
  383. package/scripts/route_lang.py +605 -0
  384. package/scripts/route_log.py +63 -0
  385. package/scripts/route_policy.py +250 -0
  386. package/scripts/rrf_classic.py +66 -0
  387. package/scripts/screenshot.py +73 -0
  388. package/scripts/search.py +886 -406
  389. package/scripts/search_attribution.py +185 -0
  390. package/scripts/search_benchmark.py +407 -0
  391. package/scripts/search_cli.py +640 -0
  392. package/scripts/search_entry.py +395 -0
  393. package/scripts/search_output.py +690 -0
  394. package/scripts/search_pipeline.py +926 -0
  395. package/scripts/search_rank.py +991 -0
  396. package/scripts/search_types.py +129 -16
  397. package/scripts/seek_locator.py +68 -0
  398. package/scripts/semantic_evidence.py +391 -0
  399. package/scripts/serp_guard.py +336 -0
  400. package/scripts/serp_kill_log.py +74 -0
  401. package/scripts/single_flight.py +120 -0
  402. package/scripts/social_engines/__init__.py +10 -0
  403. package/scripts/social_engines/bilibili_engine.py +131 -0
  404. package/scripts/social_engines/hackernews_engine.py +113 -0
  405. package/scripts/social_engines/reddit_engine.py +172 -0
  406. package/scripts/social_engines/twitter_engine.py +397 -0
  407. package/scripts/social_engines/v2ex_engine.py +101 -0
  408. package/scripts/social_engines/weibo_engine.py +128 -0
  409. package/scripts/social_engines/xiaohongshu_engine.py +137 -0
  410. package/scripts/social_engines/zhihu_engine.py +139 -0
  411. package/scripts/social_research.py +201 -0
  412. package/scripts/sogou_weixin_browser.py +318 -0
  413. package/scripts/source_ledger.py +249 -0
  414. package/scripts/stage_timing.py +58 -0
  415. package/scripts/stats_cli.py +107 -0
  416. package/scripts/straggler_policy.py +60 -0
  417. package/scripts/stylometry_detector.py +231 -0
  418. package/scripts/sync_backends.py +353 -0
  419. package/scripts/sync_installs.py +29 -0
  420. package/scripts/template_cli.py +127 -0
  421. package/scripts/text_lexicon.py +72 -0
  422. package/scripts/tfidf_router.py +109 -37
  423. package/scripts/time_utils.py +233 -0
  424. package/scripts/topic_research_profiles.py +643 -0
  425. package/scripts/train.py +737 -0
  426. package/scripts/tweet.py +596 -0
  427. package/scripts/url_canon.py +217 -0
  428. package/scripts/url_optimize.py +56 -0
  429. package/scripts/url_safety.py +236 -0
  430. package/scripts/usage_log.py +116 -0
  431. package/scripts/usage_log_clean.py +113 -0
  432. package/scripts/v2ex_nodes.py +311 -0
  433. package/scripts/variant_recall.py +188 -0
  434. package/scripts/watch.py +205 -0
  435. package/scripts/wechat_article.py +258 -0
  436. package/scripts/wide_research.py +447 -0
  437. package/scripts/wx.py +349 -0
  438. package/scripts/x_article_fetch.py +141 -0
  439. package/scripts/x_search.py +234 -0
  440. package/scripts/x_trending.py +189 -0
  441. package/scripts/yaml_load.py +67 -0
  442. package/scripts/zhihu_quota.py +139 -0
  443. package/sub-skills/ego-search/SKILL.md +253 -0
  444. package/sub-skills/ego-search/scripts/ego_search.py +800 -0
  445. package/sub-skills/ego-search/scripts/merge.py +226 -0
  446. package/sub-skills/ego-search/scripts/quality.py +64 -0
  447. package/sub-skills/ego-search/scripts/runtime.py +172 -0
  448. package/sub-skills/ego-search/scripts/safety.py +109 -0
  449. package/sub-skills/ego-search/scripts/serp_spec.py +109 -0
  450. package/sub-skills/ego-search/scripts/webbridge_adapter.py +374 -0
  451. package/sub-skills/js-run/SKILL.md +67 -0
  452. package/sub-skills/js-run/scripts/jsrun.py +112 -0
  453. package/sub-skills/js-run/scripts/shim.js +188 -0
  454. package/sub-skills/local-search/SKILL.md +50 -53
  455. package/sub-skills/local-search/bm25.py +186 -0
  456. package/sub-skills/local-search/cli_runner.py +331 -0
  457. package/sub-skills/local-search/config.yaml +152 -55
  458. package/sub-skills/local-search/engine_registry.py +91 -26
  459. package/sub-skills/local-search/{health_check.py → local_health_check.py} +140 -10
  460. package/sub-skills/local-search/local_search_adapter.py +13 -2
  461. package/sub-skills/local-search/parse_maps.yaml +40 -42
  462. package/sub-skills/local-search/parsers.py +328 -0
  463. package/sub-skills/local-search/search_v3.py +716 -242
  464. package/sub-skills/local-search/smart_router.py +47 -7
  465. package/sub-skills/local-seek/SKILL.md +110 -0
  466. package/sub-skills/local-seek/config/domains.yaml +20 -0
  467. package/sub-skills/local-seek/scripts/eval_rank.py +216 -0
  468. package/sub-skills/local-seek/scripts/eval_seek.py +224 -0
  469. package/sub-skills/local-seek/scripts/seek.py +1465 -0
  470. package/sub-skills/local-seek/scripts/seek_frecency.py +126 -0
  471. package/sub-skills/local-seek/scripts/seek_fts.py +430 -0
  472. package/sub-skills/local-seek/scripts/seek_rank.py +197 -0
@@ -0,0 +1,240 @@
1
+ #!/usr/bin/env python3
2
+ """cli_io.py — CLI 标准输入/输出判据的唯一来源。
3
+
4
+ ## 为什么需要它
5
+
6
+ 判断「stdin 有没有数据」最直觉的写法是 `not sys.stdin.isatty()`,但它是**错的**:
7
+ `/dev/null`、已关闭的 fd、以及**任何非交互环境下的空 stdin** 都不是 tty,
8
+ 于是这个判据会把「没有数据」判成「有数据」。
9
+
10
+ 后果在 argo 的主战场(脚本 / CI / cron / agent 调用)上最严重:
11
+ `argo evidence "query"` 会走进「读管道」分支、拿到空串,然后崩在
12
+ `json.load(sys.stdin)` 上(2026-09-15 实测复现,退出码 1 + Traceback)。
13
+
14
+ 真正的判据是 fd 的**类型**:
15
+ - S_ISFIFO → `... | argo ...`(管道)
16
+ - S_ISREG → `argo ... < data.json`(文件重定向)
17
+ - S_ISCHR → 终端或 /dev/null(无数据)
18
+
19
+ 但「fd 类型对」只解决「要不要读」,不解决「读到什么时候」。它们合起来才是
20
+ 完整的判据——**只判类型会让空管道永久阻塞**:
21
+
22
+ FIFO 的 `read()` 要等到写端关闭才返回。而 agent / CI / cron 起的子进程,
23
+ stdin 正是一个「空、且在整个子进程生命周期内不关闭」的管道;终端里
24
+ `argo evidence "q"` 也是同一个形态。实测(2026-09-27):
25
+ `bin/argo evidence "query" --json` 在管道 stdin 下 90 秒不返回,
26
+ `< /dev/null` 才 1 秒退出。后果是所有调用方(尤其 agent)只能等自己的超时。
27
+
28
+ 所以管道分支**必须带截止时间**:先等「第一个字节到达」,再带总上限读到 EOF。
29
+ 两个上限都写在这里,是因为「判据」和「期限」是同一件事的两半,分散到调用方
30
+ 就会各自漂移(`bin/argo evidence` 与 `batch_probe` 都会各写一遍)。
31
+
32
+ ## stdout 序列化同理
33
+
34
+ `--json` 输出是给 Agent / 脚本读的,缩进只增加传输体积与 token,不增加任何
35
+ 信息。MCP 侧早已如此(`mcp_handlers._dumps` 默认 `separators=(",", ":")`),
36
+ 但 CLI 侧此前在 45 处各写一遍 `json.dumps(..., indent=2)`——同一份载荷两套
37
+ 计算方式,实测多占 22% 体积。这里给 stdout 一个唯一入口。
38
+
39
+ ## stdout/stderr 的编码也归这里
40
+
41
+ 给子进程注入 `PYTHONUTF8=1` 是本仓既有做法(mcp_server / search.py 的
42
+ local-seek / recompute 都这么做),但**自家进程**从没做过同一件事。实测
43
+ `PYTHONIOENCODING=ascii python3 scripts/search.py "贵州茅台"` 直接
44
+ UnicodeEncodeError 崩掉;Windows 老终端(cp1252/cp936)走的是同一条路。
45
+ 输出契约既然定的是 UTF-8 JSON,进程自己的 stdout 就必须跟上,见
46
+ `ensure_utf8_stdio()`。
47
+ """
48
+
49
+ from __future__ import annotations
50
+
51
+ import json
52
+ import os
53
+ import stat
54
+ import sys
55
+ import time
56
+ from typing import Any
57
+
58
+ __all__ = ["stdin_is_piped", "read_stdin_if_piped", "dumps", "dumps_pretty",
59
+ "ensure_utf8_stdio"]
60
+
61
+ # stdout 的紧凑分隔符(无冗余空格):与 mcp_handlers._dumps 的默认计算方式一致。
62
+ _COMPACT = (",", ":")
63
+
64
+ # 管道 stdin 的两个截止时间(秒)。见模块头「必须带截止时间」。
65
+ #
66
+ # 第一个字节:实测 `echo '{...}' | argo ...` 的首字节在毫秒级到达,0.25s 已是
67
+ # 两个数量级的余量;再长只是让「空管道」这一类多等,没有收益。
68
+ _FIRST_BYTE_WAIT_S = 0.25
69
+ # 总上限:正常载荷(evidence 的搜索结果 JSON、preflight 的 URL 清单)在毫秒级
70
+ # 读完,3s 只用来兜「写端写了半截又不关闭」的半开管道——超时返回**已读到的
71
+ # 部分**而不是空串,让 json.load 在调用方那里响亮地失败,而不是被静默当成
72
+ # 「没有 stdin 数据」而改走另一条分支(那会变成悄悄换答案)。
73
+ _TOTAL_WAIT_S = 3.0
74
+ # 单次系统调用的读取块大小。
75
+ _CHUNK = 65536
76
+ # 无数据时的轮询间隔:期限只有 0.25s/3s 两级,10ms 足够精确而几乎不烧 CPU。
77
+ _POLL_INTERVAL_S = 0.01
78
+
79
+
80
+ def dumps(obj: Any) -> str:
81
+ """CLI stdout 的 JSON 序列化唯一来源(默认紧凑)。
82
+
83
+ 用途边界:**stdout**。写进磁盘的归档文件(`archive_run` 的 public.json /
84
+ coverage.json 等)是给人翻的,仍用 `dumps_pretty`——「机器读 stdout、
85
+ 人读文件」这条线让两种格式各归其位,而不是按文件拍脑袋。
86
+ """
87
+ return json.dumps(obj, ensure_ascii=False, separators=_COMPACT)
88
+
89
+
90
+ def dumps_pretty(obj: Any) -> str:
91
+ """人读场景(归档文件、诊断输出)的缩进序列化。"""
92
+ return json.dumps(obj, ensure_ascii=False, indent=2)
93
+
94
+
95
+ def ensure_utf8_stdio() -> None:
96
+ """把本进程的 stdout/stderr 固定成「机器可读、且不会炸」的编码。
97
+
98
+ why:子进程侧早就注入了 `PYTHONUTF8=1`,自家进程却从来没人管。实测
99
+ `PYTHONIOENCODING=ascii python3 scripts/search.py "贵州茅台"` 直接
100
+ UnicodeEncodeError + Traceback(退出码 1);Windows 老控制台
101
+ (cp1252/cp936)是同一个故障形态。而 stdout 的契约是 UTF-8 JSON
102
+ (见 `dumps`),进程自己的流必须跟上,否则「能力都在、结果出不来」。
103
+
104
+ **分两档,因为管道与终端的正确行为不同**:
105
+ - 非终端(管道 / 文件 / agent 消费):强制 UTF-8。机器读的字节必须是
106
+ UTF-8,否则下游 decode 出的就是乱码,而这类调用正是 argo 的主战场。
107
+ - 终端:保留平台编码,只把 errors 放宽成 `backslashreplace`。中文
108
+ Windows 的 cp936 终端本来就能正确显示中文,硬换成 UTF-8 反而变乱码;
109
+ 而写不出的字符以转义形式出现,既不崩、也不像 `replace` 那样把字符
110
+ 静默换成 `?`(那等于悄悄损坏数据,比崩更难查)。
111
+
112
+ 只碰 encoding / errors,不动缓冲与换行;任何不支持 reconfigure 的流
113
+ (测试替身、已被包过的流)静默跳过——这是纯加固,失败不该影响主流程。
114
+ """
115
+ for stream in (sys.stdout, sys.stderr):
116
+ try:
117
+ if stream.isatty():
118
+ stream.reconfigure(errors="backslashreplace")
119
+ else:
120
+ stream.reconfigure(encoding="utf-8",
121
+ errors="backslashreplace")
122
+ except (AttributeError, ValueError, OSError):
123
+ continue
124
+
125
+
126
+ def stdout_is_tty() -> bool:
127
+ """stdout 是否是终端(人类消费)。
128
+
129
+ Agent 消费场景(管道/重定向/capture_output)下 stdout 不是 tty,
130
+ 此时可自动启用 --fields agent 瘦身。判据是 os.isatty(fileno())——
131
+ 直接问内核「是不是终端」;与 stdin_is_piped 同构的是 fail-safe 结构:
132
+ fd 取不到时这里当终端(不瘦身),那边当没数据。
133
+ """
134
+ try:
135
+ return os.isatty(sys.stdout.fileno())
136
+ except (OSError, ValueError, AttributeError):
137
+ return True # fail-safe:取不到就当终端,不瘦身
138
+
139
+
140
+ def stdin_is_piped() -> bool:
141
+ """stdin 是否接了管道或文件重定向(而非终端 / /dev/null / 未打开)。"""
142
+ mode = _stdin_mode()
143
+ return mode is not None and (stat.S_ISFIFO(mode) or stat.S_ISREG(mode))
144
+
145
+
146
+ def _stdin_mode() -> int | None:
147
+ """stdin 的 st_mode;取不到(已关闭 / 非法 fd)返回 None。
148
+
149
+ 「取得到吗」与「是什么类型」拆开,是因为前者要 fail-safe 成「没有数据」,
150
+ 后者才谈得上判据;两件事混在一个函数里时,新增调用方总有一半会忘。
151
+ """
152
+ try:
153
+ return os.fstat(sys.stdin.fileno()).st_mode
154
+ except (OSError, ValueError, AttributeError):
155
+ return None
156
+
157
+
158
+ def read_stdin_if_piped() -> str:
159
+ """读走 stdin 的全部内容;未接管道/重定向时返回空串。
160
+
161
+ 一次性读完而不是判空后再读——fd 只能顺序读一遍,窥探会吃掉内容。
162
+ (带截止时间的管道分支同理:**边读边攒**,而不是先窥探再读第二次。)
163
+ """
164
+ mode = _stdin_mode()
165
+ if mode is None:
166
+ return ""
167
+ if stat.S_ISREG(mode):
168
+ # 文件重定向:read() 到 EOF 立即返回,本来就不会挂,无需期限
169
+ return _read_all_text()
170
+ if not stat.S_ISFIFO(mode):
171
+ return "" # 终端 / /dev/null / 其它字符设备:没有数据
172
+ return _read_pipe_with_deadline()
173
+
174
+
175
+ def _read_all_text() -> str:
176
+ try:
177
+ return sys.stdin.read()
178
+ except (OSError, ValueError, UnicodeDecodeError):
179
+ return ""
180
+
181
+
182
+ def _read_pipe_with_deadline() -> str:
183
+ """读管道 stdin,带「首字节」与「总时长」两个截止时间(见模块头)。
184
+
185
+ 做法是把 fd 临时切成非阻塞、用 `os.read` 轮询,而不是「另起线程去阻塞读」:
186
+ **daemon 线程解不开这个锁**——它阻塞在 BufferedReader 的 C 读上时,解释器
187
+ 退出会撞上 `_enter_buffered_busy: could not acquire lock for
188
+ <_io.BufferedReader name='<stdin>'> at interpreter shutdown`(本机实测直接
189
+ SIGABRT,rc=-6,比原来的挂起更难查)。非阻塞轮询不留后台线程,就没有这个
190
+ 收尾问题。
191
+
192
+ 前提:本函数是 stdin 的第一个读者。走 `os.read(fd)` 会绕过文本层的缓冲,
193
+ 若此前已有代码读过 stdin,缓冲区里那一截就取不到了。现有调用方
194
+ (`bin/argo` 的 evidence 分支、`batch_probe` 的 stdin URL 清单)都在进程
195
+ 最开头调用它。
196
+ """
197
+ try:
198
+ fd = sys.stdin.fileno()
199
+ except (OSError, ValueError, AttributeError):
200
+ return ""
201
+ try:
202
+ was_blocking = os.get_blocking(fd)
203
+ os.set_blocking(fd, False)
204
+ except (OSError, ValueError, AttributeError):
205
+ # 设不了非阻塞(少数平台 / 管道类型):退回改动前的语义(可能阻塞),
206
+ # 但绝不猜数据、也不造假数据
207
+ return _read_all_text()
208
+
209
+ deadline_first = time.monotonic() + _FIRST_BYTE_WAIT_S
210
+ deadline_total = deadline_first + _TOTAL_WAIT_S
211
+ chunks: list[bytes] = []
212
+ try:
213
+ while True:
214
+ try:
215
+ block = os.read(fd, _CHUNK)
216
+ except BlockingIOError:
217
+ block = None
218
+ except (OSError, ValueError):
219
+ break # fd 坏了/关了:手上有多少算多少
220
+ if block is not None:
221
+ if not block:
222
+ break # EOF:写端关闭,正常收尾
223
+ chunks.append(block)
224
+ continue
225
+ # 这一刻没有数据可读
226
+ if not chunks:
227
+ if time.monotonic() >= deadline_first:
228
+ return "" # 首字节没来:按「没有 stdin 数据」处理
229
+ elif time.monotonic() >= deadline_total:
230
+ break # 半开管道:带已读到的部分返回,让调用方响亮地失败
231
+ time.sleep(_POLL_INTERVAL_S)
232
+ finally:
233
+ try:
234
+ if was_blocking:
235
+ os.set_blocking(fd, True)
236
+ except (OSError, ValueError, AttributeError):
237
+ pass
238
+ payload = b"".join(chunks)
239
+ encoding = getattr(sys.stdin, "encoding", None) or "utf-8"
240
+ return payload.decode(encoding, errors="replace")