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,124 @@
1
+ #!/bin/sh
2
+ # argo MCP 启动器 —— 保证任何客户端、任何启动上下文都拿到引擎密钥。
3
+ #
4
+ # 背景(2026-08-29):各客户端 server 的密钥来自「宿主 app 启动时的环境」,
5
+ # 上下文不同密钥就不同(有的 8 个全有、有的全无),且 launchctl setenv
6
+ # 重启即失效。此启动器把密钥收敛到唯一真源文件,启动时注入:
7
+ # 1. ~/.config/argo/env(chmod 600,勿入库勿分享)——唯一真源
8
+ # 2. 系统域兜底:macOS 走 launchctl getenv,其它平台无此层、直接跳过
9
+ # 提前恢复配额/换 key:改 env 文件后重启对应客户端即可,零配置分散维护。
10
+ #
11
+ # 跨平台(2026-09-15):原版是 `#!/bin/zsh` + `dscl` + `${(P)k}` + `${0:A:h}`
12
+ # + 写死 `/opt/homebrew/bin/python3`,只在装了 Homebrew 的 macOS 上成立。
13
+ # 而 `mcp_setup.py` 把本脚本路径写成 MCP 客户端的 command(10 处引用),
14
+ # 于是 Linux / Windows-WSL 用户接 MCP 的第一步就是
15
+ # `bad interpreter: /bin/zsh`——不是配置错,是脚本根本起不来。
16
+ # 改用 POSIX sh + 解释器探测后,macOS 本机行为不变(同一个 env 文件、同一层
17
+ # launchctl 兜底、同一批透传名单),其余平台从「拉不起来」变成「能起」。
18
+
19
+ # 某些宿主(如 dsh web)以净化环境 spawn MCP,HOME 可能缺失——先兜底
20
+ if [ -z "$HOME" ]; then
21
+ if command -v dscl >/dev/null 2>&1; then # macOS
22
+ HOME="$(dscl . -read "/Users/$(id -un)" NFSHomeDirectory 2>/dev/null | awk '{print $2}')"
23
+ elif command -v getent >/dev/null 2>&1; then # Linux
24
+ HOME="$(getent passwd "$(id -un)" | cut -d: -f6)"
25
+ fi
26
+ [ -n "$HOME" ] && export HOME
27
+ fi
28
+
29
+ ENV_FILE="${HOME}/.config/argo/env"
30
+ # set -a 仅覆盖 env 文件加载这一行,内部变量不导出
31
+ set -a
32
+ [ -f "$ENV_FILE" ] && . "$ENV_FILE"
33
+ set +a
34
+
35
+ # 透传名单单一真源:launchctl print 批量路径与 getenv 回退路径共用这一份
36
+ # (与 engine_env.KNOWN_ENV_ALIASES 展开 + 代理变量对齐,
37
+ # tests/test_launch_passthrough_alignment.py 锁两表一致,改名单两处同步)
38
+ _ARGO_PASSTHROUGH_KEYS="ALL_PROXY ANYSEARCH_API_KEY ARGO_ANYSEARCH_API_KEY ARGO_BOCHA_API_KEY\
39
+ ARGO_BRAVE_API_KEY ARGO_BYTED_API_KEY ARGO_EASTMONEY_APIKEY\
40
+ ARGO_EXA_API_KEY ARGO_FELO_API_KEY ARGO_FIRECRAWL_API_KEY\
41
+ ARGO_GITHUB_TOKEN ARGO_JEV_API_KEY ARGO_METASO_API_KEY\
42
+ ARGO_OCTEN_API_KEY ARGO_PROXY ARGO_QWEATHER_KEY\
43
+ ARGO_TAVILY_API_KEY TYPESAFE_API_KEY\
44
+ ARGO_WEB_SEARCH_API_KEY ARGO_WEREAD_API_KEY\
45
+ ARGO_WOLFRAM_APPID ARGO_YUANBAO_API_KEY ARGO_ZHIHU_ACCESS_SECRET\
46
+ BOCHA_API_KEY BRAVE_API_KEY EASTMONEY_APIKEY EXA_API_KEY\
47
+ FELO_API_KEY FIRECRAWL_API_KEY GITHUB_TOKEN HTTPS_PROXY\
48
+ HTTP_PROXY METASO_API_KEY NO_PROXY OCTEN_API_KEY\
49
+ QWEATHER_KEY TAVILY_API_KEY TENCENTCLOUD_WSA_APIKEY\
50
+ WEB_SEARCH_API_KEY WEREAD_API_KEY WOLFRAM_APPID\
51
+ YUANBAO_API_KEY ZHIHU_ACCESS_SECRET"
52
+
53
+ # launchctl 兜底(macOS):旧实现逐键 spawn `launchctl getenv`——实测每次
54
+ # 4-20ms,名单里 ~30 个未设键让每个宿主会话白付百毫秒级纯开销。改为一次
55
+ # `launchctl print gui/$UID` 读整个域环境(实测热态 ~30ms):environment 段
56
+ # 的 "KEY => value" 行与 getenv 同源(setenv 探针实测,含空格值一致)。
57
+ # print 不可用(非 macOS / 特殊上下文)时回退旧逐键 getenv,行为同 08-29 版。
58
+ _lc_vals=""
59
+ if command -v launchctl >/dev/null 2>&1; then
60
+ _lc_vals="$(launchctl print "gui/$(id -u)" 2>/dev/null | LC_ALL=C awk -v keys="$_ARGO_PASSTHROUGH_KEYS" '
61
+ BEGIN { n = split(keys, a, " "); for (i = 1; i <= n; i++) want[a[i]] = 1 }
62
+ /^[[:space:]]*environment[[:space:]]*=[[:space:]]*\{/ { e = 1; next }
63
+ e && /^[[:space:]]*\}/ { exit }
64
+ e && / => / {
65
+ i = index($0, " => ")
66
+ k = substr($0, 1, i - 1)
67
+ sub(/^[[:space:]]+/, "", k)
68
+ if (k in want) print k "\t" substr($0, i + 4)
69
+ }')"
70
+ fi
71
+ if [ -n "$_lc_vals" ]; then
72
+ # 名单内已设的键逐条导出;env 文件/父环境已给的键不覆盖(语义同旧循环)
73
+ while IFS=" " read -r k v; do
74
+ eval "cur=\${$k}"
75
+ if [ -z "$cur" ] && [ -n "$v" ]; then
76
+ export "$k=$v"
77
+ fi
78
+ done <<_ARGO_LC_EOF
79
+ $_lc_vals
80
+ _ARGO_LC_EOF
81
+ else
82
+ for k in $_ARGO_PASSTHROUGH_KEYS; do
83
+ if command -v launchctl >/dev/null 2>&1; then
84
+ # POSIX 间接展开(zsh 的 ${(P)k} 在 sh 下不存在,eval 是等价写法)
85
+ eval "cur=\${$k}"
86
+ if [ -z "$cur" ]; then
87
+ v="$(launchctl getenv "$k" 2>/dev/null)"
88
+ [ -n "$v" ] && export "$k=$v"
89
+ fi
90
+ fi
91
+ done
92
+ fi
93
+
94
+ # 脚本所在目录的绝对路径(POSIX 写法,替代 zsh 的 ${0:A:h})
95
+ SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
96
+
97
+ # 解释器:ARGO_PYTHON 显式指定优先(客户端配置可覆盖);否则自动探测,取第一个
98
+ # 同时满足「版本 ≥3.9」且「能导入 PyYAML」的——版本下限与 bin/argo 的 MIN_PYTHON
99
+ # 一致(改一处就要改另一处)。为什么不是更高的版本:早期这里写 3.10,理由是
100
+ # 「脚本用了 `X | None`」,但实测全仓 0 处该写法。而配置/引擎声明都靠 PyYAML
101
+ # 解析,版本够却没装 yaml 的解释器选了也只能用残缺的内置默认配置——所以这两点
102
+ # 必须**同时**判,少判一个就会选到跑不动的解释器(bin/argo 曾因此把 3.9 选中
103
+ # 并写进缓存)。报错最终都落在客户端日志里,用户看到的是「MCP server 未就绪」,
104
+ # 所以探测阶段就把不可用的解释器跳过。
105
+ # 全都不达标时回落 python3:宁可让错误信息可读,也不抛「找不到解释器」。
106
+ # ARGO_PYTHON 显式指定同样要过「版本 + PyYAML」双判据(2026-10-02 补齐):
107
+ # 此前只查存在性,把无 yaml 的解释器写进 env 文件会带着残缺配置起服务,
108
+ # 宿主只看到「MCP server 未就绪」——与下方自动探测同一条判据。
109
+ if [ -n "$ARGO_PYTHON" ] && command -v "$ARGO_PYTHON" >/dev/null 2>&1 \
110
+ && "$ARGO_PYTHON" -c 'import sys, yaml; sys.exit(0 if sys.version_info >= (3, 9) else 1)' >/dev/null 2>&1; then
111
+ PY="$ARGO_PYTHON"
112
+ else
113
+ PY=""
114
+ for c in python3 python3.14 python3.13 python3.12 python3.11 python3.10 python3.9 python; do
115
+ p="$(command -v "$c" 2>/dev/null)" || continue
116
+ if "$p" -c 'import sys, yaml; sys.exit(0 if sys.version_info >= (3, 9) else 1)' >/dev/null 2>&1; then
117
+ PY="$p"
118
+ break
119
+ fi
120
+ done
121
+ [ -n "$PY" ] || PY="python3"
122
+ fi
123
+
124
+ exec "$PY" -u "${SCRIPT_DIR}/mcp_server.py" "$@"
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env python3
2
+ """mcp_local.py — MCP 本地文件检索、受限预览与可复算沙箱。
3
+
4
+ 拆分自 mcp_handlers.py:隔离本地文件系统访问、白名单审查、seek 定位与安全执行沙箱。
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import os
11
+ import subprocess
12
+ import sys
13
+ from typing import Any
14
+
15
+ from mcp_compact import _trim_snippet
16
+
17
+ _LOCAL_READ_ALLOWED_EXTS = {
18
+ ".md", ".txt", ".csv", ".tsv", ".json", ".yaml", ".yml", ".log",
19
+ ".py", ".js", ".ts", ".html", ".xml", ".rst", ".ipynb",
20
+ }
21
+
22
+
23
+ def _local_read_whitelist() -> list[str]:
24
+ """白名单目录:ARGO_LOCAL_READ_DIRS(逗号分隔);没配置就返回空,不放行。"""
25
+ raw = (os.environ.get("ARGO_LOCAL_READ_DIRS") or "").strip()
26
+ if not raw:
27
+ return []
28
+ return [os.path.realpath(os.path.expanduser(d))
29
+ for d in raw.split(",") if d.strip()]
30
+
31
+
32
+ def _local_read_preview(
33
+ path: str,
34
+ max_chars: int = 4000,
35
+ line_start: int | None = None,
36
+ line_end: int | None = None,
37
+ ) -> tuple[str, dict[str, Any]]:
38
+ """白名单内文本文件预览(行窗口或字符截断);越权/二进制拒绝。"""
39
+ root = os.path.realpath(os.path.expanduser(path))
40
+ allowed = _local_read_whitelist()
41
+ if not allowed:
42
+ raise PermissionError(
43
+ "本地读取未配置白名单:设 ARGO_LOCAL_READ_DIRS=目录1,目录2(没配置就不放行)"
44
+ )
45
+ if not any(root == d or root.startswith(d + os.sep) for d in allowed):
46
+ raise PermissionError(f"路径不在白名单目录内: {path}")
47
+ if not os.path.isfile(root):
48
+ raise FileNotFoundError(f"文件不存在: {path}")
49
+ ext = os.path.splitext(root)[1].lower()
50
+ if ext not in _LOCAL_READ_ALLOWED_EXTS:
51
+ raise PermissionError(f"仅支持文本类文件预览({ext} 不支持;pdf 走其他路径)")
52
+ size = os.path.getsize(root)
53
+ if size > 4 * 1024 * 1024:
54
+ raise PermissionError("文件超过 4MB,拒绝预览(请缩小范围或改用搜索)")
55
+
56
+ with open(root, encoding="utf-8", errors="replace") as f:
57
+ full = f.read()
58
+ total_lines = full.count("\n") + (1 if full and not full.endswith("\n") else 0)
59
+ if line_start is not None or line_end is not None:
60
+ start = max(1, int(line_start or 1))
61
+ end = int(line_end) if line_end else start + 200
62
+ lines = full.splitlines(keepends=True)[(start - 1): end]
63
+ content = "".join(lines)
64
+ lines_slice = (start, start + len(lines) - 1)
65
+ else:
66
+ content = full
67
+ lines_slice = None
68
+
69
+ truncated = len(content) > max_chars
70
+ if truncated:
71
+ content = content[:max_chars]
72
+ return content, {
73
+ "path": root,
74
+ "chars": len(content),
75
+ "lines": (lines_slice[1] - lines_slice[0] + 1) if lines_slice else None,
76
+ "total_lines": total_lines,
77
+ "is_preview": truncated or lines_slice is not None,
78
+ }
79
+
80
+
81
+ def _seek_py() -> str:
82
+ """定位 local-seek 的 seek.py(安装感知、唯一来源,见 seek_locator)。"""
83
+ from seek_locator import resolve_seek_py
84
+ return resolve_seek_py()
85
+
86
+
87
+ def handle_local_search(
88
+ arguments: dict[str, Any],
89
+ pretty: bool = False,
90
+ ok_fn=None,
91
+ clamp_int_fn=None,
92
+ lazy_cached_fn=None,
93
+ ) -> dict[str, Any]:
94
+ """argo_local_search 实现:本地文件搜索。"""
95
+ query = str(arguments.get("query", "")).strip()
96
+
97
+ def _local_err(msg: str) -> dict:
98
+ return ok_fn({"query": query, "engine": "local_files", "count": 0, "results": [],
99
+ "errors": [msg]}, pretty=pretty)
100
+
101
+ if not query:
102
+ return _local_err("query 不能为空")
103
+ path = str(arguments.get("path", "~"))
104
+ max_results = clamp_int_fn(arguments.get("max_results", 5), 5, 1, 20)
105
+ exact = bool(arguments.get("exact", False))
106
+
107
+ # 宽泛根守卫
108
+ try:
109
+ if lazy_cached_fn("local_seek")._is_broad_local_root(os.path.expanduser(path)):
110
+ return _local_err("路径过宽(home / 根目录),扫全盘既慢又失准,已拒绝;请传具体目录")
111
+ except Exception as e:
112
+ sys.stderr.write(
113
+ f"[argo-mcp] local_search 宽泛根守卫不可用({type(e).__name__}),fail-open\n")
114
+
115
+ payload = None
116
+ try:
117
+ from local_seek import seek_query_payload
118
+ payload = seek_query_payload(query, os.path.expanduser(path),
119
+ max_results, exact=exact, time_budget=15)
120
+ except Exception:
121
+ payload = None
122
+
123
+ if payload is None:
124
+ seek_py = _seek_py()
125
+
126
+ cmd = [sys.executable, seek_py, query, "--path", path, "--json",
127
+ "--max", str(max_results)]
128
+ if exact:
129
+ cmd.append("--exact")
130
+ try:
131
+ # 兼容测试 patch mcp_handlers.subprocess.run
132
+ runner = subprocess.run
133
+ try:
134
+ import mcp_handlers
135
+ runner = getattr(mcp_handlers.subprocess, "run", subprocess.run)
136
+ except Exception:
137
+ pass
138
+
139
+ proc = runner(
140
+ cmd, capture_output=True, text=True,
141
+ encoding="utf-8", errors="replace", timeout=15,
142
+ env={**os.environ, "PYTHONUTF8": "1"})
143
+ except Exception as e:
144
+ return _local_err(f"本地搜索执行失败: {e}")
145
+ if proc.returncode != 0:
146
+ msg = (proc.stdout or proc.stderr or "").strip() or "本地搜索无结果"
147
+ return _local_err(msg)
148
+ try:
149
+ payload = json.loads(proc.stdout)
150
+ except Exception:
151
+ return _local_err("本地搜索输出解析失败")
152
+
153
+ mode = payload.get("mode", "fast")
154
+ score = 0.9 if mode == "fast" else 0.7
155
+ results = []
156
+ for r in payload.get("results") or []:
157
+ abspath = os.path.abspath(r.get("path", ""))
158
+ line = r.get("line") or 0
159
+ results.append({
160
+ "title": abspath,
161
+ "url": f"file://{abspath}" + (f"#L{line}" if line else ""),
162
+ "snippet": _trim_snippet(r.get("snippet"), 120),
163
+ "source": "local_files", "score": score,
164
+ })
165
+ return ok_fn({
166
+ "query": query, "engine": "local_files", "engines_used": ["local_files"],
167
+ "count": len(results), "elapsed_ms": payload.get("elapsed_ms"),
168
+ "cached": False, "mode": mode, "depth": None,
169
+ "results": results, "errors": [],
170
+ }, pretty=pretty)
171
+
172
+
173
+ def handle_local_read(
174
+ arguments: dict[str, Any],
175
+ pretty: bool = False,
176
+ ok_fn=None,
177
+ int_param_fn=None,
178
+ ) -> dict[str, Any]:
179
+ """argo_local_read 实现:白名单本地文本预览。"""
180
+ raw_path = str(arguments.get("path", "")).strip()
181
+ max_chars = max(200, min(int_param_fn(arguments, "max_chars", 4000), 20000))
182
+ line_start = arguments.get("line_start")
183
+ line_end = arguments.get("line_end")
184
+ if not raw_path:
185
+ return ok_fn({"path": "", "content": "", "errors": ["path 不能为空"]}, pretty=pretty)
186
+ try:
187
+ content, meta = _local_read_preview(
188
+ raw_path, max_chars=max_chars,
189
+ line_start=line_start, line_end=line_end,
190
+ )
191
+ except Exception as e:
192
+ return ok_fn({"path": raw_path, "content": "",
193
+ "errors": [str(e)]}, pretty=pretty)
194
+ return ok_fn({
195
+ "path": meta["path"],
196
+ "content": content,
197
+ "chars": meta["chars"],
198
+ "lines": meta["lines"],
199
+ "total_lines": meta["total_lines"],
200
+ "is_preview": meta["is_preview"],
201
+ "errors": [],
202
+ }, pretty=pretty)
203
+
204
+
205
+ def handle_recompute(
206
+ arguments: dict[str, Any],
207
+ pretty: bool = False,
208
+ ok_fn=None,
209
+ clamp_int_fn=None,
210
+ ) -> dict[str, Any]:
211
+ """argo_recompute 实现:可复算执行器。"""
212
+ script = str(arguments.get("script", "")).strip()
213
+ inputs_raw = arguments.get("file_inputs")
214
+ inputs = []
215
+ if isinstance(inputs_raw, str) and inputs_raw.strip():
216
+ try:
217
+ inputs = json.loads(inputs_raw)
218
+ except ValueError:
219
+ inputs = []
220
+ elif isinstance(inputs_raw, list):
221
+ inputs = inputs_raw
222
+ elif inputs_raw:
223
+ try:
224
+ inputs = json.loads(inputs_raw)
225
+ except (ValueError, TypeError):
226
+ inputs = []
227
+ timeout_s = clamp_int_fn(arguments.get("timeout_s", 30), 30, 1, 120)
228
+ max_mem_mb = clamp_int_fn(arguments.get("max_mem_mb", 512), 512, 64, 4096)
229
+ allow_exec = bool(arguments.get("allow_exec", False))
230
+ if not script:
231
+ return ok_fn({"ok": False, "skipped_reason": "script 为空"}, pretty=pretty)
232
+ try:
233
+ from recompute import run_recompute
234
+ result = run_recompute(
235
+ script, inputs or None,
236
+ timeout_s=timeout_s, max_mem_mb=max_mem_mb,
237
+ allow_exec=allow_exec,
238
+ )
239
+ except Exception as e:
240
+ result = {"ok": False, "skipped_reason": f"执行器异常: {e}"}
241
+ return ok_fn(result, pretty=pretty)