argo-search 1.0.1 → 2.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -21
- package/README.en.md +822 -0
- package/README.es.md +864 -0
- package/README.ja.md +864 -0
- package/README.ko.md +864 -0
- package/README.md +867 -320
- package/SKILL.md +135 -0
- package/assets/readme/hero.svg +121 -0
- package/assets/readme/made-with-beautify.svg +10 -0
- package/assets/readme/proof-routes.svg +73 -0
- package/assets/readme/settings-keys.png +0 -0
- package/assets/readme/settings-tools.png +0 -0
- package/assets/readme/why-better.svg +104 -0
- package/assets/readme/workflow.svg +83 -0
- package/backends/domain_profiles.json +2308 -96
- package/backends/engine_registry.yaml +3314 -503
- package/backends/query_synonyms_cn.json +35 -0
- package/backends/quota_profiles.json +2409 -161
- package/backends/source_types_cn.json +83 -0
- package/backends/text_lexicon.json +44 -0
- package/bin/argo +703 -0
- package/bin/argo.js +71 -39
- package/config.yaml +4976 -363
- package/cordis.patch.yml +21 -0
- package/data/countries.json +40 -0
- package/data/lang_matrix/lang_capability.json +842 -0
- package/data/lang_matrix/matrix_2026-09-10.json +11921 -0
- package/data/regions_cn.json +1 -0
- package/docs/ADDING_NEW_ENGINE.md +184 -0
- package/docs/ARGO_INTRO.md +124 -0
- package/docs/DATA_SOURCE_GAPS.md +81 -0
- package/docs/DESIGN_LOCAL_DATA_FUSION.md +90 -0
- package/docs/ENGINE_CATALOG.md +564 -0
- package/docs/MCP_SETUP.md +106 -0
- package/docs/PLATFORM_PATHS.md +111 -0
- package/docs/RELEASE_NOTES_v2.8.0.md +71 -0
- package/docs/RELEASE_NOTES_v2.8.2.md +63 -0
- package/docs/RELEASE_NOTES_v2.8.3.md +55 -0
- package/docs/RELEASE_NOTES_v2.8.4.md +79 -0
- package/docs/RELEASE_NOTES_v2.8.5.md +102 -0
- package/docs/RELEASE_NOTES_v2.8.6.md +66 -0
- package/docs/RELEASE_NOTES_v2.8.7.md +65 -0
- package/docs/RELEASE_NOTES_v2.8.8.md +67 -0
- package/docs/RELEASE_NOTES_v2.8.9.md +67 -0
- package/docs/RELEASE_NOTES_v2.9.0.md +64 -0
- package/docs/SEARCH_ARCHIVE.md +115 -0
- package/docs/assets/architecture.svg +104 -0
- package/docs/assets/hero.svg +98 -0
- package/docs/engines/bangumi.md +27 -0
- package/docs/engines/biorxiv.md +27 -0
- package/docs/engines/clawhub.md +27 -0
- package/docs/engines/crt_sh.md +27 -0
- package/docs/engines/datacite.md +27 -0
- package/docs/engines/deps_dev.md +27 -0
- package/docs/engines/douban_movie.md +27 -0
- package/docs/engines/endoflife.md +27 -0
- package/docs/engines/flk_law.md +27 -0
- package/docs/engines/fxtwitter.md +27 -0
- package/docs/engines/google_news.md +27 -0
- package/docs/engines/gov_regulations.md +27 -0
- package/docs/engines/guqian.md +27 -0
- package/docs/engines/hackernews.md +27 -0
- package/docs/engines/iplant.md +27 -0
- package/docs/engines/keenable.md +27 -0
- package/docs/engines/met_museum.md +27 -0
- package/docs/engines/nasa_images.md +27 -0
- package/docs/engines/netease_music.md +27 -0
- package/docs/engines/npm.md +27 -0
- package/docs/engines/nvd.md +27 -0
- package/docs/engines/openreview.md +27 -0
- package/docs/engines/openstd.md +27 -0
- package/docs/engines/parallel_free.md +27 -0
- package/docs/engines/people_daily.md +27 -0
- package/docs/engines/realtime_index.md +27 -0
- package/docs/engines/sec_edgar.md +27 -0
- package/docs/engines/seltz.md +27 -0
- package/docs/engines/skillsmp.md +27 -0
- package/docs/engines/sspai.md +27 -0
- package/docs/engines/std_samr.md +27 -0
- package/docs/engines/train.md +27 -0
- package/docs/engines/un_comtrade.md +27 -0
- package/docs/engines/wikisource.md +27 -0
- package/docs/engines/zdic.md +27 -0
- package/docs/engines/zenodo.md +27 -0
- package/docs/engines/zhihu_hot_app.md +27 -0
- package/docs//344/270/272/344/273/200/344/271/210/351/200/211/346/213/251argo.md +176 -0
- package/engines/README.md +10 -0
- package/engines/_template_cli.yaml +39 -0
- package/engines/_template_http.yaml +37 -0
- package/engines/plugins/_template_plugin.py +50 -0
- package/engines/specs/_cisa_kev.yaml +54 -0
- package/engines/specs/_osv.yaml +63 -0
- package/engines/specs/aljazeera.yaml +43 -0
- package/engines/specs/antara.yaml +43 -0
- package/engines/specs/artic.yaml +20 -0
- package/engines/specs/aviation_weather.yaml +39 -0
- package/engines/specs/bangumi.yaml +21 -0
- package/engines/specs/biorxiv.yaml +24 -0
- package/engines/specs/carbon_intensity.yaml +32 -0
- package/engines/specs/cinii.yaml +44 -0
- package/engines/specs/clawhub.yaml +49 -0
- package/engines/specs/cleveland.yaml +19 -0
- package/engines/specs/cn_ai_news.yaml +43 -0
- package/engines/specs/core.yaml +35 -0
- package/engines/specs/crt_sh.yaml +38 -0
- package/engines/specs/ct24.yaml +43 -0
- package/engines/specs/datacite.yaml +27 -0
- package/engines/specs/datagov_uk.yaml +41 -0
- package/engines/specs/ddgs_images.yaml +45 -0
- package/engines/specs/deepseek_search.yaml +74 -0
- package/engines/specs/deezer.yaml +20 -0
- package/engines/specs/deps_dev.yaml +21 -0
- package/engines/specs/digup.yaml +36 -0
- package/engines/specs/doi.yaml +39 -0
- package/engines/specs/douban_movie.yaml +22 -0
- package/engines/specs/dw_news.yaml +47 -0
- package/engines/specs/egov_law.yaml +21 -0
- package/engines/specs/elpais.yaml +43 -0
- package/engines/specs/endoflife.yaml +21 -0
- package/engines/specs/energy_charts.yaml +21 -0
- package/engines/specs/factcheck_org.yaml +52 -0
- package/engines/specs/faz.yaml +43 -0
- package/engines/specs/federal_register.yaml +57 -0
- package/engines/specs/firecrawl.yaml +53 -0
- package/engines/specs/flk_law.yaml +24 -0
- package/engines/specs/folha.yaml +43 -0
- package/engines/specs/france24.yaml +44 -0
- package/engines/specs/full_fact.yaml +47 -0
- package/engines/specs/fxtwitter.yaml +31 -0
- package/engines/specs/gbfs_nyc.yaml +32 -0
- package/engines/specs/gdacs.yaml +21 -0
- package/engines/specs/gdelt.yaml +64 -0
- package/engines/specs/google_news.yaml +22 -0
- package/engines/specs/gov_regulations.yaml +38 -0
- package/engines/specs/guardian_rss.yaml +59 -0
- package/engines/specs/hurriyet.yaml +43 -0
- package/engines/specs/iplant.yaml +25 -0
- package/engines/specs/jikan.yaml +24 -0
- package/engines/specs/jolpica.yaml +20 -0
- package/engines/specs/k10plus.yaml +20 -0
- package/engines/specs/keenable.yaml +44 -0
- package/engines/specs/lefigaro.yaml +43 -0
- package/engines/specs/listenbrainz.yaml +19 -0
- package/engines/specs/matichon.yaml +43 -0
- package/engines/specs/met_museum.yaml +21 -0
- package/engines/specs/nasa_images.yaml +45 -0
- package/engines/specs/netease_music.yaml +38 -0
- package/engines/specs/nhk.yaml +43 -0
- package/engines/specs/nhtsa_vpic.yaml +20 -0
- package/engines/specs/noaa_swpc.yaml +20 -0
- package/engines/specs/nvd.yaml +38 -0
- package/engines/specs/obis.yaml +20 -0
- package/engines/specs/opencitations.yaml +52 -0
- package/engines/specs/openf1.yaml +21 -0
- package/engines/specs/openfoodfacts.yaml +45 -0
- package/engines/specs/openligadb.yaml +20 -0
- package/engines/specs/openreview.yaml +37 -0
- package/engines/specs/openstd.yaml +21 -0
- package/engines/specs/people_daily.yaml +22 -0
- package/engines/specs/realtime_index.yaml +34 -0
- package/engines/specs/ror.yaml +20 -0
- package/engines/specs/satnogs.yaml +20 -0
- package/engines/specs/sec_edgar.yaml +46 -0
- package/engines/specs/skillsmp.yaml +50 -0
- package/engines/specs/sogou_weixin_browser.yaml +30 -0
- package/engines/specs/soilgrids.yaml +25 -0
- package/engines/specs/sspai.yaml +36 -0
- package/engines/specs/stackexchange.yaml +46 -0
- package/engines/specs/std_samr.yaml +21 -0
- package/engines/specs/tass.yaml +43 -0
- package/engines/specs/tle_mirror.yaml +21 -0
- package/engines/specs/train.yaml +37 -0
- package/engines/specs/tvmaze.yaml +20 -0
- package/engines/specs/twitter_syndication.yaml +31 -0
- package/engines/specs/un_comtrade.yaml +23 -0
- package/engines/specs/unpaywall.yaml +54 -0
- package/engines/specs/vnpress.yaml +43 -0
- package/engines/specs/weather.yaml +32 -0
- package/engines/specs/who_don.yaml +21 -0
- package/engines/specs/who_gho.yaml +20 -0
- package/engines/specs/wikimedia_commons.yaml +34 -0
- package/engines/specs/wikisource.yaml +22 -0
- package/engines/specs/worms.yaml +19 -0
- package/engines/specs/x_trending.yaml +34 -0
- package/engines/specs/yna.yaml +43 -0
- package/engines/specs/ynet.yaml +43 -0
- package/engines/specs/zbmath.yaml +40 -0
- package/engines/specs/zdic.yaml +22 -0
- package/engines/specs/zenodo.yaml +27 -0
- package/engines/specs/zhihu_hot_app.yaml +35 -0
- package/mcp/clients.yaml +74 -0
- package/package.json +51 -12
- package/packages/dsh-plugin/README.md +134 -0
- package/packages/dsh-plugin/cordis.patch.yml +48 -0
- package/packages/dsh-plugin/dsh/client.js +1244 -0
- package/packages/dsh-plugin/dsh/index.js +2290 -0
- package/packages/dsh-plugin/dsh/native-tools.mjs +743 -0
- package/packages/dsh-plugin/package.json +38 -0
- package/packages/dsh-plugin/test/client.test.js +232 -0
- package/packages/dsh-plugin/test/config.test.js +30 -0
- package/packages/dsh-plugin/test/index.test.js +1338 -0
- package/references/query-templates.md +96 -0
- package/references/query-templates.yaml +118 -0
- package/scripts/ab_eval.py +219 -0
- package/scripts/ab_eval_p0p1.py +266 -0
- package/scripts/adaptive.py +271 -70
- package/scripts/answer.py +154 -0
- package/scripts/archive_run.py +591 -0
- package/scripts/argo_engine_registry.py +172 -0
- package/scripts/argo_paths.py +728 -0
- package/scripts/article.py +136 -0
- package/scripts/arxiv_source.py +201 -0
- package/scripts/badcase_ledger.py +252 -0
- package/scripts/batch_probe.py +241 -0
- package/scripts/benchmark.py +19 -0
- package/scripts/bounded_run.py +144 -0
- package/scripts/browser_auth.py +323 -0
- package/scripts/burstiness_detector.py +147 -0
- package/scripts/cache.py +1078 -67
- package/scripts/cache_guard.py +271 -0
- package/scripts/cache_key_vdom.py +56 -0
- package/scripts/cache_similarity.py +170 -0
- package/scripts/caliber_isolation.py +195 -0
- package/scripts/calibrate_lowquality.py +210 -0
- package/scripts/candidate_envelope.py +366 -0
- package/scripts/chrome_cdp.py +871 -0
- package/scripts/circuit_breaker.py +389 -0
- package/scripts/citations.py +334 -0
- package/scripts/cite_cli.py +59 -0
- package/scripts/cjk_tokens.py +95 -0
- package/scripts/clarify.py +47 -24
- package/scripts/cli_io.py +240 -0
- package/scripts/config.py +683 -45
- package/scripts/config_cache.py +402 -0
- package/scripts/conn_pool.py +220 -0
- package/scripts/content_security.py +685 -0
- package/scripts/content_signals.py +730 -0
- package/scripts/crawl.py +74 -35
- package/scripts/daemon.py +866 -0
- package/scripts/digup_bridge.py +214 -0
- package/scripts/engine_admission.py +366 -0
- package/scripts/engine_dispatch.py +1019 -0
- package/scripts/engine_env.py +534 -0
- package/scripts/engine_failure.py +411 -0
- package/scripts/engine_families.py +732 -0
- package/scripts/engine_policy.py +218 -0
- package/scripts/engine_requires.py +190 -0
- package/scripts/engine_status.py +322 -0
- package/scripts/engine_validate.py +638 -0
- package/scripts/engines.py +778 -294
- package/scripts/engines_base.py +1521 -0
- package/scripts/engines_builders.py +298 -0
- package/scripts/engines_builders_batch10.py +159 -0
- package/scripts/engines_builders_batch11.py +174 -0
- package/scripts/engines_builders_batch12.py +103 -0
- package/scripts/engines_builders_batch13.py +340 -0
- package/scripts/engines_builders_batch9.py +1468 -0
- package/scripts/engines_builders_cn.py +2283 -0
- package/scripts/engines_builders_data.py +2923 -0
- package/scripts/engines_builders_data_macro.py +775 -0
- package/scripts/engines_builders_feeds.py +255 -0
- package/scripts/engines_builders_intl.py +1239 -0
- package/scripts/engines_builders_search.py +440 -0
- package/scripts/engines_builders_tech.py +1360 -0
- package/scripts/evidence.py +588 -162
- package/scripts/evidence_loop.py +592 -0
- package/scripts/evidence_tier.py +298 -0
- package/scripts/except_sets.py +25 -0
- package/scripts/extract.py +55 -16
- package/scripts/fact_align.py +207 -0
- package/scripts/fact_crosscheck.py +230 -0
- package/scripts/fetch.py +25 -12
- package/scripts/fetch_browser.py +87 -0
- package/scripts/fetch_jsrun.py +122 -0
- package/scripts/fetch_quality.py +225 -0
- package/scripts/fetch_render_tinyfish.py +117 -0
- package/scripts/fetch_v3.py +1779 -0
- package/scripts/focus_extract.py +350 -0
- package/scripts/fulltext_store.py +169 -0
- package/scripts/fxtwitter_api.py +325 -0
- package/scripts/gen_engine_catalog.py +364 -0
- package/scripts/gen_native_tools.py +91 -0
- package/scripts/gen_routing_snapshot.py +184 -0
- package/scripts/health_check.py +140 -402
- package/scripts/health_probe.py +23 -8
- package/scripts/hot_state.py +134 -0
- package/scripts/http_client.py +1053 -0
- package/scripts/image_ops.py +430 -0
- package/scripts/image_vision/vision_probe +0 -0
- package/scripts/image_vision/vision_probe.swift +126 -0
- package/scripts/install.ps1 +148 -0
- package/scripts/install.sh +206 -0
- package/scripts/job.py +1186 -0
- package/scripts/jump_resolver.py +235 -0
- package/scripts/lang_capability.py +150 -0
- package/scripts/lang_detect.py +289 -0
- package/scripts/lang_matrix_probe.py +329 -0
- package/scripts/lang_pref.py +311 -0
- package/scripts/link_source.py +340 -0
- package/scripts/local_engines.py +321 -0
- package/scripts/local_image.py +970 -0
- package/scripts/local_seek.py +366 -0
- package/scripts/macro_countries.py +82 -0
- package/scripts/matrix_search_eval.py +1105 -0
- package/scripts/mcp_diag.py +8 -3
- package/scripts/mcp_handlers.py +1074 -0
- package/scripts/mcp_handlers_surface.py +157 -0
- package/scripts/mcp_launch.sh +122 -0
- package/scripts/mcp_server.py +118 -417
- package/scripts/mcp_setup.py +407 -0
- package/scripts/mcp_tools.py +330 -0
- package/scripts/mcp_transport.py +191 -0
- package/scripts/min_version_scan.py +335 -0
- package/scripts/net_proxy.py +258 -0
- package/scripts/network_aware.py +152 -0
- package/scripts/paper.py +274 -0
- package/scripts/pdf_extract.py +518 -0
- package/scripts/phrase_filter.py +66 -0
- package/scripts/plan.py +422 -0
- package/scripts/postprocess_signals.py +150 -0
- package/scripts/pre-commit +48 -0
- package/scripts/query_enhance.py +157 -0
- package/scripts/query_operators.py +196 -0
- package/scripts/query_rewriter.py +116 -7
- package/scripts/query_signals.py +300 -0
- package/scripts/query_templates.py +167 -0
- package/scripts/query_understanding.py +411 -0
- package/scripts/query_variants.py +298 -0
- package/scripts/quota.py +488 -76
- package/scripts/rank_signals.py +775 -0
- package/scripts/ranking_eval.py +319 -0
- package/scripts/readability_extract.py +433 -0
- package/scripts/recompute.py +415 -0
- package/scripts/recovery.py +616 -0
- package/scripts/recovery_l0.py +160 -0
- package/scripts/redskill/redskill_engine.py +332 -0
- package/scripts/regression_p0p1.py +318 -0
- package/scripts/replay_eval.py +640 -0
- package/scripts/rerank_tfidf.py +225 -0
- package/scripts/research.py +591 -403
- package/scripts/research_cli.py +361 -0
- package/scripts/research_dossier.py +492 -0
- package/scripts/research_expand.py +146 -0
- package/scripts/research_gates.py +272 -0
- package/scripts/research_report.py +209 -0
- package/scripts/research_strategy.py +37 -0
- package/scripts/research_work_packages.py +195 -0
- package/scripts/result_lang.py +311 -0
- package/scripts/robots_guard.py +259 -0
- package/scripts/route.py +921 -254
- package/scripts/route_bangs.py +40 -0
- package/scripts/route_cache.py +225 -0
- package/scripts/route_combo.py +910 -0
- package/scripts/route_domains.py +328 -0
- package/scripts/route_lang.py +605 -0
- package/scripts/route_log.py +63 -0
- package/scripts/route_policy.py +250 -0
- package/scripts/rrf_classic.py +66 -0
- package/scripts/screenshot.py +73 -0
- package/scripts/search.py +897 -405
- package/scripts/search_attribution.py +88 -0
- package/scripts/search_benchmark.py +407 -0
- package/scripts/search_cli.py +627 -0
- package/scripts/search_entry.py +389 -0
- package/scripts/search_output.py +606 -0
- package/scripts/search_pipeline.py +1077 -0
- package/scripts/search_rank.py +991 -0
- package/scripts/search_types.py +27 -12
- package/scripts/seek_locator.py +68 -0
- package/scripts/semantic_evidence.py +215 -0
- package/scripts/serp_guard.py +228 -0
- package/scripts/serp_kill_log.py +51 -0
- package/scripts/single_flight.py +120 -0
- package/scripts/social_engines/__init__.py +10 -0
- package/scripts/social_engines/bilibili_engine.py +131 -0
- package/scripts/social_engines/hackernews_engine.py +113 -0
- package/scripts/social_engines/reddit_engine.py +172 -0
- package/scripts/social_engines/twitter_engine.py +397 -0
- package/scripts/social_engines/v2ex_engine.py +101 -0
- package/scripts/social_engines/weibo_engine.py +128 -0
- package/scripts/social_engines/xiaohongshu_engine.py +137 -0
- package/scripts/social_engines/zhihu_engine.py +139 -0
- package/scripts/social_research.py +201 -0
- package/scripts/sogou_weixin_browser.py +318 -0
- package/scripts/source_ledger.py +249 -0
- package/scripts/stage_timing.py +58 -0
- package/scripts/stats_cli.py +95 -0
- package/scripts/straggler_policy.py +60 -0
- package/scripts/stylometry_detector.py +231 -0
- package/scripts/sync_backends.py +353 -0
- package/scripts/sync_installs.py +29 -0
- package/scripts/template_cli.py +127 -0
- package/scripts/text_lexicon.py +72 -0
- package/scripts/tfidf_router.py +109 -37
- package/scripts/time_utils.py +233 -0
- package/scripts/topic_research_profiles.py +643 -0
- package/scripts/train.py +737 -0
- package/scripts/tweet.py +596 -0
- package/scripts/url_canon.py +217 -0
- package/scripts/url_optimize.py +56 -0
- package/scripts/url_safety.py +236 -0
- package/scripts/usage_log.py +116 -0
- package/scripts/usage_log_clean.py +113 -0
- package/scripts/v2ex_nodes.py +311 -0
- package/scripts/variant_recall.py +188 -0
- package/scripts/watch.py +205 -0
- package/scripts/wechat_article.py +258 -0
- package/scripts/wide_research.py +402 -0
- package/scripts/wx.py +349 -0
- package/scripts/x_article_fetch.py +141 -0
- package/scripts/x_search.py +234 -0
- package/scripts/x_trending.py +189 -0
- package/scripts/yaml_load.py +67 -0
- package/sub-skills/ego-search/SKILL.md +253 -0
- package/sub-skills/ego-search/references/browser-runtime.md +43 -0
- package/sub-skills/ego-search/references/install.md +67 -0
- package/sub-skills/ego-search/references/original-ego-upgrade.md +51 -0
- package/sub-skills/ego-search/scripts/ego_search.py +800 -0
- package/sub-skills/ego-search/scripts/merge.py +226 -0
- package/sub-skills/ego-search/scripts/quality.py +64 -0
- package/sub-skills/ego-search/scripts/runtime.py +172 -0
- package/sub-skills/ego-search/scripts/safety.py +109 -0
- package/sub-skills/ego-search/scripts/serp_spec.py +109 -0
- package/sub-skills/ego-search/scripts/webbridge_adapter.py +374 -0
- package/sub-skills/ego-search/tests/test_query_normalize.py +68 -0
- package/sub-skills/js-run/SKILL.md +67 -0
- package/sub-skills/js-run/scripts/jsrun.py +112 -0
- package/sub-skills/js-run/scripts/shim.js +188 -0
- package/sub-skills/js-run/tests/fixtures/challenge_like.js +27 -0
- package/sub-skills/js-run/tests/test_jsrun.py +165 -0
- package/sub-skills/local-search/SKILL.md +50 -53
- package/sub-skills/local-search/bm25.py +162 -0
- package/sub-skills/local-search/config.yaml +152 -55
- package/sub-skills/local-search/engine_registry.py +91 -26
- package/sub-skills/local-search/{health_check.py → local_health_check.py} +140 -10
- package/sub-skills/local-search/local_search_adapter.py +13 -2
- package/sub-skills/local-search/parse_maps.yaml +40 -42
- package/sub-skills/local-search/search_v3.py +1182 -65
- package/sub-skills/local-search/smart_router.py +47 -7
- package/sub-skills/local-seek/SKILL.md +110 -0
- package/sub-skills/local-seek/config/domains.yaml +20 -0
- package/sub-skills/local-seek/references/auto-behaviors.md +24 -0
- package/sub-skills/local-seek/references/fd-mdfind-recipes.md +62 -0
- package/sub-skills/local-seek/references/git-integration.md +54 -0
- package/sub-skills/local-seek/references/remote-handoff.md +46 -0
- package/sub-skills/local-seek/references/rg-recipes.md +96 -0
- package/sub-skills/local-seek/references/strategies.md +52 -0
- package/sub-skills/local-seek/references/structural-search.md +59 -0
- package/sub-skills/local-seek/scripts/eval_rank.py +216 -0
- package/sub-skills/local-seek/scripts/eval_seek.py +224 -0
- package/sub-skills/local-seek/scripts/seek.py +1465 -0
- package/sub-skills/local-seek/scripts/seek_frecency.py +126 -0
- package/sub-skills/local-seek/scripts/seek_fts.py +430 -0
- package/sub-skills/local-seek/scripts/seek_rank.py +193 -0
- package/sub-skills/local-seek/tests/test_content_rank.py +222 -0
- package/sub-skills/local-seek/tests/test_determinism_20261006.py +145 -0
- package/sub-skills/local-seek/tests/test_noise_tier.py +101 -0
- package/sub-skills/local-seek/tests/test_pcre2_probe.py +136 -0
- package/sub-skills/local-seek/tests/test_rank_pinyin.py +77 -0
- package/sub-skills/local-seek/tests/test_regression_20261003.py +169 -0
- package/sub-skills/local-seek/tests/test_regression_20261006.py +146 -0
- package/sub-skills/local-seek/tests/test_seek_degradation.py +111 -0
- package/sub-skills/local-seek/tests/test_seek_fts.py +313 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
根据查询特征将请求路由到最优本地引擎组合,覆盖:
|
|
5
5
|
- 中文通用 / 中文新闻 / 代码 / 学术 / 参考百科 / 事实问答 / 垂直实体
|
|
6
|
-
- 与 unified-search 的 route.py
|
|
6
|
+
- 与 unified-search 的 route.py 拆开,local-search 内部使用
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
@@ -22,6 +22,8 @@ if not logger.handlers:
|
|
|
22
22
|
|
|
23
23
|
# 查询特征正则
|
|
24
24
|
_RE_CHINESE = re.compile(r"[一-鿿]")
|
|
25
|
+
_RE_KANA = re.compile(r"[\u3040-\u30ff]")
|
|
26
|
+
_RE_HANGUL = re.compile(r"[\uac00-\ud7af]")
|
|
25
27
|
_RE_ACADEMIC = re.compile(
|
|
26
28
|
r"\b(paper|arxiv|preprint|doi|citation|abstract|journal|conference|"
|
|
27
29
|
r"peer[-\s]?review|research|survey|review|thesis|dissertation)\b|"
|
|
@@ -60,10 +62,23 @@ CATEGORY_PRIORITY = {
|
|
|
60
62
|
"academic": ["local_arxiv", "local_semantic_scholar", "local_crossref", "local_pubmed"],
|
|
61
63
|
"code": ["local_github", "local_stackoverflow", "local_gitlab", "local_npm"],
|
|
62
64
|
"news": ["local_bing_news", "local_google_news", "local_duckduckgo_news"],
|
|
63
|
-
|
|
65
|
+
# chinese 与主路径 route_combo._select_sub_engines 中文支对齐(2026-10-06 实测):
|
|
66
|
+
# baidu 直连 0 结果移出;sogou(~1s 相关)/360(~1s)实测可用;yandex 殿后。
|
|
67
|
+
"chinese": ["local_sogou", "local_360", "local_yandex", "local_bing", "local_duckduckgo"],
|
|
68
|
+
# ja:yandex 实测覆盖最好;bing text 后端已被 ddgs 9.14.4 移除(auto 降级)
|
|
69
|
+
"japanese": ["local_yandex", "local_duckduckgo", "local_bing"],
|
|
70
|
+
# ko 同 ja
|
|
71
|
+
"korean": ["local_yandex", "local_duckduckgo"],
|
|
64
72
|
"reference": ["local_wikipedia", "local_wiktionary", "local_wikiquote"],
|
|
65
73
|
"vertical": ["local_openstreetmap", "local_imdb", "local_goodreads"],
|
|
66
|
-
|
|
74
|
+
# web_general 顺序 = 实测可用性(2026-10-06 重排):
|
|
75
|
+
# ddgs 9.14.4 起 text 后端仅 brave/duckduckgo/google/grokipedia/
|
|
76
|
+
# mojeek/startpage/wikipedia/yahoo/yandex——没有 bing,local_bing 的
|
|
77
|
+
# `-b bing` 已静默降级 auto(1.6-6s 随机波动,拖早停第二引擎的尾),
|
|
78
|
+
# 故移出 web_general(chinese 域仍保留作第 4 备选)。
|
|
79
|
+
# brave 对真实查询稳定 0 结果;yandex 是唯一稳定后端(~1.9s)置首,
|
|
80
|
+
# ddg/yahoo 次之(限流时 1s 级快速失败,不拖墙钟)。
|
|
81
|
+
"web_general": ["local_yandex", "local_duckduckgo", "local_yahoo", "local_brave", "local_bing"],
|
|
67
82
|
}
|
|
68
83
|
|
|
69
84
|
|
|
@@ -71,9 +86,29 @@ def extract_features(query: str) -> dict[str, Any]:
|
|
|
71
86
|
"""提取查询特征向量。"""
|
|
72
87
|
total = max(len(query), 1)
|
|
73
88
|
chinese = len(_RE_CHINESE.findall(query))
|
|
89
|
+
# 主语言判定:优先复用 scripts/lang_detect 单来源
|
|
90
|
+
primary_lang = "en"
|
|
91
|
+
try:
|
|
92
|
+
from lang_detect import detect_language
|
|
93
|
+
primary_lang = detect_language(query)
|
|
94
|
+
except ImportError:
|
|
95
|
+
kana = len(_RE_KANA.findall(query))
|
|
96
|
+
hangul = len(_RE_HANGUL.findall(query))
|
|
97
|
+
if kana / total >= 0.15 or (kana and chinese / total >= 0.3):
|
|
98
|
+
primary_lang = "ja"
|
|
99
|
+
elif hangul / total >= 0.15:
|
|
100
|
+
primary_lang = "ko"
|
|
101
|
+
elif chinese / total >= 0.3:
|
|
102
|
+
primary_lang = "zh"
|
|
103
|
+
else:
|
|
104
|
+
primary_lang = "en"
|
|
74
105
|
return {
|
|
75
106
|
"chinese_ratio": chinese / total,
|
|
76
|
-
|
|
107
|
+
# is_chinese:仅当真主语言为 zh 时标中文(日文汉字查询不再误入 chinese 分类)
|
|
108
|
+
"is_chinese": primary_lang == "zh" or (
|
|
109
|
+
primary_lang not in ("ja", "ko") and chinese / total > 0.3
|
|
110
|
+
),
|
|
111
|
+
"primary_lang": primary_lang,
|
|
77
112
|
"is_academic": bool(_RE_ACADEMIC.search(query)),
|
|
78
113
|
"is_code": bool(_RE_CODE.search(query)),
|
|
79
114
|
"is_news": bool(_RE_NEWS.search(query)),
|
|
@@ -116,6 +151,11 @@ def route_query(
|
|
|
116
151
|
|
|
117
152
|
# 特征 → 候选分类
|
|
118
153
|
candidates: list[tuple[str, float]] = []
|
|
154
|
+
# 日/韩主语言:优先对应语言的本地引擎分类
|
|
155
|
+
if features.get("primary_lang") == "ja":
|
|
156
|
+
candidates.append(("japanese", 1.0))
|
|
157
|
+
elif features.get("primary_lang") == "ko":
|
|
158
|
+
candidates.append(("korean", 1.0))
|
|
119
159
|
if features["is_academic"]:
|
|
120
160
|
candidates.append(("academic", 1.0))
|
|
121
161
|
if features["is_code"]:
|
|
@@ -130,13 +170,13 @@ def route_query(
|
|
|
130
170
|
# 事实查询优先百科与通用搜索
|
|
131
171
|
candidates.append(("reference", 0.85))
|
|
132
172
|
candidates.append(("web_general", 0.7))
|
|
133
|
-
if features["is_chinese"]:
|
|
173
|
+
if features["is_chinese"] and features.get("primary_lang") != "ja":
|
|
134
174
|
candidates.append(("chinese", 0.85))
|
|
135
175
|
# 中文新闻类查询增强
|
|
136
176
|
if features["is_news"]:
|
|
137
177
|
candidates.append(("news", 0.9))
|
|
138
178
|
|
|
139
|
-
#
|
|
179
|
+
# 保底
|
|
140
180
|
if not candidates:
|
|
141
181
|
candidates.append(("web_general", 0.5))
|
|
142
182
|
|
|
@@ -168,7 +208,7 @@ def route_query(
|
|
|
168
208
|
if len(selected) >= max_engines:
|
|
169
209
|
break
|
|
170
210
|
|
|
171
|
-
#
|
|
211
|
+
# 保底:如果都没选到,返回前几个启用的可用引擎
|
|
172
212
|
if not selected:
|
|
173
213
|
selected = reg.list_engines(available_only=require_available, enabled_only=True)[:max_engines]
|
|
174
214
|
reasons = [f"{e}(fallback)" for e in selected]
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: local-seek
|
|
3
|
+
version: 1.6.0
|
|
4
|
+
description: 本机文件与代码内容搜索(rg/fd/mdfind/grep 统一入口 seek.py,工具输出即答案)。与 argo 联网搜索互补:搜本机目录、代码符号、文件名、文档全文、文件结构。触发:搜本地、找文件、找代码、本机搜 xx、代码在哪、统计本地命中。
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# local-seek — 本地高效搜索(v1.6.0)
|
|
8
|
+
|
|
9
|
+
搜本机文件和内容就从这里开始。**工具的输出就是答案**,不用再自己翻一遍。
|
|
10
|
+
与 Argo(联网搜索)分工:Argo 搜网络,本技能搜本机。
|
|
11
|
+
|
|
12
|
+
## 三层递进:先定位、再看上下文、最后精读
|
|
13
|
+
|
|
14
|
+
不要一上来就读文件。一层层往里走,每层的结果都不多:
|
|
15
|
+
|
|
16
|
+
| 层 | 干什么 | 命令 | 输出量 |
|
|
17
|
+
|----|--------|------|--------|
|
|
18
|
+
| L1 定位 | 找到「在哪个文件」 | seek.py "词" --count 或 --filename | 每文件一行 |
|
|
19
|
+
| L2 上下文 | 看命中位置附近 | seek.py "词" --context 2 | 每命中 3 行 |
|
|
20
|
+
| L3 精读 | 读关键段落 | read_file 按行号局部读取 | 按需 |
|
|
21
|
+
|
|
22
|
+
每次搜索先想清楚停在哪一层,默认只做第一层。
|
|
23
|
+
|
|
24
|
+
## 统一入口
|
|
25
|
+
|
|
26
|
+
统一走 `scripts/seek.py`(相对 argo 根:`sub-skills/local-seek/scripts/seek.py`),
|
|
27
|
+
由它选工具,不要自己拼 rg/fd 参数:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 以下以 argo 安装根为 cwd;或写死 $ARGO_HOME/sub-skills/local-seek/scripts/seek.py
|
|
31
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" # 默认:当前目录全文
|
|
32
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --path ~/notes # 指定目录
|
|
33
|
+
python3 sub-skills/local-seek/scripts/seek.py "词" --path ~/.agents --dot # 连 . 开头目录与软链一起搜;搜 ~/.agents、~/.zcode 要加(Spotlight 收不到)
|
|
34
|
+
python3 sub-skills/local-seek/scripts/seek.py "词" --path . --include-noise # repos/、tests/ 等与真源平权(默认排真源之后,仍搜得到)
|
|
35
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --count # 先数命中,再决定是否深入
|
|
36
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --filename # 按文件名
|
|
37
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --spotlight # 全盘兜底(PDF/邮件/笔记)
|
|
38
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --type py,ts
|
|
39
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --json # 结构化输出
|
|
40
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --exact # 关闭中文扩展,精确匹配
|
|
41
|
+
python3 sub-skills/local-seek/scripts/seek.py "查询词" --exclude 某文件 # 额外排除(可重复)
|
|
42
|
+
python3 sub-skills/local-seek/scripts/seek.py --outline 文件路径 # 文件结构(def/class/标题/顶层key)
|
|
43
|
+
python3 sub-skills/local-seek/scripts/seek.py --lines 10-50 文件路径 # 按行读取,替代 read_file 全文
|
|
44
|
+
python3 sub-skills/local-seek/scripts/seek.py "裸except" --structural # 结构搜索(空catch/裸except/装饰函数等)
|
|
45
|
+
python3 sub-skills/local-seek/scripts/seek.py --git-log 文件路径 # 文件的最近提交历史
|
|
46
|
+
python3 sub-skills/local-seek/scripts/seek.py --git-blame 12 文件路径 # 第 12 行的提交归属
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
内置智能行为(固定字符串回退、中文 2-gram 扩展、PCRE2 检测、结构搜索、
|
|
50
|
+
git 联动等)自动生效,明细见 references/auto-behaviors.md。
|
|
51
|
+
|
|
52
|
+
## 工具选择(何时换工具)
|
|
53
|
+
|
|
54
|
+
| 场景 | 用 | 为什么 |
|
|
55
|
+
|------|-----|--------|
|
|
56
|
+
| 搜代码/正文关键词 | rg(默认) | 毫秒级,尊重 .gitignore,自动排除 node_modules 等 |
|
|
57
|
+
| 只记得文件名 | --filename(fd) | 按文件名模糊匹配 |
|
|
58
|
+
| 搜 PDF/邮件/已归档内容 | --spotlight(mdfind) | 用系统已建好的索引,不额外花时间(Windows/Linux 无此工具,改用 rg) |
|
|
59
|
+
| 找代码模式(裸except/空catch等) | --structural | 按语义不按字符串 |
|
|
60
|
+
| 追文件历史/单行归属 | --git-log / --git-blame | 免开终端敲 git |
|
|
61
|
+
| 当前目录搜不到 | 先扩大 --path,再 --spotlight | 先窄后宽 |
|
|
62
|
+
| 大仓库担心输出爆炸 | --count + --max 20 | 先看分布再深入 |
|
|
63
|
+
|
|
64
|
+
## 执行纪律
|
|
65
|
+
|
|
66
|
+
1. **先窄后宽**:先限定目录/扩展名,搜不到再扩大。禁止一开始就全盘扫。
|
|
67
|
+
2. **先数后看**:--count 看分布,--context 0(默认)看命中行,最后才读文件。
|
|
68
|
+
3. **指定类型**:代码场景加 --type(py,ts,go…),文档场景用 --scope doc。
|
|
69
|
+
4. **绝对路径优先**:涉及读文件时用 read_file + 绝对路径。
|
|
70
|
+
5. **不读整个文件**:L3 精读用行号偏移局部读取,命中上下文不够再扩。
|
|
71
|
+
6. **结果为空先换词**:换同义词/拆词/去大小写,再换工具(fd→mdfind),
|
|
72
|
+
不要重复同一查询。
|
|
73
|
+
7. **先结构后正文**:大文件先 --outline 看结构,再 --lines N-M 按需读取,
|
|
74
|
+
禁止直接 read_file 整个文件。
|
|
75
|
+
8. **结构搜索按语义**:找「是不是有裸 except」这类问题用 --structural,
|
|
76
|
+
不要手写正则碰运气;可用语义清单见 references/structural-search.md。
|
|
77
|
+
9. **git 只读标题**:--git-log 只给标题,够用就停;要看具体改动再手动 git show。
|
|
78
|
+
|
|
79
|
+
## 排序与性能(v1.6.0)
|
|
80
|
+
|
|
81
|
+
内容命中按 **BM25F 相关度重排**(实现文件不再被文档顺带提及淹没),池子按
|
|
82
|
+
**文件轮转配额**(每文件 ≤8 行);文件名场景用 **fzf FuzzyMatchV2** 评分。
|
|
83
|
+
确定性不变:与 rg 发射序无关,并列分按 (路径,行号)。
|
|
84
|
+
|
|
85
|
+
大树上的内容搜索可开 **FTS5 索引快路**:`ARGO_LOCAL_FTS=1`(默认关),
|
|
86
|
+
首次对该目录先跑 `scripts/seek_fts.py rebuild <目录>` 预热,之后毫秒级返回;
|
|
87
|
+
rg 永远兜底(索引未建成/带正则/零命中时自动回退)。明细见
|
|
88
|
+
references/auto-behaviors.md。
|
|
89
|
+
|
|
90
|
+
逃生门(默认行为已是最优,仅在回退/实验时用):
|
|
91
|
+
- `ARGO_SEEK_CONTENT_RERANK=0` 关闭内容重排,恢复 (路径,行号) 原序
|
|
92
|
+
- `ARGO_SEEK_FRECENCY=1` 开启访问频次加成(实验项,默认关)
|
|
93
|
+
- 排序质量用 `scripts/eval_rank.py` 评测(MRR/耗时,支持 --compare)
|
|
94
|
+
|
|
95
|
+
## 配置
|
|
96
|
+
|
|
97
|
+
排除规则与知识域:`sub-skills/local-seek/config/domains.yaml`
|
|
98
|
+
查看当前规则:`python3 sub-skills/local-seek/scripts/seek.py --domains`
|
|
99
|
+
|
|
100
|
+
## 参考
|
|
101
|
+
|
|
102
|
+
按场景的完整命令配方(进阶,非常规操作再读):
|
|
103
|
+
|
|
104
|
+
- references/rg-recipes.md — rg 分场景配方(函数定义/跨文件引用/多词/正则)
|
|
105
|
+
- references/auto-behaviors.md — 自动行为明细(重排/FTS/中文扩展/PCRE2/git)
|
|
106
|
+
- references/fd-mdfind-recipes.md — fd 与 Spotlight 配方
|
|
107
|
+
- references/strategies.md — 三层做法的详细说明,以及怎么少花 token
|
|
108
|
+
- references/structural-search.md — 结构搜索手册(语义规则表/别名/扩展新规则)
|
|
109
|
+
- references/git-integration.md — git 联动用法、场景与边界
|
|
110
|
+
- references/remote-handoff.md — 本地搜不到时的扩大与联网交接清单
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# local-seek 搜索配置
|
|
2
|
+
# 修改后即时生效,无需重启。
|
|
3
|
+
|
|
4
|
+
# 附加排除规则(追加到内置默认排除之后)
|
|
5
|
+
# 内置默认排除:node_modules .git __pycache__ .venv dist build target 等
|
|
6
|
+
exclude:
|
|
7
|
+
- "*.min.js"
|
|
8
|
+
- "*.map"
|
|
9
|
+
- "*.lock"
|
|
10
|
+
- ".turbo"
|
|
11
|
+
- ".nyc_output"
|
|
12
|
+
- "*.egg-info"
|
|
13
|
+
|
|
14
|
+
# 知识域:经常要搜的目录,填在这里可被 --domains 查询
|
|
15
|
+
# 示例:- ~/Documents/notes
|
|
16
|
+
knowledge_domains: []
|
|
17
|
+
|
|
18
|
+
# 输出控制
|
|
19
|
+
max_results: 30 # 默认最大结果数
|
|
20
|
+
snippet_chars: 120 # 命中行截断长度
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# seek.py 自动行为明细(按需读取)
|
|
2
|
+
|
|
3
|
+
这些行为全部自动生效,无需手动指定;排障或想理解「为什么这么搜」时再读。
|
|
4
|
+
从 SKILL.md 挪入(v1.6.0,触发即注入预算 7KB 的口径)。
|
|
5
|
+
|
|
6
|
+
- **固定字符串**:查询是纯字面量时自动用 rg -F;含 regex 元字符但解析失败
|
|
7
|
+
(如 interface{})自动回退 -F。
|
|
8
|
+
- **中文扩展**:中文查询先按原词精确匹配,没命中再拆成 2 字词(2-gram)放宽
|
|
9
|
+
(如「数据抓取」放宽到「数据」「抓取」),这样能多搜到一些;--exact 关闭。
|
|
10
|
+
- **PCRE2 检测**:查询含 look-around 时检查本机 rg 是否支持,不支持给出
|
|
11
|
+
明确提示而非报错。
|
|
12
|
+
- **结构搜索**:--structural 按语义检索代码模式(裸 except、空 catch、
|
|
13
|
+
装饰函数、函数/类定义),中英文别名都认,零安装(rg -U 多行实现)。
|
|
14
|
+
- **Git 联动**:--git-log / --git-blame 直接回答「这行谁改的、最近动过什么」,
|
|
15
|
+
文件不在仓库或未跟踪时给出明确区分,不报错。
|
|
16
|
+
- **BM25F 内容重排**:文件名 2.0 / 目录 0.6 / 行文本 1.0 三字段,BM25+ 下界 +
|
|
17
|
+
逐字短语加成 + 文件级命中数先验;池子按文件轮转配额(每文件 ≤8 行)。
|
|
18
|
+
`ARGO_SEEK_CONTENT_RERANK=0` 关闭。
|
|
19
|
+
- **fzf V2 文件名评分**:驼峰/边界/gap 惩罚,DP 最优对齐(junegunn/fzf 口径)。
|
|
20
|
+
- **FTS5 索引快路**:`ARGO_LOCAL_FTS=1` 后,无正则元字符的内容查询走
|
|
21
|
+
SQLite FTS5 倒排索引(unicode61 + CJK 逐字短语),只在索引过期(TTL 120s)
|
|
22
|
+
时付一次增量刷新(rg --files 清单 + 改动文件重读,预算 1.5s)。rg 永远
|
|
23
|
+
兜底:索引未建成/查询带正则/零命中语义见 seek_fts.py docstring。大树首次
|
|
24
|
+
建索引较慢,先跑 `python3 scripts/seek_fts.py rebuild <目录>` 预热。
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# fd 与 Spotlight(mdfind)配方
|
|
2
|
+
|
|
3
|
+
## fd — 按文件名查找
|
|
4
|
+
|
|
5
|
+
统一入口用 `seek.py "词" --filename`,手动配方:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 文件名模糊匹配(忽略大小写)
|
|
9
|
+
fd "login"
|
|
10
|
+
|
|
11
|
+
# 指定目录
|
|
12
|
+
fd "auth" ~/src
|
|
13
|
+
|
|
14
|
+
# 限定扩展名
|
|
15
|
+
fd -e py "schema"
|
|
16
|
+
fd -e md -e txt "notes"
|
|
17
|
+
|
|
18
|
+
# 只看目录
|
|
19
|
+
fd -t d "config"
|
|
20
|
+
|
|
21
|
+
# 隐藏文件
|
|
22
|
+
fd -H ".*rc"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
注意:fd 默认自动排除 .gitignore 中的内容,无需手动加 -E。
|
|
26
|
+
|
|
27
|
+
## mdfind — macOS Spotlight 全盘兜底
|
|
28
|
+
|
|
29
|
+
用系统预建索引,覆盖 rg 搜不到的东西(PDF 正文、邮件、已归档目录、图片元数据)。
|
|
30
|
+
统一入口用 `seek.py "词" --spotlight`。
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# 全盘搜索(走系统索引,毫秒级)
|
|
34
|
+
mdfind "关键词"
|
|
35
|
+
|
|
36
|
+
# 限定目录
|
|
37
|
+
mdfind -onlyin ~/Documents "关键词"
|
|
38
|
+
|
|
39
|
+
# 限定文件名
|
|
40
|
+
mdfind -name "report"
|
|
41
|
+
|
|
42
|
+
# 文件名+内容混合(kMDItem 查询语法)
|
|
43
|
+
mdfind "kMDItemFSName == '*.pdf' && 关键词"
|
|
44
|
+
|
|
45
|
+
# 只看最近修改
|
|
46
|
+
mdfind "kMDItemFSContentChangeDate >= $time.today(-7) 关键词"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 何时用 mdfind 而不是 rg
|
|
50
|
+
|
|
51
|
+
| 信号 | 用 |
|
|
52
|
+
|------|----|
|
|
53
|
+
| 全盘搜,不知道文件在哪 | mdfind |
|
|
54
|
+
| 搜 PDF/邮件/已归档内容 | mdfind |
|
|
55
|
+
| 目录未建立 Spotlight 索引(外接盘/网络盘) | 退回 rg + 明确 --path |
|
|
56
|
+
| 代码仓库内 | rg(永远优先) |
|
|
57
|
+
|
|
58
|
+
### 坑
|
|
59
|
+
|
|
60
|
+
- 外接盘、~/Library 部分目录可能未索引,mdfind 搜不到
|
|
61
|
+
- mdfind 的查询是「关键词匹配」,中文分词效果取决于系统
|
|
62
|
+
- 结果不带行号,定位到文件后需再 rg 找行
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Git 联动手册(--git-log / --git-blame)
|
|
2
|
+
|
|
3
|
+
本地搜索找到文件只是第一步,经常要接着回答「这行谁改的、为什么改、什么时候
|
|
4
|
+
改的」。git 联动让 seek.py 直接给出答案,不用再开终端敲 git。
|
|
5
|
+
|
|
6
|
+
## 用法
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# 文件的最近提交历史(默认 10 条,oneline)
|
|
10
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py --git-log 文件路径
|
|
11
|
+
|
|
12
|
+
# 某一行是谁在哪个提交改的
|
|
13
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py --git-blame 12 文件路径
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
文件路径作为位置参数(或 `--path`),两者互斥时位置参数优先。
|
|
17
|
+
|
|
18
|
+
## 输出示例
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
# --git-log
|
|
22
|
+
local-seek: seek.py 最近 3 条提交
|
|
23
|
+
cd02e96 补全结构搜索与 git 联动
|
|
24
|
+
a1b2c3d 中文扩展:空格噪音修复
|
|
25
|
+
|
|
26
|
+
# --git-blame 12
|
|
27
|
+
local-seek: seek.py 第 12 行
|
|
28
|
+
cd02e96f (taxueseek 2026-07-03 20:58:20 +0800 3) ap.add_argument("--git-blame"...
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 适用场景
|
|
32
|
+
|
|
33
|
+
| 场景 | 命令 | 读什么 |
|
|
34
|
+
|------|------|--------|
|
|
35
|
+
| 这文件最近在动什么 | --git-log | 提交标题序列 |
|
|
36
|
+
| 某行代码的来历 | --git-blame N | 提交哈希、作者、时间 |
|
|
37
|
+
| 拿到哈希后看完整改动 | --git-log 后再 `git -C 目录 show 哈希` | diff 正文 |
|
|
38
|
+
| 谁改坏了某段逻辑 | --git-blame 定位行 → show 对应提交 | 上下文 |
|
|
39
|
+
|
|
40
|
+
## 边界与局限
|
|
41
|
+
|
|
42
|
+
- **未跟踪文件**:untracked(从未 git add)的文件无历史,报「无提交历史」,
|
|
43
|
+
不是错误。把文件 git add 后即有。
|
|
44
|
+
- **仓库外文件**:不在任何 git 仓库内的文件报「不在 git 仓库中」。
|
|
45
|
+
- **行号漂移**:blame 按当前行号定位,改动过的文件行号会移动,属正常。
|
|
46
|
+
- **大文件历史**:--git-log 只读标题不看 diff,是低成本路径;要 diff 再手动
|
|
47
|
+
git show,不要指望 seek.py 输出正文。
|
|
48
|
+
- **子模块/符号链接**:git -C 父目录 对符号链接指向的仓库无效,需先解析真实路径。
|
|
49
|
+
|
|
50
|
+
## 与本地搜索的组合套路
|
|
51
|
+
|
|
52
|
+
1. 搜到文件里的目标行:`seek.py "关键词" --path ~/repo --max 5`
|
|
53
|
+
2. 定位关键行号后 blame:`seek.py --git-blame 行号 文件路径`
|
|
54
|
+
3. 拿提交哈希再看 diff:`git -C ~/repo show 哈希`
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# 本地搜不到时的交接(remote-handoff)
|
|
2
|
+
|
|
3
|
+
local-seek 只负责本机。本地无结果不意味着结束,按本清单逐步扩大,最后
|
|
4
|
+
交接给联网搜索。判断标准写死在每一步,避免无限折腾。
|
|
5
|
+
|
|
6
|
+
## 交接顺序(每步只做一次,失败即进下一步)
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
L1 当前目录 rg 搜索(默认)
|
|
10
|
+
↓ 无命中
|
|
11
|
+
L2 --path 扩大到知识域(~/notes、~/Documents、技能库等)
|
|
12
|
+
↓ 无命中
|
|
13
|
+
L3 --spotlight 全盘兜底(mdfind,走 macOS 索引,覆盖 PDF/邮件/笔记)
|
|
14
|
+
↓ 无命中
|
|
15
|
+
L4 换词重试 1 次(同义词/拆词/去掉修饰词),仍无
|
|
16
|
+
↓
|
|
17
|
+
L5 交接联网:unified-search(多引擎聚合)或 argo(深度研究)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 判断标准
|
|
21
|
+
|
|
22
|
+
| 现象 | 结论 | 动作 |
|
|
23
|
+
|------|------|------|
|
|
24
|
+
| L1-L3 均无命中 | 本机确实没有,或不在已索引范围 | 进 L4 |
|
|
25
|
+
| 换词后仍无 | 大概率是「没有这个内容」而非「没找到」 | 进 L5 |
|
|
26
|
+
| L5 联网也无 | 内容不存在或太新未收录 | 如实告知,停止搜索 |
|
|
27
|
+
| 命中但太少/太泛 | 不是交接问题,是词选得不好 | 回到 L2/L4 调整 |
|
|
28
|
+
|
|
29
|
+
## 交接命令
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 本地最后一搏
|
|
33
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py "关键词" --spotlight
|
|
34
|
+
|
|
35
|
+
# 联网:unified-search(多引擎,快)
|
|
36
|
+
# 联网:argo 深度研究(学术/金融领域,带信源核验)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 纪律
|
|
40
|
+
|
|
41
|
+
- **禁止无限扩大**:每层只试一次,最多一轮换词,两轮无果就交接或停止。
|
|
42
|
+
- **交接前确认需求边界**:用户要的是「我电脑里的文件」就别接出网;
|
|
43
|
+
要的是「这个事实/最新信息」就该直接联网,不必先搜本地。
|
|
44
|
+
- **本地与联网并行**:需求两可时并行调用,互不阻塞,先到的先答。
|
|
45
|
+
- **不把联网结果当本地文件**:交接后答案来自网络,措辞上要区分来源,
|
|
46
|
+
需要文件路径的请求不能用网页内容冒充。
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# rg 分场景配方
|
|
2
|
+
|
|
3
|
+
统一入口 `seek.py` 已覆盖多数场景,以下配方用于非常规操作或手动微调。
|
|
4
|
+
所有命令均尊重 .gitignore,自动排除 node_modules 等(见 config/domains.yaml)。
|
|
5
|
+
|
|
6
|
+
## 基础
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# 全文搜(当前目录)
|
|
10
|
+
rg "关键词"
|
|
11
|
+
|
|
12
|
+
# 指定目录
|
|
13
|
+
rg "关键词" ~/notes
|
|
14
|
+
|
|
15
|
+
# 忽略大小写
|
|
16
|
+
rg -i "keyword"
|
|
17
|
+
|
|
18
|
+
# 正则
|
|
19
|
+
rg "func[0-9]+\(" src/
|
|
20
|
+
|
|
21
|
+
# 固定字符串(避免正则转义,含特殊字符时用)
|
|
22
|
+
rg -F "a.b[c]" .
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 定位类
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# 只看文件名(最省 token,先看分布)
|
|
29
|
+
rg -l "关键词" .
|
|
30
|
+
rg --files-with-matches "关键词" .
|
|
31
|
+
|
|
32
|
+
# 每文件命中数(先数后看)
|
|
33
|
+
rg --count-matches "关键词" .
|
|
34
|
+
|
|
35
|
+
# 只看行号不输出内容
|
|
36
|
+
rg -l --line-number "关键词" .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 上下文类
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# 前后 N 行
|
|
43
|
+
rg -C 2 "关键词" .
|
|
44
|
+
rg -A 3 "关键词" . # 只后文
|
|
45
|
+
rg -B 1 "关键词" . # 只前文
|
|
46
|
+
|
|
47
|
+
# 输出到文件避免刷屏(超大批量时)
|
|
48
|
+
rg "关键词" . > /tmp/rg_out.txt
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 类型过滤
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# 按扩展名
|
|
55
|
+
rg -g "*.py" "关键词" .
|
|
56
|
+
rg -g "*.{py,ts,js}" "关键词" .
|
|
57
|
+
|
|
58
|
+
# 排除
|
|
59
|
+
rg -g "!test_*" "关键词" .
|
|
60
|
+
rg -g "!*.min.js" "关键词" .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 常用语义场景
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# 函数/类定义在哪
|
|
67
|
+
rg -n "def handle_request|class AuthService" src/
|
|
68
|
+
# 跨语言:rg "function (getUser|setUser)" .
|
|
69
|
+
|
|
70
|
+
# 跨文件引用(谁在调用某函数)
|
|
71
|
+
rg "send_email\(" .
|
|
72
|
+
|
|
73
|
+
# TODO/FIXME 盘点
|
|
74
|
+
rg -n "TODO|FIXME|HACK" --type-add 'todo:*.{py,js,ts,go,rs}' -t todo .
|
|
75
|
+
|
|
76
|
+
# 只搜中文
|
|
77
|
+
rg -n "[\u4e00-\u9fff]" .
|
|
78
|
+
|
|
79
|
+
# 找 JSON/YAML 里的键
|
|
80
|
+
rg -n '"max_results"' config/
|
|
81
|
+
|
|
82
|
+
# 日志排查(最近日志)
|
|
83
|
+
rg "ERROR|panic" --glob "*.log" .
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 性能
|
|
87
|
+
|
|
88
|
+
- 大仓库先 `--count` 或 `-l`,避免输出千行
|
|
89
|
+
- 指定 `-g` 类型或目录,rg 只扫必要范围
|
|
90
|
+
- 超过 30s 无结果:换词或换 mdfind(--spotlight),不要重复等待
|
|
91
|
+
- rg 退出码:0=有匹配,1=无匹配,2=报错。脚本已处理,手动用时注意
|
|
92
|
+
|
|
93
|
+
## 非代码文件(可选扩展)
|
|
94
|
+
|
|
95
|
+
rga(ripgrep-all)未安装时可临时用 mdfind 覆盖 PDF/Office 场景;
|
|
96
|
+
若常搜这类文件,装 rga:`brew install ripgrep-all`
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 渐进式策略与 token 纪律
|
|
2
|
+
|
|
3
|
+
本 skill 的核心不是「更快地搜索」,而是「用最少的 token 拿到答案」。
|
|
4
|
+
工具输出就是压缩结果,模型不该有探索成本。
|
|
5
|
+
|
|
6
|
+
## 三层渐进(永远按此顺序)
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
L1 定位 seek.py "词" --count / --filename
|
|
10
|
+
→ 输出「文件:命中数」或文件路径列表,每行 < 80 字符
|
|
11
|
+
↓ 从中挑出最相关的 1-3 个文件
|
|
12
|
+
L2 上下文 seek.py "词" --context 2 --path <该文件所在目录>
|
|
13
|
+
→ 输出「路径:行号:命中行 ± 2 行」
|
|
14
|
+
↓ 确定要精读的段落
|
|
15
|
+
L3 精读 read_file 该文件,用行号偏移局部读取
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
任何一步已经能回答用户,就停。不要为完整性多搜。
|
|
19
|
+
|
|
20
|
+
## 搜索范围扩大的顺序(先窄后宽)
|
|
21
|
+
|
|
22
|
+
1. 当前目录 + 默认排除(最常命中)
|
|
23
|
+
2. `--path` 扩大到知识域(~/notes、~/Documents 等,见 domains.yaml)
|
|
24
|
+
3. `--spotlight` 全盘兜底
|
|
25
|
+
|
|
26
|
+
禁止跳级:用户问「找代码里某个函数」却直接 mdfind 全盘,浪费且不准。
|
|
27
|
+
|
|
28
|
+
## 输出量控制
|
|
29
|
+
|
|
30
|
+
| 手段 | 效果 |
|
|
31
|
+
|------|------|
|
|
32
|
+
| `--max 20` | 截断结果数,防止刷屏 |
|
|
33
|
+
| `--count` | 只报分布,不报内容 |
|
|
34
|
+
| `--type py,ts` | 只扫目标类型 |
|
|
35
|
+
| `--context 0`(默认) | 不输出上下文行 |
|
|
36
|
+
| `-l` 手动模式 | 只列文件名 |
|
|
37
|
+
|
|
38
|
+
## 常见失败与换词策略
|
|
39
|
+
|
|
40
|
+
| 现象 | 处理 |
|
|
41
|
+
|------|------|
|
|
42
|
+
| 无匹配 | 换同义词/拆词/去掉修饰词,重试 1 次后换工具 |
|
|
43
|
+
| 命中过多 | 加 `--type` / `--max` / 更具体的关键词(加引号做短语匹配) |
|
|
44
|
+
| 结果太泛 | 指定目录缩小范围 |
|
|
45
|
+
| 搜代码但命中注释/文档 | 换更精确的符号名或结构模式 |
|
|
46
|
+
| Spotlight 搜不到 | 确认目录已索引;退回 rg + 明确 --path |
|
|
47
|
+
|
|
48
|
+
## 与 Argo 的分工
|
|
49
|
+
|
|
50
|
+
- 用户要「网上查」→ argo(联网)
|
|
51
|
+
- 用户要「本地找/搜我的文件」→ local-seek
|
|
52
|
+
- 混合需求(如「查网上的同时翻本地笔记」)→ 并行调用,互不干扰
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# 结构搜索手册(--structural)
|
|
2
|
+
|
|
3
|
+
按「语义」而非「字符串」检索代码模式:找裸 except、空 catch、装饰函数这类
|
|
4
|
+
「看着就知道有问题/有特征」的结构。零安装实现:rg -U 多行匹配 + 语言感知
|
|
5
|
+
pattern,本机装 ast-grep 后可升级为 AST 精确匹配(见文末)。
|
|
6
|
+
|
|
7
|
+
## 用法
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 按语义名或中文别名检索,输出同普通搜索(路径:行号:片段)
|
|
11
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py "裸except" --structural
|
|
12
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py "empty-catch" --structural --path ~/repo
|
|
13
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py "函数定义" --structural --path ~/repo --type py
|
|
14
|
+
python3 ~/.agents/skills/argo/sub-skills/local-seek/scripts/seek.py "不存在语义" --structural # 报可用列表
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
查询词可写语义名(empty-catch)或任意中文别名(空catch、裸异常),大小写不敏感。
|
|
18
|
+
|
|
19
|
+
## 内置规则
|
|
20
|
+
|
|
21
|
+
| 语义名 | 中文别名 | 查什么 | 覆盖语言 |
|
|
22
|
+
|--------|---------|--------|---------|
|
|
23
|
+
| empty-catch | 空catch、空捕获、空异常处理 | `catch (...) {}` 空体 | js/jsx/ts/tsx |
|
|
24
|
+
| bare-except | 裸except、无类型except | `except:` 无异常类型 | py |
|
|
25
|
+
| unwrapped-error | 错误未包装、裸return err | `return err` 直接返回错误 | go |
|
|
26
|
+
| decorated-fn | 装饰函数、装饰器函数 | 带 `@decorator` 的函数定义 | py |
|
|
27
|
+
| function-def | 函数定义、找函数 | 函数定义行 | py/js/ts/go/rs |
|
|
28
|
+
| class-def | 类定义、找类 | 类/结构体定义行 | py/js/ts/go/java |
|
|
29
|
+
|
|
30
|
+
## 实现说明
|
|
31
|
+
|
|
32
|
+
- 每条规则 = 若干 (扩展名集合, 正则) 对,逐语言跑 `rg -U -i --line-number`。
|
|
33
|
+
- `-U` 启用多行模式,decorated-fn 才能跨行匹配 `@装饰器\n def`。
|
|
34
|
+
- 语言无命中(rg 退出码 1)静默跳过,不报错。
|
|
35
|
+
- 与正文搜索共用排除规则(domains.yaml + --exclude)。
|
|
36
|
+
- 局限:正则近似,非真实 AST。缩进风格怪异的代码、嵌套场景可能漏报;
|
|
37
|
+
`catch {}` 内只有注释也算空体(正则按字面空体判断)。
|
|
38
|
+
|
|
39
|
+
## 扩展新规则
|
|
40
|
+
|
|
41
|
+
在 seek.py 的 `STRUCTURAL_RULES` 字典追加一条:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
"todo-count": {
|
|
45
|
+
"aliases": ("待办统计", "todo盘点"),
|
|
46
|
+
"patterns": [
|
|
47
|
+
(("py", "js", "ts"), r"TODO|FIXME|HACK"),
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
规则键即语义名,aliases 提供中文入口,patterns 按语言给正则。
|
|
53
|
+
加完跑 `python3 scripts/eval_seek.py` 确认无回归,再补一条结构用例。
|
|
54
|
+
|
|
55
|
+
## 升级路径(装 ast-grep 后)
|
|
56
|
+
|
|
57
|
+
ast-grep 能精确匹配 AST 节点(真·空 catch 块、未捕获的裸 except),
|
|
58
|
+
消除正则的漏报误报。届时在 structural_search 里检测 `sg` 命令存在则优先
|
|
59
|
+
AST,缺失时回落当前 rg -U 实现,行为对调用方透明。
|