Not in the top 1,000 by GitHub stars
aigclink/geolook
Open-source end-to-end GEO implementation: status analysis, diagnosis, strategy, tickets, execution, verification
History
Review weekly changes to SKILL.md before updating. Dates mark the weeks in which we observed each version; checks apply to the recorded commits.
View weekly changes
SKILL.md
Week of Nov 2, 2026 · +0 / −0 lines
Before Network or broad shell → After Network or broad shell
9492cb3a1952 → 9492cb3a1952
Week of Oct 26, 2026 · Line counts unavailable
Before Not checked yet → After Network or broad shell
First observation → 9492cb3a1952
No earlier version was observed for comparison.
Heat
3.9- Star growth, last 7 daysNot available
- Star growth, last 24 hoursNot available
- Rank movement, last 7 daysNot available
- Commits, last 30 daysNot available
- Accounts asking about it through MCP, last 7 daysNot available
- Hot votes this weekNot available
Heat never changes the order by stars, and sponsorship never touches it. How heat works
Stars over time
Individual skills in this repository
- geo
/
How it works
geo
When your agent uses it
完整的 GEO(生成式引擎优化)服务流水线:给一个产品官网 URL 和介绍材料, 做站点诊断与 AI 答案采样、生成带验收标准的执行工单、产出可直接部署的资产 (llms.txt / JSON-LD / 定义块 / FAQ / 内容大纲与初稿)、自动验收工单是否闭环、 并打包成可直接发给客户的交付物。可按周期复跑,做长期 GEO 运营与月报。 国内和海外双市场并行:国内覆盖 智谱GLM/豆包/DeepSeek/Kimi/MiniMax/纳米AI/百度AI, 海外覆盖 Gemini/ChatGPT/Claude/Grok/Perplexity,问题库与指标按市场分开算。 当用户说「做 GEO」「生成式引擎优化」「让 AI 推荐我的产品」「AI 搜索里搜不到我们」 「GEO 方案/诊断/监测/月报/交付」「给客户做 GEO 服务」,或给一个产品网址要做 AI 可见性优化时使用。GEO 指生成式引擎优化,不是地理信息; 不用于传统 SEO 关键词排名、竞价投放或建站。
What it loads into context
Frontmatter
293 tokensAlways available to the agent
SKILL.md
5,657 tokensWhen the skill is activated
Reference documents
37,804 tokensLoaded on request
Token counts are estimates. Scripts run separately; they are not counted as reference context.
The playbook
- 最快的用法:给一个网址
- 两种用法
- 先读什么
- 步骤 0 · 建项目
- 步骤 1 · 吃透产品,建事实底座
- 步骤 2 · 建问题库
- 无自有网站的项目(电商商品、线下品牌、小程序…)
- 每期循环(`serve` 自动做完,这里说明每步在干什么)
- 全部命令
- 排期自动执行
- 边界
- 目录
Scripts executed separately
extension/background.jsextension/content.jsextension/sandbox.shextension/sidepanel.jsextension/test/e2e.jsscripts/analytics.pyscripts/audit.pyscripts/benchmark.pyscripts/blueprint.pyscripts/bootstrap.pyscripts/crawl.pyscripts/dashboard.pyscripts/deliver.pyscripts/deliverables.pyscripts/expand.pyscripts/generate.pyscripts/geo.pyscripts/geolib.pyscripts/jobs.pyscripts/publish.pyscripts/report.pyscripts/sample.pyscripts/service.shscripts/tasks.pyscripts/verify.pytests/__init__.pytests/test_analytics.pytests/test_audit.pytests/test_bootstrap.pytests/test_crawl.pytests/test_dashboard.pytests/test_deliver.pytests/test_geolib.pytests/test_jobs.pytests/test_model_config.pytests/test_report.pytests/test_sample.pytests/test_tasks.pytests/test_ui.py
Files
.env.exampleasset929 bytes.gitignoreasset83 bytesLICENSEasset1,077 bytesREADME.ja.mddoc23,261 bytesREADME.mddoc20,365 bytesREADME.zh-CN.mddoc20,727 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesSKILL.mdcore19,274 bytesdocs/demo.en.gifasset1,233,489 bytesdocs/demo.en.mp4asset724,958 bytesdocs/demo.gifasset963,851 bytesdocs/demo.ja.gifasset1,215,818 bytesdocs/demo.ja.mp4asset719,118 bytesdocs/demo.mp4asset751,871 bytesdocs/logo.pngasset12,046 bytesdocs/screenshots-en/assets.pngasset120,527 bytesdocs/screenshots-en/channels.pngasset297,489 bytesdocs/screenshots-en/competitors.pngasset228,870 bytesdocs/screenshots-en/engines.pngasset216,939 bytesdocs/screenshots-en/facts.pngasset228,622 bytesdocs/screenshots-en/gaps.pngasset231,045 bytesdocs/screenshots-en/overview.pngasset208,597 bytesdocs/screenshots-en/plan.pngasset263,282 bytesdocs/screenshots-en/publishing.pngasset217,559 bytesdocs/screenshots-en/questions.pngasset240,718 bytesdocs/screenshots-en/samples.pngasset294,256 bytesdocs/screenshots-en/settings.pngasset221,166 bytesdocs/screenshots-en/siteaudit.pngasset217,415 bytesdocs/screenshots-en/verify.pngasset282,916 bytesdocs/screenshots-en/workbench.pngasset174,315 bytesdocs/screenshots-ja/assets.pngasset127,885 bytesdocs/screenshots-ja/channels.pngasset296,839 bytesdocs/screenshots-ja/competitors.pngasset235,471 bytesdocs/screenshots-ja/engines.pngasset247,028 bytesdocs/screenshots-ja/facts.pngasset248,342 bytesdocs/screenshots-ja/gaps.pngasset245,876 bytesdocs/screenshots-ja/overview.pngasset229,009 bytesdocs/screenshots-ja/plan.pngasset274,112 bytesdocs/screenshots-ja/publishing.pngasset234,903 bytesdocs/screenshots-ja/questions.pngasset284,816 bytesdocs/screenshots-ja/samples.pngasset308,424 bytesdocs/screenshots-ja/settings.pngasset235,814 bytesdocs/screenshots-ja/siteaudit.pngasset257,968 bytesdocs/screenshots-ja/verify.pngasset297,753 bytesdocs/screenshots-ja/workbench.pngasset188,298 bytesdocs/screenshots/assets.pngasset120,527 bytesdocs/screenshots/channels.pngasset297,489 bytesdocs/screenshots/competitors.pngasset228,870 bytesdocs/screenshots/engines.pngasset216,939 bytesdocs/screenshots/facts.pngasset228,622 bytesdocs/screenshots/gaps.pngasset231,045 bytesdocs/screenshots/overview.pngasset208,597 bytesdocs/screenshots/plan.pngasset263,282 bytesdocs/screenshots/publishing.pngasset217,559 bytesdocs/screenshots/questions.pngasset240,718 bytesdocs/screenshots/samples.pngasset294,256 bytesdocs/screenshots/settings.pngasset221,166 bytesdocs/screenshots/siteaudit.pngasset217,415 bytesdocs/screenshots/verify.pngasset282,916 bytesdocs/screenshots/workbench.pngasset174,315 bytesdocs/video-script.mddoc7,581 bytesextension/README.mddoc8,086 bytesextension/background.jsruns251 bytesextension/content.jsruns9,684 bytesextension/manifest.jsonasset1,469 bytesextension/sandbox.shruns6,848 bytesextension/sidepanel.htmlasset5,870 bytesextension/sidepanel.jsruns17,042 bytesextension/test/e2e.jsruns6,322 bytesextension/test/fixture.htmlasset3,192 bytesreferences/attribution.mddoc3,780 bytesreferences/cn-platforms.mddoc7,620 bytesreferences/cn-source-ranking.mddoc8,147 bytesreferences/content-patterns.mddoc5,248 bytesreferences/global-platforms.mddoc4,639 bytesreferences/method.mddoc14,682 bytesreferences/sources.mddoc4,769 bytesscripts/analytics.pyruns24,032 bytesscripts/audit.pyruns26,581 bytesscripts/benchmark.pyruns4,087 bytesscripts/blueprint.pyruns18,347 bytesscripts/bootstrap.pyruns16,255 bytesscripts/crawl.pyruns16,444 bytesscripts/dashboard.pyruns37,831 bytesscripts/deliver.pyruns22,590 bytesscripts/deliverables.pyruns19,969 bytesscripts/expand.pyruns12,909 bytesscripts/generate.pyruns27,046 bytesscripts/geo.pyruns24,329 bytesscripts/geolib.pyruns17,736 bytesscripts/jobs.pyruns8,995 bytesscripts/publish.pyruns18,541 bytesscripts/report.pyruns19,424 bytesscripts/sample.pyruns42,979 bytesscripts/service.shruns3,029 bytesscripts/tasks.pyruns28,505 bytesscripts/ui.htmlasset304,344 bytesscripts/verify.pyruns16,090 bytestests/__init__.pyruns0 bytestests/test_analytics.pyruns7,660 bytestests/test_audit.pyruns9,506 bytestests/test_bootstrap.pyruns5,450 bytestests/test_crawl.pyruns4,253 bytestests/test_dashboard.pyruns1,530 bytestests/test_deliver.pyruns5,420 bytestests/test_geolib.pyruns5,131 bytestests/test_jobs.pyruns4,350 bytestests/test_model_config.pyruns5,137 bytestests/test_report.pyruns3,686 bytestests/test_sample.pyruns6,497 bytestests/test_tasks.pyruns3,968 bytestests/test_ui.pyruns868 bytes
Read SKILL.md
# GEO 全流程服务
从**诊断**到**交付**的完整链路,不只是给建议:
```
抓取 → 体检 → AI答案采样 → 生成工单 → 产出资产 → 报告 → 自动验收 → 客户交付包
```
核心判断只有一句:**GEO 的终点不是排名,是 AI 答案里那句话是不是按你的口径说的。**
所以最小单位不是页面,是**可被抽取的事实块**。
项目目录:`/Users/brucejan/geo`,每个客户/产品一个 `work/<slug>/`。
---View the complete source on GitHubSkills included
- geo
Repository facts
- License
- MIT
- Created
- Jul 29, 2026
- Last pushed
- Aug 10, 2026
- Forks
- 205
- Open issues
- 3
- Project activity
- Slowing
Rank over the last 12 weeks
Now #990 · best #756 · down 234 in 30 days
- #813 on Oct 18
- #857 on Oct 19
- #866 on Oct 20
- #881 on Oct 21
- #865 on Oct 23
- #990 since Oct 25
67 earlier periods
- #864 on Aug 2
- #833 from Aug 7 to Aug 9
- #867 on Aug 10
- #862 on Aug 11
- #858 on Aug 12
- #860 on Aug 13
- #842 on Aug 14
- #810 on Aug 15
- #831 on Aug 16
- #833 on Aug 17
- #847 on Aug 18
- #832 on Aug 19
- #820 on Aug 20
- #821 on Aug 21
- #769 on Aug 22
- #825 on Aug 23
- #832 on Aug 24
- #839 on Aug 25
- #821 on Aug 26
- #829 on Aug 27
- #861 on Aug 28
- #781 on Aug 29
- #785 on Aug 30
- #820 on Aug 31
- #841 on Sep 1
- #810 on Sep 2
- #820 on Sep 3
- #788 on Sep 4
- #766 on Sep 5
- #794 on Sep 6
- #810 on Sep 7
- #835 on Sep 8
- #815 on Sep 9
- #819 on Sep 10
- #796 on Sep 11
- #787 on Sep 13
- #813 on Sep 14
- #807 on Sep 15
- #818 from Sep 16 to Sep 17
- #800 on Sep 18
- #774 on Sep 19
- #790 on Sep 20
- #808 on Sep 21
- #831 on Sep 22
- #815 on Sep 23
- #785 on Sep 24
- #756 on Sep 25
- #768 on Sep 26
- #792 on Sep 27
- #815 on Sep 28
- #839 on Sep 29
- #822 on Sep 30
- #772 on Oct 1
- #785 on Oct 2
- #769 on Oct 3
- #812 on Oct 5
- #813 on Oct 6
- #830 on Oct 7
- #874 on Oct 8
- #837 on Oct 9
- #819 on Oct 10
- #814 on Oct 11
- #838 on Oct 12
- #841 on Oct 13
- #852 on Oct 14
- #835 on Oct 15
- #824 on Oct 17
Before you install
Network or broad shellAutomated signals, not a guarantee
Checked Nov 4, 2026
Not fully analyzed: some files were too long, unreadable or missing. This never lowers the level.
Show 9 notes
SKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzedSKILL.md:1Analysis incomplete: Referenced executable target unavailable; not analyzed
- No broad tool permissions
- 4 dangerous shell commandsin 2 files: extension/sandbox.sh:90 scripts/service.sh:60
- 406 network referencesin 35 files: scripts/publish.py:35 scripts/sample.py:35 tests/test_audit.py:12 and 32 more
- No hidden or obfuscated text
- No instruction overrides
- 39 executable scriptsin 39 files: extension/background.js:1 extension/content.js:1 extension/sandbox.sh:1 and 36 more
- 112 references to secretsin 19 files: scripts/publish.py:24 tests/test_model_config.py:26 scripts/sample.py:41 and 16 more
- No requests to vote in Hot
Show all 561 signals by file
.env.example
- Access to secretsline 6
[Credential-related source omitted] - Access to secretsline 7
[Credential-related source omitted] - Access to secretsline 8
[Credential-related source omitted] - Access to secretsline 9
[Credential-related source omitted] - Access to secretsline 10
[Credential-related source omitted] - Access to secretsline 13
[Credential-related source omitted] - Access to secretsline 14
[Credential-related source omitted] - Access to secretsline 15
[Credential-related source omitted] - Access to secretsline 16
[Credential-related source omitted] - Access to secretsline 17
[Credential-related source omitted]
.gitignore
- Access to secretsline 5
[Credential-related source omitted]
README.ja.md
- Network accessline 11
    · 🔍 [ライブデモ(読み取り専用)](https://geolook.cc/demo/) · 📹 [HD デモ動画 (mp4)](docs/demo.ja.mp4) · 🖼 [全スクリーンショット](docs/screenshots-ja/) - Network accessline 91
# 1. クローンしてインストール git clone https://github.com/aigclink/geolook.git - Network accessline 92
git clone https://github.com/aigclink/geolook.git cd geolook pip3 install requests beautifulsoup4 lxml - Network accessline 96
# 2. ダッシュボードを起動(ブラウザが開きます) python3 scripts/geo.py ui # → http://127.0.0.1:8765 - Network accessline 97
python3 scripts/geo.py ui # → http://127.0.0.1:8765 - Access to secretsline 100
[Credential-related source omitted] - Access to secretsline 101
[Credential-related source omitted] - Network accessline 111
# 方法 A(推奨):SSH トンネル。ポートを公開しない ssh -N -L 8765:127.0.0.1:8765 user@your-server # その後ローカルで http://127.0.0.1:8765 を開く - Network accessline 112
ssh -N -L 8765:127.0.0.1:8765 user@your-server # その後ローカルで http://127.0.0.1:8765 を開く - Access to secretsline 115
[Credential-related source omitted] - Network accessline 116
[Credential-related source omitted] - Network accessline 117
[Credential-related source omitted] - Network accessline 118
[Credential-related source omitted] - Access to secretsline 127
[Credential-related source omitted] - Network accessline 135
python3 scripts/geo.py new --url https://example.com --market both - Network accessline 232
- [@yaojingang](https://github.com/yaojingang) - Network accessline 236
質問・提案・コラボレーションは [bingqiang2008@gmail.com](mailto:bingqiang2008@gmail.com) まで。[issue](https://github.com/aigclink/geolook/issues) も歓迎。
README.md
- Network accessline 11
    · 🔍 [Live demo (read-only)](https://geolook.cc/demo/) · 📹 [HD demo video (mp4)](docs/demo.en.mp4) · 🖼 [All screenshots](docs/screenshots-en/) - Network accessline 19
<sub>Mirror while DNS propagates: [geolook.cc](https://geolook.cc) · [demo](https://geolook.cc/demo/)</sub> - Access to secretsline 63
[Credential-related source omitted] - Network accessline 93
# 1. Clone and install git clone https://github.com/aigclink/geolook.git - Network accessline 94
git clone https://github.com/aigclink/geolook.git cd geolook pip3 install requests beautifulsoup4 lxml - Network accessline 98
# 2. Start the dashboard (opens your browser) python3 scripts/geo.py ui # → http://127.0.0.1:8765 - Network accessline 99
python3 scripts/geo.py ui # → http://127.0.0.1:8765 - Access to secretsline 105
[Credential-related source omitted] - Network accessline 115
# Option A (recommended): SSH tunnel, no port exposed ssh -N -L 8765:127.0.0.1:8765 user@your-server # then open http://127.0.0.1:8765 locally - Network accessline 116
ssh -N -L 8765:127.0.0.1:8765 user@your-server # then open http://127.0.0.1:8765 locally - Access to secretsline 119
[Credential-related source omitted] - Network accessline 120
[Credential-related source omitted] - Network accessline 121
[Credential-related source omitted] - Network accessline 122
[Credential-related source omitted] - Network accessline 139
python3 scripts/geo.py new --url https://example.com --market both - Network accessline 239
- [@yaojingang](https://github.com/yaojingang) - Network accessline 243
Questions, ideas or collaboration — email [bingqiang2008@gmail.com](mailto:bingqiang2008@gmail.com), or open an [issue](https://github.com/aigclink/geolook/issues).
README.zh-CN.md
- Network accessline 11
    · 🔍 [在线演示(只读)](https://geolook.cc/demo/) · 📹 [高清演示视频 (mp4)](docs/demo.mp4) · 🖼 [全部截图](docs/screenshots/) - Network accessline 19
<sub>域名生效前可用镜像:[geolook.cc](https://geolook.cc) · [演示](https://geolook.cc/demo/)</sub> - Network accessline 117
# 1. 克隆并安装依赖 git clone https://github.com/aigclink/geolook.git - Network accessline 118
git clone https://github.com/aigclink/geolook.git cd geolook pip3 install requests beautifulsoup4 lxml - Network accessline 122
# 2. 启动看板(自动打开浏览器) python3 scripts/geo.py ui # → http://127.0.0.1:8765 - Network accessline 123
python3 scripts/geo.py ui # → http://127.0.0.1:8765 - Access to secretsline 128
[Credential-related source omitted] - Access to secretsline 129
[Credential-related source omitted] - Network accessline 139
# 方式 A(推荐):SSH 隧道,不暴露任何端口 ssh -N -L 8765:127.0.0.1:8765 user@your-server # 然后本地浏览器打开 http://127.0.0.1:8765 - Network accessline 141
# 然后本地浏览器打开 http://127.0.0.1:8765 - Access to secretsline 144
[Credential-related source omitted] - Network accessline 145
[Credential-related source omitted] - Network accessline 146
[Credential-related source omitted] - Network accessline 147
[Credential-related source omitted] - Network accessline 164
python3 scripts/geo.py new --url https://example.com --market both - Network accessline 272
- [@yaojingang](https://github.com/yaojingang) - Network accessline 276
问题、建议或合作:邮箱 [bingqiang2008@gmail.com](mailto:bingqiang2008@gmail.com),或提 [issue](https://github.com/aigclink/geolook/issues)。
SKILL.md
- Network accessline 34
python3 scripts/geo.py new --url https://example.com --market both - Network accessline 57
python3 scripts/geo.py ui # 默认 http://127.0.0.1:8765(前台运行) - Access to secretsline 175
[Credential-related source omitted] - Access to secretsline 176
[Credential-related source omitted] - Access to secretsline 177
[Credential-related source omitted] - Access to secretsline 178
[Credential-related source omitted] - Access to secretsline 179
[Credential-related source omitted] - Access to secretsline 180
[Credential-related source omitted] - Access to secretsline 181
[Credential-related source omitted] - Access to secretsline 182
[Credential-related source omitted] - Access to secretsline 183
[Credential-related source omitted] - Access to secretsline 184
[Credential-related source omitted]
extension/README.md
- Network accessline 24
- **不后台采集、不定时任务**。后台脚本只有一行「点图标开侧栏」,一切动作由你在侧栏发起, 关掉侧栏什么都不会发生。 - **数据只进本机**。唯一的网络请求目标是 `http://127.0.0.1:8765`(你自己跑的 GeoLook 看板)。 - Network accessline 25
关掉侧栏什么都不会发生。 - **数据只进本机**。唯一的网络请求目标是 `http://127.0.0.1:8765`(你自己跑的 GeoLook 看板)。 无遥测、无远程代码、不上传任何数据到第三方。 - Network accessline 26
- **数据只进本机**。唯一的网络请求目标是 `http://127.0.0.1:8765`(你自己跑的 GeoLook 看板)。 - Access to secretsline 47
[Credential-related source omitted]
extension/background.js
- Executable scriptline 1
Executable file
extension/content.js
- Executable scriptline 1
Executable file - Network accessline 57
const NEWCHAT = { "chatgpt.com": "https://chatgpt.com/", - Network accessline 58
"chatgpt.com": "https://chatgpt.com/", - Network accessline 59
"chat.openai.com": "https://chat.openai.com/", - Network accessline 60
"claude.ai": "https://claude.ai/new", - Network accessline 61
"doubao.com": "https://www.doubao.com/chat/", - Network accessline 62
"perplexity.ai": "https://www.perplexity.ai/", - Network accessline 63
"gemini.google.com": "https://gemini.google.com/app", - Network accessline 64
"chatglm.cn": "https://chatglm.cn/main/alltoolsdetail", - Network accessline 65
"kimi.com": "https://kimi.com/", - Network accessline 66
"kimi.moonshot.cn": "https://kimi.moonshot.cn/", - Network accessline 67
"yuanbao.tencent.com": "https://yuanbao.tencent.com/chat/naQivTmsDa", - Network accessline 68
"metaso.cn": "https://metaso.cn/", - Network accessline 69
"wenxin.baidu.com": "https://wenxin.baidu.com/",
extension/manifest.json
- Network accessline 10
], "host_permissions": [ "http://127.0.0.1:8765/*" - Network accessline 11
"host_permissions": [ "http://127.0.0.1:8765/*" ], - Network accessline 12
"http://127.0.0.1:8765/*" - Network accessline 24
{ "matches": [ "https://chatgpt.com/*", - Network accessline 25
"matches": [ "https://chatgpt.com/*", "https://chat.openai.com/*", - Network accessline 26
"https://chatgpt.com/*", - Network accessline 27
"https://chat.openai.com/*", - Network accessline 28
"https://claude.ai/*", - Network accessline 29
"https://www.doubao.com/*", - Network accessline 30
"https://doubao.com/*", - Network accessline 31
"https://www.perplexity.ai/*", - Network accessline 32
"https://perplexity.ai/*", - Network accessline 33
"https://gemini.google.com/*", - Network accessline 34
"https://www.google.com/*", - Network accessline 35
"https://chatglm.cn/*", - Network accessline 36
"https://kimi.com/*", - Network accessline 37
"https://www.kimi.com/*", - Network accessline 38
"https://kimi.moonshot.cn/*", - Network accessline 39
"https://yuanbao.tencent.com/*", - Network accessline 40
"https://yiyan.baidu.com/*", - Network accessline 41
"https://chat.baidu.com/*", - Network accessline 42
"https://www.n.cn/*", - Network accessline 43
"https://bot.n.cn/*", - Network accessline 44
"https://metaso.cn/*", - Network accessline 45
"https://wenxin.baidu.com/*"
extension/sandbox.sh
- Executable scriptline 1
#!/usr/bin/env bash - Network accessline 5
# ./sandbox.sh 一次性沙箱:从模板复制并清空站点数据,用完即弃 # ./sandbox.sh --keep 持久沙箱:登录态保留,必须登录的引擎用这个 # ./sandbox.sh --keep https://www.doubao.com/chat/ 直接打开某引擎 - Network accessline 6
# ./sandbox.sh --keep 持久沙箱:登录态保留,必须登录的引擎用这个 # ./sandbox.sh --keep https://www.doubao.com/chat/ 直接打开某引擎 # ./sandbox.sh --check 自检:模板、扩展、看板是否都就位 - Network accessline 7
# ./sandbox.sh --keep https://www.doubao.com/chat/ 直接打开某引擎 - Network accessline 81
echo "✗ 日常 Chrome 不支持自动装载扩展——跑 ./sandbox.sh --init 手动装一次"; RC=1 fi if curl -fsS -m 3 http://127.0.0.1:8765/api/projects >/dev/null 2>&1; then - Network accessline 82
fi if curl -fsS -m 3 http://127.0.0.1:8765/api/projects >/dev/null 2>&1; then echo "✓ 看板在线(127.0.0.1:8765)" - Network accessline 83
if curl -fsS -m 3 http://127.0.0.1:8765/api/projects >/dev/null 2>&1; then - Dangerous shell operationline 90
rm -rf "$TEMPLATE"; echo "模板已删除:$TEMPLATE(下次跑 --init 重建)"; exit 0 ;; - Dangerous shell operationline 136
trap 'rm -rf "$PROFILE"' EXIT - Access to secretsline 141
[Credential-related source omitted] - Dangerous shell operationline 144
rm -rf "$PROFILE/Default/$junk"
extension/sidepanel.html
extension/sidepanel.js
- Executable scriptline 1
Executable file - Network accessline 27
function serverUrl() { return $("#server").value.trim().replace(/\/$/, "") || "http://127.0.0.1:8765"; } - Network accessline 30
async function apiGet(path) { const r = await fetch(serverUrl() + path); - Network accessline 31
const r = await fetch(serverUrl() + path); - Network accessline 262
try { const nc = await chrome.tabs.sendMessage(RUN.tabId, { type: "geolook-newchat" }); - Network accessline 263
const nc = await chrome.tabs.sendMessage(RUN.tabId, { type: "geolook-newchat" }); - Network accessline 264
if (nc && nc.url) { await chrome.tabs.update(RUN.tabId, { url: nc.url }); await sleep(3500); } - Network accessline 310
if (!SAMPLES.length) { $("#upmsg").textContent = "还没有已采集的样本"; return; } try { const r = await fetch(`${serverUrl()}/api/collect/${slug()}`, { - Network accessline 311
try { const r = await fetch(`${serverUrl()}/api/collect/${slug()}`, { method: "POST", headers: { "Content-Type": "application/json" }, - Network accessline 312
const r = await fetch(`${serverUrl()}/api/collect/${slug()}`, {
extension/test/e2e.js
- Executable scriptline 1
Executable file - Network accessline 9
const CFT = os.homedir() + "/Library/Caches/ms-playwright/chromium-1228/chrome-mac-arm64/" + "Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"; const FIXTURE = "http://localhost:8614/test/fixture.html"; - Network accessline 10
"Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"; const FIXTURE = "http://localhost:8614/test/fixture.html"; const DASH = "http://127.0.0.1:8765"; - Network accessline 11
const FIXTURE = "http://localhost:8614/test/fixture.html"; - Network accessline 12
const DASH = "http://127.0.0.1:8765"; - Network accessline 19
fs.copyFileSync(path.join(SRC, f), path.join(dir, f)); const mf = JSON.parse(fs.readFileSync(path.join(dir, "manifest.json"), "utf8")); mf.content_scripts[0].matches.push("http://localhost:8614/*"); - Network accessline 20
const mf = JSON.parse(fs.readFileSync(path.join(dir, "manifest.json"), "utf8")); mf.content_scripts[0].matches.push("http://localhost:8614/*"); fs.writeFileSync(path.join(dir, "manifest.json"), JSON.stringify(mf, null, 2)); - Network accessline 21
mf.content_scripts[0].matches.push("http://localhost:8614/*"); - Network accessline 44
const pong = await sw.evaluate(async () => { const tabs = await chrome.tabs.query({ url: "http://localhost:8614/*" }); - Network accessline 45
const tabs = await chrome.tabs.query({ url: "http://localhost:8614/*" }); - Network accessline 100
console.log("【7】看板侧确认"); const r = await (await fetch(`${DASH}/api/samples/aigclink?limit=5`)).json(); - Network accessline 101
const r = await (await fetch(`${DASH}/api/samples/aigclink?limit=5`)).json();
extension/test/fixture.html
- Network accessline 40
]; const CITES = [ ["https://zhuanlan.zhihu.com/p/000000", "AI 售前工具横评"], - Network accessline 41
const CITES = [ ["https://zhuanlan.zhihu.com/p/000000", "AI 售前工具横评"], ["https://blog.csdn.net/example/article/details/1", "方案自动生成实践"], - Network accessline 42
["https://zhuanlan.zhihu.com/p/000000", "AI 售前工具横评"], - Network accessline 43
["https://blog.csdn.net/example/article/details/1", "方案自动生成实践"], - Network accessline 44
["https://custom.aigclink.ai/", "AIGCLINK定制家 官网"],
references/cn-platforms.md
- Access to secretsline 103
[Credential-related source omitted] - Access to secretsline 104
[Credential-related source omitted] - Access to secretsline 105
[Credential-related source omitted] - Access to secretsline 113
[Credential-related source omitted] - Access to secretsline 114
[Credential-related source omitted]
references/cn-source-ranking.md
- Network accessline 141
# 数据(约 430KB,只需这一个 mart) curl -sLO https://raw.githubusercontent.com/yaojingang/geo-citation-lab/main/03-cn-geo-citation-dataset/data/marts/source_visibility.parquet - Network accessline 142
curl -sLO https://raw.githubusercontent.com/yaojingang/geo-citation-lab/main/03-cn-geo-citation-dataset/data/marts/source_visibility.parquet - Network accessline 143
curl -sLO https://raw.githubusercontent.com/yaojingang/geo-citation-lab/main/03-cn-geo-citation-dataset/data/reference/source_types.csv
references/content-patterns.md
- Network accessline 103
<script type="application/ld+json"> { "@context": "https://schema.org", - Network accessline 104
{ "@context": "https://schema.org", "@type": "Organization", - Network accessline 105
"@context": "https://schema.org", - Network accessline 107
"name": "品牌规范名", "alternateName": ["别名1", "别名2"], "url": "https://example.com", - Network accessline 108
"alternateName": ["别名1", "别名2"], "url": "https://example.com", "logo": "https://example.com/logo.png", - Network accessline 109
"url": "https://example.com", - Network accessline 110
"logo": "https://example.com/logo.png", - Network accessline 140
## 重要页面 - [产品总览](https://example.com/product): 一句话说明 - Network accessline 141
- [产品总览](https://example.com/product): 一句话说明 - Network accessline 142
- [价格](https://example.com/pricing): 一句话说明 - Network accessline 143
- [文档](https://docs.example.com): 一句话说明
references/global-platforms.md
references/sources.md
- Network accessline 10
| 资料 | 地址 | 什么时候用 | |---|---|---| | GEO Citation Lab(数据总仓) | https://github.com/yaojingang/geo-citation-lab | 要复算或查原始口径 | - Network accessline 11
|---|---|---| | GEO Citation Lab(数据总仓) | https://github.com/yaojingang/geo-citation-lab | 要复算或查原始口径 | | 海外跨平台实验 3 分钟速读 | `01-geo-experiment-data-report/QUICK_REPORT.md` | **最高性价比**,`method.md` 的数字主要来自这里 | - Network accessline 12
| GEO Citation Lab(数据总仓) | https://github.com/yaojingang/geo-citation-lab | 要复算或查原始口径 | - Network accessline 14
| 国内 AI 引用偏好数据集 CN-GEO | `03-cn-geo-citation-dataset/` | 查国内平台/信源分布,21.4 万条引用记录 | | 海外 AI 引用偏好数据集 | `01-geo-experiment-data-report/` | 做海外市场时的信源判据 | | 论文:Citation Selection → Absorption | https://arxiv.org/abs/2604.25707 | 海外三平台实验,`method.m - Network accessline 15
| 海外 AI 引用偏好数据集 | `01-geo-experiment-data-report/` | 做海外市场时的信源判据 | | 论文:Citation Selection → Absorption | https://arxiv.org/abs/2604.25707 | 海外三平台实验,`method.md` 第 2 节数字的出处 | | 论文:中文生成式搜索引用什么 | https://arxiv.org/pdf/2607.15771 | 国内四产品八界面,Web - Network accessline 16
| 论文:Citation Selection → Absorption | https://arxiv.org/abs/2604.25707 | 海外三平台实验,`method.md` 第 2 节数字的出处 | - Network accessline 17
| 论文:中文生成式搜索引用什么 | https://arxiv.org/pdf/2607.15771 | 国内四产品八界面,Web/App 差异的出处 | - Network accessline 24
git clone --depth 1 https://github.com/yaojingang/geo-citation-lab.git - Network accessline 27
单文件取:`https://raw.githubusercontent.com/yaojingang/geo-citation-lab/main/<路径>` - Network accessline 33
| 资料 | 地址 | 说明 | |---|---|---| | yao-geo-skills(21 个细分 skill) | https://github.com/yaojingang/yao-geo-skills | 需要某个环节的**更细方法**时去查对应 `skills/<id>/SKILL.md` | - Network accessline 34
|---|---|---| | yao-geo-skills(21 个细分 skill) | https://github.com/yaojingang/yao-geo-skills | 需要某个环节的**更细方法**时去查对应 `skills/<id>/SKILL.md` | | **GEORank**(开源 GEO 工作台) | https://github.com/yaojingang/GEORank | 见下方说明 | - Network accessline 35
| yao-geo-skills(21 个细分 skill) | https://github.com/yaojingang/yao-geo-skills | 需要某个环节的**更细方法**时去查对应 `skills/<id>/SKILL.md` | - Network accessline 36
| **GEORank**(开源 GEO 工作台) | https://github.com/yaojingang/GEORank | 见下方说明 | - Network accessline 37
| GEORankHub(官方演示站) | https://georankhub.com | 不想自建时的在线入口 | - Network accessline 38
| GEOFlow(开源 GEO 运营系统) | https://github.com/yaojingang/GEOFlow | 要上规模化内容生产/分发平台时才需要,Laravel + Docker | - Network accessline 39
| GEO 资源专题 | https://tok123.cc/collections/geo-resources-and-services | 工具与服务商索引 | - Network accessline 69
| 资料 | 地址 | |---|---| | 《国内生成式AI引用生态全景报告》 | https://doc.laoyao.cn/qty18p | - Network accessline 70
|---|---| | 《国内生成式AI引用生态全景报告》 | https://doc.laoyao.cn/qty18p | | 《信源偏好分析报告》 | https://doc.laoyao.cn/krgovd | - Network accessline 71
| 《国内生成式AI引用生态全景报告》 | https://doc.laoyao.cn/qty18p | - Network accessline 72
| 《信源偏好分析报告》 | https://doc.laoyao.cn/krgovd | - Network accessline 73
| 《GEO白皮书》 | https://yaojingang.feishu.cn/docx/Jv85dXAeZoKJ7exJi4Yc4Edrnhf | - Network accessline 74
| 《GEO红皮书》 | https://yaojingang.feishu.cn/wiki/Otqtw0HFbiNeCMkjKalcFkoJnpf | - Network accessline 75
| 《GEO蓝皮书》 | https://yaojingang.feishu.cn/wiki/MwkiwPDqCiHGwVk2uOtcNUlrnnf | - Network accessline 76
| 《GEO到底是什么》 | https://mp.weixin.qq.com/s/GXuu0Hku-j-8ona5yzQSvA | - Network accessline 77
| 《从SEO到GEO,从流量到Agent》 | https://mp.weixin.qq.com/s/2P_zSjJkybl-rAyZjMIQAw | - Network accessline 78
| 《从AI搜索逻辑到GEOFlow落地实战》 | https://mp.weixin.qq.com/s/8Lyrzux7WacHjiHx_P9Fbg | - Network accessline 79
| 《一文讲透GEO内容工程》 | https://mp.weixin.qq.com/s/0ZZ5je2-W83HY7RtmsYkJA |
scripts/analytics.py
- Executable scriptline 1
Executable file
scripts/audit.py
- Executable scriptline 1
Executable file
scripts/benchmark.py
- Executable scriptline 1
Executable file
scripts/blueprint.py
- Executable scriptline 1
Executable file
scripts/bootstrap.py
- Executable scriptline 1
Executable file
scripts/crawl.py
- Executable scriptline 1
Executable file - Network accessline 149
AI_UA_PROBES = { "GPTBot": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; " "GPTBot/1.2; +https://openai.com/gptbot", - Network accessline 150
"GPTBot": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; " "GPTBot/1.2; +https://openai.com/gptbot", "ClaudeBot": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; " - Network accessline 151
"GPTBot/1.2; +https://openai.com/gptbot", - Network accessline 153
"ClaudeBot/1.0; +claudebot@anthropic.com", "PerplexityBot": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; " "PerplexityBot/1.0; +https://perplexity.ai/perplexitybot", - Network accessline 154
"PerplexityBot": "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; " "PerplexityBot/1.0; +https://perplexity.ai/perplexitybot", "Bytespider": "Mozilla/5.0 (Linux; Android 5.0) AppleWebKit/537.36 (KHTM - Network accessline 155
"PerplexityBot/1.0; +https://perplexity.ai/perplexitybot", - Network accessline 191
if not G.robots_decision(groups, bot, "/")[0]: continue res = G.fetch(root, timeout=10, retries=0, ua=ua) - Network accessline 192
continue res = G.fetch(root, timeout=10, retries=0, ua=ua) probe[bot] = res["status"] - Network accessline 193
res = G.fetch(root, timeout=10, retries=0, ua=ua) - Network accessline 217
if bots_denied: robots_blocked.append({"url": u, "bots": bots_denied}) res = G.fetch(u, timeout=10, retries=0) - Network accessline 218
robots_blocked.append({"url": u, "bots": bots_denied}) res = G.fetch(u, timeout=10, retries=0) if res["status"] != 200: - Network accessline 219
res = G.fetch(u, timeout=10, retries=0) - Network accessline 247
elif "SSLError" in errors: lines.append("→ TLS 证书链问题:浏览器会自动补中间证书,Python 不会。" "用 https://www.ssllabs.com/ssltest/ 检查并补齐中间证书(Chain issues)") - Network accessline 248
lines.append("→ TLS 证书链问题:浏览器会自动补中间证书,Python 不会。" "用 https://www.ssllabs.com/ssltest/ 检查并补齐中间证书(Chain issues)") elif "ConnectionError" in errors or "ConnectTimeout" in errors or "ReadTimeout" in errors: - Network accessline 249
"用 https://www.ssllabs.com/ssltest/ 检查并补齐中间证书(Chain issues)") - Network accessline 286
home = G.fetch(root) - Network accessline 292
def crawl_one(i: int, u: str) -> dict: res = home if u.rstrip("/") == root else G.fetch(u) - Network accessline 293
res = home if u.rstrip("/") == root else G.fetch(u)
scripts/dashboard.py
- Executable scriptline 1
Executable file - Access to secretsline 208
[Credential-related source omitted] - Access to secretsline 215
[Credential-related source omitted] - Access to secretsline 217
[Credential-related source omitted] - Access to secretsline 403
[Credential-related source omitted] - Access to secretsline 409
[Credential-related source omitted] - Access to secretsline 411
[Credential-related source omitted] - Access to secretsline 770
[Credential-related source omitted] - Access to secretsline 771
[Credential-related source omitted] - Access to secretsline 774
[Credential-related source omitted] - Network accessline 777
threading.Thread(target=_monitor_loop, daemon=True).start() srv = ThreadingHTTPServer((host, port), Handler) url = f"http://{'127.0.0.1' if host == '0.0.0.0' else host}:{port}/" - Network accessline 778
srv = ThreadingHTTPServer((host, port), Handler) url = f"http://{'127.0.0.1' if host == '0.0.0.0' else host}:{port}/" G.info(f"看板已启动:{url}(Ctrl+C 退出)" - Network accessline 779
url = f"http://{'127.0.0.1' if host == '0.0.0.0' else host}:{port}/"
scripts/deliver.py
- Executable scriptline 1
Executable file
scripts/deliverables.py
- Executable scriptline 1
Executable file
scripts/expand.py
- Executable scriptline 1
Executable file - Network accessline 80
url = f"https://suggestion.baidu.com/su?wd={quote(q)}&ie=utf-8&oe=utf-8" r = requests.get(url, headers=UA, timeout=timeout) - Network accessline 81
r = requests.get(url, headers=UA, timeout=timeout) - Network accessline 88
url = (f"https://suggestqueries.google.com/complete/search" f"?client=firefox&hl={hl}&q={quote(q)}") r = requests.get(url, headers=UA, timeout=timeout) - Network accessline 89
f"?client=firefox&hl={hl}&q={quote(q)}") r = requests.get(url, headers=UA, timeout=timeout) data = json.loads(r.text) - Network accessline 90
r = requests.get(url, headers=UA, timeout=timeout)
scripts/generate.py
- Executable scriptline 1
Executable file - Network accessline 128
org = { "@context": "https://schema.org", "@type": "Organization", - Network accessline 129
"@context": "https://schema.org", "@type": "Organization", - Network accessline 142
app = { "@context": "https://schema.org", "@type": "SoftwareApplication", - Network accessline 143
"@context": "https://schema.org", "@type": "SoftwareApplication", - Network accessline 165
faq = {"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [ - Network accessline 170
article = { "@context": "https://schema.org", "@type": "Article", - Network accessline 171
"@context": "https://schema.org", "@type": "Article", - Network accessline 179
breadcrumb = {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [
scripts/geo.py
- Executable scriptline 1
#!/usr/bin/env python3 - Network accessline 4
python3 scripts/geo.py init --url https://example.com --name 品牌名 - Network accessline 64
name = a.name if not name and url: res = G.fetch(url) - Network accessline 65
if not name and url: res = G.fetch(url) if res["html"]: - Network accessline 66
res = G.fetch(url)
scripts/geolib.py
- Executable scriptline 1
Executable file - Access to secretsline 28
[Credential-related source omitted] - Access to secretsline 36
[Credential-related source omitted] - Network accessline 194
def fetch(url: str, timeout: int = 12, retries: int = 1, ua: str | None = None) -> dict: - Network accessline 210
headers["Accept"] = ("text/html,application/xhtml+xml,application/xml;" "q=0.9,image/avif,image/webp,*/*;q=0.8") r = requests.get( - Network accessline 211
"q=0.9,image/avif,image/webp,*/*;q=0.8") r = requests.get( url, - Network accessline 212
r = requests.get( - Network accessline 268
def fetch_text(url: str, timeout: int = 8) -> str: try: r = requests.get(url, timeout=timeout, headers={"User-Agent": UA}) - Network accessline 269
try: r = requests.get(url, timeout=timeout, headers={"User-Agent": UA}) if r.status_code == 200: - Network accessline 270
r = requests.get(url, timeout=timeout, headers={"User-Agent": UA})
scripts/jobs.py
scripts/publish.py
- Executable scriptline 1
Executable file - Access to secretsline 24
[Credential-related source omitted] - Access to secretsline 34
[Credential-related source omitted] - Network accessline 35
"cfg": [("repo", "owner/repo"), ("branch", "main"), ("dir", "docs/geo")], "note": "Contents API 提交 markdown 到你的仓库(配 Pages/静态站即上线)", "guide": {"url": 'https://github.com/settings/tokens', "steps": ['github.com/settings/tokens - Network accessline 36
"note": "Contents API 提交 markdown 到你的仓库(配 Pages/静态站即上线)", "guide": {"url": 'https://github.com/settings/tokens', "steps": ['github.com/settings/tokens 生成 Token(Fine-grained 或 classic 勾 repo 权限),只授权目标仓库', 'GITHUB_TOKEN 填生成的 token;rep - Network accessline 37
"guide": {"url": 'https://github.com/settings/tokens', "steps": ['github.com/settings/tokens 生成 Token(Fine-grained 或 classic 勾 repo 权限),只授权目标仓库', 'GITHUB_TOKEN 填生成的 token;repo 填 owner/repo,dir 是仓库内目录', '仓库开 GitHub Pages(Settings→Pages)后,文章提 - Network accessline 39
"wordpress": { "name": "WordPress", "market": "general", "env": ["WP_USER", "WP_APP_PASSWORD"], "cfg": [("site_url", "https://blog.example.com")], - Network accessline 40
"name": "WordPress", "market": "general", "env": ["WP_USER", "WP_APP_PASSWORD"], "cfg": [("site_url", "https://blog.example.com")], "note": "REST API 新建草稿文章,登录后台确认后再发布", - Network accessline 41
"cfg": [("site_url", "https://blog.example.com")], - Network accessline 42
"note": "REST API 新建草稿文章,登录后台确认后再发布", "guide": {"url": 'https://wordpress.org/documentation/article/application-passwords/', "steps": ['WP 后台 → 用户 → 个人资料 → 底部「应用程序密码」生成一个(需 WP 5.6+)', 'WP_USER 填登录用户名,WP_APP_PASSWORD 填生成的密码(含空格原样填)', - Network accessline 43
"guide": {"url": 'https://wordpress.org/documentation/article/application-passwords/', "steps": ['WP 后台 → 用户 → 个人资料 → 底部「应用程序密码」生成一个(需 WP 5.6+)', 'WP_USER 填登录用户名,WP_APP_PASSWORD 填生成的密码(含空格原样填)', 'site_url 填站点根地址;发布后是草稿,登录后台确认再对外']}, - Network accessline 53
"cfg": [("thumb_media_id", "永久素材封面 media_id(草稿必需)")], "note": "新建草稿,需在公众号后台预览并群发;服务器 IP 要在白名单", "guide": {"url": 'https://mp.weixin.qq.com', "steps": ['公众号后台 → 设置与开发 → 基本配置:拿 AppID / AppSecret', '同页「IP 白名单」加上本机出口 IP(不加会报 401 - Network accessline 54
"note": "新建草稿,需在公众号后台预览并群发;服务器 IP 要在白名单", "guide": {"url": 'https://mp.weixin.qq.com', "steps": ['公众号后台 → 设置与开发 → 基本配置:拿 AppID / AppSecret', '同页「IP 白名单」加上本机出口 IP(不加会报 40164)', '素材库上传一张封面图,拿永久素材 media_id 填 thumb_media_id(草稿必需)', '发布后 - Network accessline 55
"guide": {"url": 'https://mp.weixin.qq.com', "steps": ['公众号后台 → 设置与开发 → 基本配置:拿 AppID / AppSecret', '同页「IP 白名单」加上本机出口 IP(不加会报 40164)', '素材库上传一张封面图,拿永久素材 media_id 填 thumb_media_id(草稿必需)', '发布后到后台「草稿箱」预览、群发']}, - Access to secretsline 59
[Credential-related source omitted] - Network accessline 60
"cfg": [("link_url", "文章公开链接(留空则自动用该文件最近一次 GitHub/WordPress 发布的 URL)")], "note": "API v2 发一条「标题 + 摘要 + 链接」的推文引流,不是发全文;developer.x.com 建应用取四个凭证", "guide": {"url": 'https://developer.x.com/en/portal/dashboard', "steps": ['deve - Network accessline 61
"note": "API v2 发一条「标题 + 摘要 + 链接」的推文引流,不是发全文;developer.x.com 建应用取四个凭证", "guide": {"url": 'https://developer.x.com/en/portal/dashboard', "steps": ['developer.x.com 申请开发者账号(Free 档即可发推),创建一个 App', 'App 的 User authentication settings 里开 - Network accessline 62
"guide": {"url": 'https://developer.x.com/en/portal/dashboard', "steps": ['developer.x.com 申请开发者账号(Free 档即可发推),创建一个 App', 'App 的 User authentication settings 里开启 Read and Write 权限', 'Keys and tokens 页生成四个值:API Key/Secret(Consumer)+ Access T - Access to secretsline 66
[Credential-related source omitted] - Network accessline 67
"cfg": [("subreddit", "发到哪个 subreddit(不带 r/)")], "note": "script 应用密码授权,markdown 全文作为 self-post;注意目标社区的自我推广规则", "guide": {"url": 'https://www.reddit.com/prefs/apps', "steps": ['reddit.com/prefs/apps → create app → 类型选「script - Network accessline 68
"note": "script 应用密码授权,markdown 全文作为 self-post;注意目标社区的自我推广规则", "guide": {"url": 'https://www.reddit.com/prefs/apps', "steps": ['reddit.com/prefs/apps → create app → 类型选「script」', 'REDDIT_CLIENT_ID 是应用名下方那串字符,SECRET 在旁边', '用户名密码就是登录凭 - Network accessline 69
"guide": {"url": 'https://www.reddit.com/prefs/apps', "steps": ['reddit.com/prefs/apps → create app → 类型选「script」', 'REDDIT_CLIENT_ID 是应用名下方那串字符,SECRET 在旁边', '用户名密码就是登录凭证;账号开了两步验证会失败,建议用专用账号', 'subreddit 先用自己的主页社区(u_你的用户名)试发,再进目标社区——先读对方的自我 - Access to secretsline 75
[Credential-related source omitted] - Network accessline 133
[Credential-related source omitted] - Access to secretsline 133
[Credential-related source omitted] - Network accessline 134
"Accept": "application/vnd.github+json"} url = f"https://api.github.com/repos/{repo}/contents/{path}" body = {"message": f"geo: publish {title}", "branch": branch, - Network accessline 135
url = f"https://api.github.com/repos/{repo}/contents/{path}" - Network accessline 136
body = {"message": f"geo: publish {title}", "branch": branch, "content": base64.b64encode(text.encode()).decode()} r0 = requests.get(url, headers=H, params={"ref": branch}, timeout=30) - Network accessline 137
"content": base64.b64encode(text.encode()).decode()} r0 = requests.get(url, headers=H, params={"ref": branch}, timeout=30) if r0.status_code == 200: # 已存在→更新 - Network accessline 138
r0 = requests.get(url, headers=H, params={"ref": branch}, timeout=30) - Network accessline 139
if r0.status_code == 200: # 已存在→更新 body["sha"] = r0.json().get("sha") r = requests.put(url, headers=H, json=body, timeout=30) - Network accessline 140
body["sha"] = r0.json().get("sha") r = requests.put(url, headers=H, json=body, timeout=30) if r.status_code in (200, 201): - Network accessline 141
r = requests.put(url, headers=H, json=body, timeout=30) - Network accessline 149
if not site: return {"ok": False, "error": "先在设置里配置 site_url"} r = requests.post(f"{site}/wp-json/wp/v2/posts", - Network accessline 150
return {"ok": False, "error": "先在设置里配置 site_url"} r = requests.post(f"{site}/wp-json/wp/v2/posts", auth=(os.environ["WP_USER"], os.environ["WP_APP_PASSWORD"]), - Network accessline 151
r = requests.post(f"{site}/wp-json/wp/v2/posts", - Access to secretsline 152
[Credential-related source omitted] - Network accessline 163
if not thumb: return {"ok": False, "error": "缺封面:先在设置里配置 thumb_media_id(永久素材)"} tr = requests.get("https://api.weixin.qq.com/cgi-bin/token", - Network accessline 164
return {"ok": False, "error": "缺封面:先在设置里配置 thumb_media_id(永久素材)"} tr = requests.get("https://api.weixin.qq.com/cgi-bin/token", params={"grant_type": "client_credential", - Network accessline 165
tr = requests.get("https://api.weixin.qq.com/cgi-bin/token", - Access to secretsline 167
[Credential-related source omitted] - Access to secretsline 168
[Credential-related source omitted] - Access to secretsline 169
[Credential-related source omitted] - Network accessline 172
[Credential-related source omitted] - Network accessline 173
[Credential-related source omitted] - Network accessline 174
[Credential-related source omitted] - Access to secretsline 174
[Credential-related source omitted] - Network accessline 182
def _pub_webhook(cfg, text, title, fname): r = requests.post(os.environ["PUBLISH_WEBHOOK_URL"], - Network accessline 183
[Credential-related source omitted] - Access to secretsline 183
[Credential-related source omitted] - Network accessline 259
if link: tweet += "\n" + link hdr = _oauth1_header("POST", "https://api.x.com/2/tweets", - Network accessline 260
tweet += "\n" + link hdr = _oauth1_header("POST", "https://api.x.com/2/tweets", os.environ["X_API_KEY"], os.environ["X_API_SECRET"], - Network accessline 261
hdr = _oauth1_header("POST", "https://api.x.com/2/tweets", - Network accessline 262
[Credential-related source omitted] - Access to secretsline 262
[Credential-related source omitted] - Network accessline 263
[Credential-related source omitted] - Access to secretsline 263
[Credential-related source omitted] - Network accessline 264
r = requests.post("https://api.x.com/2/tweets", json={"text": tweet}, - Network accessline 267
if r.status_code == 201: tid = (r.json().get("data") or {}).get("id", "") return {"ok": True, "url": f"https://x.com/i/web/status/{tid}" if tid else "", - Network accessline 268
tid = (r.json().get("data") or {}).get("id", "") return {"ok": True, "url": f"https://x.com/i/web/status/{tid}" if tid else "", "note": "" if link else "未带回链(该文件还没有长文渠道的公开 URL)"} - Network accessline 269
return {"ok": True, "url": f"https://x.com/i/web/status/{tid}" if tid else "", - Network accessline 279
return {"ok": False, "error": "先在设置里配置 subreddit"} ua = "geolook-publisher/0.1 by " + os.environ["REDDIT_USERNAME"] tok = requests.post( - Network accessline 280
[Credential-related source omitted] - Access to secretsline 280
[Credential-related source omitted] - Network accessline 281
tok = requests.post( - Network accessline 282
[Credential-related source omitted] - Access to secretsline 282
[Credential-related source omitted] - Access to secretsline 283
[Credential-related source omitted] - Access to secretsline 284
[Credential-related source omitted] - Access to secretsline 285
[Credential-related source omitted] - Network accessline 287
[Credential-related source omitted] - Access to secretsline 287
[Credential-related source omitted] - Network accessline 288
return {"ok": False, "error": f"取 token 失败 HTTP {tok.status_code}: {tok.text[:150]}"} r = requests.post( "https://oauth.reddit.com/api/submit", - Network accessline 289
r = requests.post( - Network accessline 290
"https://oauth.reddit.com/api/submit", - Access to secretsline 293
[Credential-related source omitted]
scripts/report.py
- Executable scriptline 1
Executable file
scripts/sample.py
- Executable scriptline 1
Executable file - Network accessline 35
"glm": { "name": "智谱GLM", "market": "cn", "base": "https://open.bigmodel.cn/api/paas/v4", - Network accessline 37
"base": "https://open.bigmodel.cn/api/paas/v4", - Access to secretsline 41
[Credential-related source omitted] - Network accessline 48
"name": "豆包(方舟API)", "market": "cn", "protocol": "ark", "base": "https://ark.cn-beijing.volces.com/api/v3", - Network accessline 49
"protocol": "ark", "base": "https://ark.cn-beijing.volces.com/api/v3", "model": "doubao-seed-1-6-250615", - Network accessline 50
"base": "https://ark.cn-beijing.volces.com/api/v3", - Access to secretsline 53
[Credential-related source omitted] - Network accessline 57
"deepseek": { "name": "DeepSeek", "market": "cn", "base": "https://api.deepseek.com/v1", - Network accessline 58
"name": "DeepSeek", "market": "cn", "base": "https://api.deepseek.com/v1", "model": "deepseek-v4-flash", - Network accessline 59
"base": "https://api.deepseek.com/v1", - Access to secretsline 62
[Credential-related source omitted] - Network accessline 66
"kimi": { "name": "Kimi", "market": "cn", "base": "https://api.moonshot.cn/v1", - Network accessline 67
"name": "Kimi", "market": "cn", "base": "https://api.moonshot.cn/v1", "model": "kimi-k2-0905-preview", - Network accessline 68
"base": "https://api.moonshot.cn/v1", - Access to secretsline 71
[Credential-related source omitted] - Network accessline 75
"minimax": { "name": "MiniMax", "market": "cn", "base": "https://api.minimaxi.com/v1", - Network accessline 76
"name": "MiniMax", "market": "cn", "base": "https://api.minimaxi.com/v1", "model": "MiniMax-M2", - Network accessline 77
"base": "https://api.minimaxi.com/v1", - Access to secretsline 80
[Credential-related source omitted] - Network accessline 85
"gemini": { "name": "Gemini", "market": "global", "base": "https://generativelanguage.googleapis.com/v1beta/openai", - Network accessline 86
"name": "Gemini", "market": "global", "base": "https://generativelanguage.googleapis.com/v1beta/openai", "model": "gemini-2.5-flash", - Network accessline 87
"base": "https://generativelanguage.googleapis.com/v1beta/openai", - Access to secretsline 90
[Credential-related source omitted] - Network accessline 94
"openai": { "name": "OpenAI(ChatGPT)", "market": "global", "base": os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1"), - Network accessline 95
"name": "OpenAI(ChatGPT)", "market": "global", "base": os.environ.get("OPENAI_BASE_URL", "https://api.openai.com/v1"), "model": "gpt-4o-mini", - Network accessline 96
[Credential-related source omitted] - Access to secretsline 96
[Credential-related source omitted] - Access to secretsline 99
[Credential-related source omitted] - Network accessline 105
"name": "Claude", "market": "global", "protocol": "anthropic", "base": "https://api.anthropic.com/v1", - Network accessline 106
"protocol": "anthropic", "base": "https://api.anthropic.com/v1", "model": "claude-sonnet-5", - Network accessline 107
"base": "https://api.anthropic.com/v1", - Access to secretsline 110
[Credential-related source omitted] - Network accessline 114
"grok": { "name": "Grok", "market": "global", "base": "https://api.x.ai/v1", - Network accessline 115
"name": "Grok", "market": "global", "base": "https://api.x.ai/v1", "model": "grok-3-mini", - Network accessline 116
"base": "https://api.x.ai/v1", - Access to secretsline 119
[Credential-related source omitted] - Network accessline 123
"perplexity": { "name": "Perplexity", "market": "global", "base": "https://api.perplexity.ai", - Network accessline 124
"name": "Perplexity", "market": "global", "base": "https://api.perplexity.ai", "model": "sonar", - Network accessline 125
"base": "https://api.perplexity.ai", - Access to secretsline 128
[Credential-related source omitted] - Access to secretsline 187
[Credential-related source omitted] - Access to secretsline 196
[Credential-related source omitted] - Network accessline 212
[Credential-related source omitted] - Network accessline 213
try: r = requests.post(f"{p['base']}/responses", headers=H, json={"model": _p_model(p), "input": question, - Network accessline 214
r = requests.post(f"{p['base']}/responses", headers=H, - Network accessline 240
try: # 降级:不联网的普通对话 r = requests.post(f"{p['base']}/chat/completions", headers=H, - Network accessline 241
r = requests.post(f"{p['base']}/chat/completions", headers=H, - Network accessline 256
for attempt in range(len(delays) + 1): try: r = requests.post( - Network accessline 257
try: r = requests.post( f"{p['base']}/messages", - Network accessline 258
r = requests.post( - Access to secretsline 290
[Credential-related source omitted] - Network accessline 304
for attempt in range(len(delays) + 1): try: r = requests.post( - Network accessline 305
try: r = requests.post( f"{p['base']}/chat/completions", - Network accessline 306
r = requests.post(
scripts/service.sh
- Executable scriptline 1
#!/usr/bin/env bash - Network accessline 25
cat > "$PLIST" <<EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> - Network accessline 26
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"><dict> - Network accessline 27
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> - Network accessline 48
launchctl bootstrap "gui/$UID_N" "$PLIST" sleep 2 if curl -fsS -m 5 http://127.0.0.1:8765/api/projects >/dev/null 2>&1; then - Network accessline 49
sleep 2 if curl -fsS -m 5 http://127.0.0.1:8765/api/projects >/dev/null 2>&1; then echo "✓ 已注册常驻服务:$LABEL" - Network accessline 50
if curl -fsS -m 5 http://127.0.0.1:8765/api/projects >/dev/null 2>&1; then - Network accessline 51
echo "✓ 已注册常驻服务:$LABEL" echo " http://127.0.0.1:8765 · 登录自启 · 崩溃自动拉起 · 日志 $LOG" echo " 关闭 Claude / 终端都不影响;卸载:./service.sh uninstall" - Network accessline 52
echo " http://127.0.0.1:8765 · 登录自启 · 崩溃自动拉起 · 日志 $LOG" - Dangerous shell operationline 60
rm -f "$PLIST" ;; - Network accessline 64
PID=$(launchctl print "gui/$UID_N/$LABEL" 2>/dev/null | awk '/pid =/{print $3}') echo "✓ 常驻服务运行中(pid ${PID:-?})" curl -fsS -m 3 http://127.0.0.1:8765/api/projects >/dev/null 2>&1 \ - Network accessline 65
echo "✓ 常驻服务运行中(pid ${PID:-?})" curl -fsS -m 3 http://127.0.0.1:8765/api/projects >/dev/null 2>&1 \ && echo "✓ 看板可访问:http://127.0.0.1:8765" || echo "✗ 端口无响应,看日志:$LOG" - Network accessline 66
curl -fsS -m 3 http://127.0.0.1:8765/api/projects >/dev/null 2>&1 \ - Network accessline 67
&& echo "✓ 看板可访问:http://127.0.0.1:8765" || echo "✗ 端口无响应,看日志:$LOG"
scripts/tasks.py
- Executable scriptline 1
Executable file - Network accessline 176
t = _t(next(seq), "P0", "页面技术", "修复前端渲染空壳页(SSR / 预渲染)", "静态 HTML 无正文,多数 AI 抓取器看到的是空白页——国内官网最常见致命伤(method.md 可抓取性)", "对受影响路由启用 SSR 或预渲染,确保 curl 拿到的 HTML 含完整正文", - Network accessline 177
"静态 HTML 无正文,多数 AI 抓取器看到的是空白页——国内官网最常见致命伤(method.md 可抓取性)", "对受影响路由启用 SSR 或预渲染,确保 curl 拿到的 HTML 含完整正文", "开发", "M", {"type": "auto", "check": "pages.static_text", - Network accessline 178
"对受影响路由启用 SSR 或预渲染,确保 curl 拿到的 HTML 含完整正文",
scripts/ui.html
- Network accessline 147
// 非 2xx 也尽量读 body:服务端错误响应带具体原因(如「缺凭证:GITHUB_TOKEN」), // 只报 HTTP 状态码会把可行动的信息丢掉 const api=async(u,o)=>{try{const r=await fetch(u,o);const j=await r.json().catch(()=>null); - Network accessline 148
// 只报 HTTP 状态码会把可行动的信息丢掉 const api=async(u,o)=>{try{const r=await fetch(u,o);const j=await r.json().catch(()=>null); if(!r.ok)return (j&&j.error)?j:{error:`HTTP ${r.status}`}; - Network accessline 149
const api=async(u,o)=>{try{const r=await fetch(u,o);const j=await r.json().catch(()=>null); - Access to secretsline 329
[Credential-related source omitted] - Access to secretsline 571
[Credential-related source omitted] - Access to secretsline 694
[Credential-related source omitted] - Access to secretsline 751
[Credential-related source omitted] - Access to secretsline 964
[Credential-related source omitted] - Network accessline 2296
} async function editSheet(name){ const r=await fetch(`/files/${SLUG}/samples/${encodeURIComponent(name)}`); - Network accessline 2297
async function editSheet(name){ const r=await fetch(`/files/${SLUG}/samples/${encodeURIComponent(name)}`); if(!r.ok){toast('采样表不存在','err');return} - Network accessline 2298
const r=await fetch(`/files/${SLUG}/samples/${encodeURIComponent(name)}`); - Access to secretsline 2566
[Credential-related source omitted] - Access to secretsline 2580
[Credential-related source omitted] - Network accessline 2602
</div>` :`<div class="muted" style="font-size:12px">已配置引擎:国内 ${okCn} 个 · 海外 ${okGl} 个(可在「设置」增改)${(ST.obMkt||'both')!=='global'&&!okCn?'——注意国内市场尚无可用 Key':''}${(ST.obMkt||'both')!=='cn'&&!okGl?'——注意海外市场尚无可用 Key':''}</div>`} <div c - Network accessline 2603
:`<div class="muted" style="font-size:12px">已配置引擎:国内 ${okCn} 个 · 海外 ${okGl} 个(可在「设置」增改)${(ST.obMkt||'both')!=='global'&&!okCn?'——注意国内市场尚无可用 Key':''}${(ST.obMkt||'both')!=='cn'&&!okGl?'——注意海外市场尚无可用 Key':''}</div>`} <div class="field">< - Network accessline 2604
<div class="field"><label>官网域名 *</label><input id="ob-url" class="input" placeholder="https://example.com" value="${esc(ST.obUrl||'')}"></div>
scripts/verify.py
- Executable scriptline 1
Executable file
tests/__init__.py
- Executable scriptline 1
Executable file
tests/test_analytics.py
tests/test_audit.py
- Executable scriptline 1
Executable file - Network accessline 12
def make_page(url="https://example.com/", text="", wc=None, **kw): - Network accessline 34
def test_functional_page_exempt(self): r = A.score_page(make_page(url="https://example.com/login", text=SPA_TEXT), []) - Network accessline 35
r = A.score_page(make_page(url="https://example.com/login", text=SPA_TEXT), []) - Network accessline 40
def test_functional_page_case_insensitive(self): r = A.score_page(make_page(url="https://example.com/Auth/SignIn", text=SPA_TEXT), []) - Network accessline 41
r = A.score_page(make_page(url="https://example.com/Auth/SignIn", text=SPA_TEXT), []) - Network accessline 45
def test_normal_low_page_still_spa(self): r = A.score_page(make_page(url="https://example.com/products", text=SPA_TEXT), []) - Network accessline 46
r = A.score_page(make_page(url="https://example.com/products", text=SPA_TEXT), []) - Network accessline 88
def test_contact_page_is_functional(self): r = A.score_page(make_page(url="https://example.com/contact", text=SPA_TEXT), []) - Network accessline 89
r = A.score_page(make_page(url="https://example.com/contact", text=SPA_TEXT), []) - Network accessline 108
class TestNormalizeUrl(unittest.TestCase): def test_strips_tracking_params(self): u = G.normalize_url("https://example.com/", "/p?utm_source=x&fbclid=y&id=42&gclid=z") - Network accessline 109
def test_strips_tracking_params(self): u = G.normalize_url("https://example.com/", "/p?utm_source=x&fbclid=y&id=42&gclid=z") self.assertEqual(u, "https://example.com/p?id=42") - Network accessline 110
u = G.normalize_url("https://example.com/", "/p?utm_source=x&fbclid=y&id=42&gclid=z") - Network accessline 111
self.assertEqual(u, "https://example.com/p?id=42") - Network accessline 113
def test_strips_ref_spm(self): u = G.normalize_url("https://example.com/", "https://example.com/a?ref=nav&spm=1.2.3&lang=zh") - Network accessline 114
u = G.normalize_url("https://example.com/", "https://example.com/a?ref=nav&spm=1.2.3&lang=zh") - Network accessline 115
self.assertEqual(u, "https://example.com/a?lang=zh") - Network accessline 117
def test_no_query_unchanged(self): u = G.normalize_url("https://example.com/", "/about#team") - Network accessline 118
u = G.normalize_url("https://example.com/", "/about#team") - Network accessline 119
self.assertEqual(u, "https://example.com/about") - Network accessline 136
pages = [] for i in range(35): pages.append({"url": f"https://example.com/p{i}", "score": 50, - Network accessline 137
for i in range(35): pages.append({"url": f"https://example.com/p{i}", "score": 50, "word_count": 500, "jsonld_types": ["Article"], - Network accessline 138
pages.append({"url": f"https://example.com/p{i}", "score": 50, - Network accessline 144
"pages": pages, "avg_score": 50, "block_gap": [{"block": "定义", "missing_pages": 35, "total": 35}]} cfg = {"market": "cn", "brand": {"name": "X", "site": "https://example.com"}} - Network accessline 145
"block_gap": [{"block": "定义", "missing_pages": 35, "total": 35}]} cfg = {"market": "cn", "brand": {"name": "X", "site": "https://example.com"}} out = T.from_audit(audit, cfg, iter(f"T-{i:03d}" for i in range(1, 99))) - Network accessline 146
cfg = {"market": "cn", "brand": {"name": "X", "site": "https://example.com"}} - Network accessline 154
class TestAvgScore(unittest.TestCase): def test_zero_score_200_pages_counted(self): pages = [make_page(url="https://example.com/a", text=SPA_TEXT), - Network accessline 155
def test_zero_score_200_pages_counted(self): pages = [make_page(url="https://example.com/a", text=SPA_TEXT), make_page(url="https://example.com/b", text=SPA_TEXT, status=404)] - Network accessline 156
pages = [make_page(url="https://example.com/a", text=SPA_TEXT), - Network accessline 157
make_page(url="https://example.com/b", text=SPA_TEXT, status=404)] - Network accessline 187
(pdir / "evidence").mkdir(parents=True) (pdir / "geo.json").write_text(json.dumps( {"brand": {"name": "T", "site": "https://example.com"}, "market": "cn"}, - Network accessline 188
(pdir / "geo.json").write_text(json.dumps( {"brand": {"name": "T", "site": "https://example.com"}, "market": "cn"}, ensure_ascii=False), "utf-8") - Network accessline 189
{"brand": {"name": "T", "site": "https://example.com"}, "market": "cn"}, - Network accessline 190
ensure_ascii=False), "utf-8") pages = [ make_page(url="https://example.com/ja/", text=ja_text, language="zh", wc=200), - Network accessline 191
pages = [ make_page(url="https://example.com/ja/", text=ja_text, language="zh", wc=200), make_page(url="https://example.com/zh/", text=zh_text, language="zh", wc=200), - Network accessline 192
make_page(url="https://example.com/ja/", text=ja_text, language="zh", wc=200), - Network accessline 193
make_page(url="https://example.com/zh/", text=zh_text, language="zh", wc=200),
tests/test_bootstrap.py
- Executable scriptline 1
Executable file - Network accessline 33
BASE_CFG = { "brand": {"name": "测试品牌", "aliases": [], "site": "https://t.example.com"}, - Network accessline 34
"brand": {"name": "测试品牌", "aliases": [], "site": "https://t.example.com"}, - Network accessline 45
class TestHomepageFirst(WorkDirCase): def test_root_is_first_page_not_highest_scored(self): home = "https://t.example.com/" - Network accessline 46
def test_root_is_first_page_not_highest_scored(self): home = "https://t.example.com/" deep = "https://t.example.com/blog/hot-article" - Network accessline 47
home = "https://t.example.com/" - Network accessline 48
deep = "https://t.example.com/blog/hot-article"
tests/test_crawl.py
- Executable scriptline 1
Executable file - Network accessline 16
self.status_code = status self.headers = {"Content-Type": ctype} self.url = "http://x.test/" - Network accessline 17
self.headers = {"Content-Type": ctype} self.url = "http://x.test/" self._body = body - Network accessline 18
self.url = "http://x.test/" - Network accessline 31
with mock.patch.object(G.requests, "get", side_effect=responses) as get, \ mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=retries) - Network accessline 32
mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=retries) return res, get.call_count - Network accessline 33
res = G.fetch("http://x.test/", retries=retries) - Network accessline 58
side_effect=[FakeResp(403), FakeResp(200)]) as get, \ mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=0) - Network accessline 59
mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=0) self.assertEqual(res["status"], 200) - Network accessline 60
res = G.fetch("http://x.test/", retries=0) - Network accessline 69
side_effect=[FakeResp(403), FakeResp(403)]) as get, \ mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=0) - Network accessline 70
mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=0) self.assertEqual(res["status"], 403) - Network accessline 71
res = G.fetch("http://x.test/", retries=0) - Network accessline 76
with mock.patch.object(G.requests, "get", side_effect=[FakeResp(403)]) as get, \ mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=0, ua="AI-Bot/1.0") - Network accessline 77
mock.patch.object(G.time, "sleep"): res = G.fetch("http://x.test/", retries=0, ua="AI-Bot/1.0") self.assertEqual(res["status"], 403) - Network accessline 78
res = G.fetch("http://x.test/", retries=0, ua="AI-Bot/1.0")
tests/test_dashboard.py
tests/test_deliver.py
- Executable scriptline 1
Executable file - Network accessline 30
pdir.mkdir(parents=True) (pdir / "geo.json").write_text(json.dumps( {"brand": {"name": "X", "site": "https://x.com"}, "market": "cn"}, - Network accessline 31
(pdir / "geo.json").write_text(json.dumps( {"brand": {"name": "X", "site": "https://x.com"}, "market": "cn"}, ensure_ascii=False), "utf-8") - Network accessline 32
{"brand": {"name": "X", "site": "https://x.com"}, "market": "cn"},
tests/test_geolib.py
- Executable scriptline 1
Executable file - Network accessline 54
rows = [ {"url": "https://a.example/1", "text": "line one\u2028line two"}, - Network accessline 55
{"url": "https://a.example/1", "text": "line one\u2028line two"}, - Network accessline 56
{"url": "https://a.example/2", "text": "para\u2029break"}, - Network accessline 57
{"url": "https://a.example/3", "text": "next\u0085line"}, - Network accessline 58
{"url": "https://a.example/4", "text": "vert\u000btab and form\u000cfeed"}, - Network accessline 59
{"url": "https://a.example/5", "text": "plain"}, - Network accessline 87
def test_has_site(self): self.assertTrue(G.has_site({"brand": {"site": "https://a.com"}})) - Network accessline 88
self.assertTrue(G.has_site({"brand": {"site": "https://a.com"}}))
tests/test_jobs.py
- Executable scriptline 1
Executable file
tests/test_model_config.py
- Executable scriptline 1
Executable file - Access to secretsline 26
[Credential-related source omitted] - Access to secretsline 27
[Credential-related source omitted] - Access to secretsline 35
[Credential-related source omitted] - Access to secretsline 37
[Credential-related source omitted] - Access to secretsline 42
[Credential-related source omitted] - Access to secretsline 61
[Credential-related source omitted] - Access to secretsline 72
[Credential-related source omitted] - Access to secretsline 82
[Credential-related source omitted] - Access to secretsline 83
[Credential-related source omitted] - Access to secretsline 107
[Credential-related source omitted] - Access to secretsline 109
[Credential-related source omitted] - Access to secretsline 110
[Credential-related source omitted] - Access to secretsline 112
[Credential-related source omitted] - Access to secretsline 117
[Credential-related source omitted] - Access to secretsline 118
[Credential-related source omitted]
tests/test_report.py
tests/test_sample.py
- Executable scriptline 1
Executable file - Network accessline 10
CFG = { "brand": {"name": "AIGCLINK定制家", "aliases": ["定制家"], "site": "https://aigclink.example.com"}, - Network accessline 11
"brand": {"name": "AIGCLINK定制家", "aliases": ["定制家"], "site": "https://aigclink.example.com"}, - Network accessline 50
def test_latin_alias_requires_boundary(self): cfg = {"brand": {"name": "灵眸", "aliases": ["AIGC"], "site": "https://x.example.com"}, - Network accessline 51
cfg = {"brand": {"name": "灵眸", "aliases": ["AIGC"], "site": "https://x.example.com"}, - Access to secretsline 123
[Credential-related source omitted]
tests/test_tasks.py
- Executable scriptline 1
Executable file - Network accessline 30
CFG = {"brand": {"name": "X", "site": "https://x.com"}, - Network accessline 81
(pdir / "metrics").mkdir(parents=True) (pdir / "geo.json").write_text(json.dumps( {"brand": {"name": "X", "site": "https://x.com"}, - Network accessline 82
(pdir / "geo.json").write_text(json.dumps( {"brand": {"name": "X", "site": "https://x.com"}, "market": "cn", "targets": {"mention_rate": 0.3}}, ensure_ascii=False), "utf-8") - Network accessline 83
{"brand": {"name": "X", "site": "https://x.com"},
tests/test_ui.py
- Executable scriptline 1
Executable file
How the signals fit together
Facts from a static read of the files at the pinned commit. They describe what the code does, not why.
Some files could not be read; the facts below still hold.
Signal confidence: 7 facts
- Network access in code of documentationREADME.md:94Low confidence
- Network access in code of documentationREADME.md:99Low confidence
- Network access in code of documentationREADME.md:116Low confidence
- Access to secrets in code of documentationREADME.md:119Low confidence
- Network access in code of documentationREADME.md:139Low confidence
- Network access in code of the SKILL.mdSKILL.md:34High confidence
- Network access in code of the SKILL.mdSKILL.md:57High confidence
Works with
| Agent | Status | Evidence | Install to |
|---|---|---|---|
| Claude Code | Compatible | Standard SKILL.md SKILL.md | .claude/skills/<skill-name>/ |
| Codex | Compatible | Standard SKILL.md SKILL.md | .agents/skills/<skill-name>/ |
| Cursor | Compatible | Standard SKILL.md SKILL.md | .cursor/skills/<skill-name>/ |
| Gemini CLI | Compatible | Standard SKILL.md SKILL.md | .gemini/skills/<skill-name>/ |
| GitHub Copilot | Compatible | Standard SKILL.md SKILL.md | .github/skills/<skill-name>/ |
| OpenCode | Compatible | Standard SKILL.md SKILL.md | .opencode/skills/<skill-name>/ |
- Native The repository ships a manifest, folder or frontmatter field for this agent.
- Compatible A standard SKILL.md that this agent can read.
- Unknown No evidence either way.
Derived automatically from paths, manifests and frontmatter. Not tested on each agent.