rankup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseRankup 2.0
Rankup 2.0
rankup.rankup/它不重复实现 Wrangler、Stripe、趋势研究或外链工具;它负责把这些能力串成一条长期可维护的网站工作流。
rankup.rankup/It does not reimplement Wrangler, Stripe, trend research or backlink tools; it is responsible for stringing these capabilities into a long-term maintainable website workflow.
红线:先查脚本清单,禁止重造轮子
Red Line: Check Script List First, No Reinventing the Wheel
动手之前先看这一节。凡是本清单里已经有的能力,一律调用现成脚本;不准在对话里现写一段等价实现,也不准手工点一遍界面。
这是被明确指出过的红线,理由不是洁癖:现写的实现每次形状都不一样,结果不可比、踩过的坑要重踩、上下文白烧,而且下次换个报表还得再写一遍。脚本坏了就修脚本(改完更新头部的已验证日期),不要绕过它。只有清单里确实没有的能力,才允许新写——写完立刻按「可复用操作必须落成脚本」固化并登记。
判定顺序,从上往下,命中即停:
- 本清单(本 Skill + 兄弟 Skill 的脚本);
- 跨项目资产登记表 (别的项目已经写好的,直接去那个路径取);
registry.md - 当前项目的 ;
<project>/.rankup/scripts/ - 都没有 → 才新写。
Read this section before taking any action. For any capability already listed in this inventory, call the existing script directly; do not write an equivalent implementation in the conversation, nor manually click through the interface.
This is an explicitly stated red line, not just a matter of preference: ad-hoc implementations vary every time, making results incomparable, requiring repeated troubleshooting of the same issues, wasting context, and needing to be rewritten for different reports. Fix the script if it breaks (update the verified date at the top after modification), do not bypass it. Only write new scripts when the capability is truly not in the inventory—and immediately solidify and register it following the rule "Reusable operations must be turned into scripts".
Judgment order, top to bottom, stop at first match:
- This inventory (scripts from this Skill + sibling Skills);
- Cross-project asset registry (already written by other projects, directly retrieve from that path);
registry.md - Current project's ;
<project>/.rankup/scripts/ - None of the above → only then write a new script.
本 Skill 自带
Included in This Skill
| 脚本 | 干什么 | 什么时候用 |
|---|---|---|
| 一个脚本覆盖 seo.web.cafe 全部有后端的工具: | 问「这个词难不难做」「这盘面能不能进」「这条外链值不值」「这域名什么来历」。零配置可跑,匿名 10 次/日 |
| Google Trends:热度对比、地区分布、相关飙升词、每日热搜 | 问「XX 和 YY 哪个更火」「哪个国家有机会」「最近什么在涨」。首次运行自动建 venv |
| 驱动只有网页形态的 AI Chatbot(要登录、按条扣费、无 API),反复提问并完整取回长回答 | 需要向某个聊天式工具连续提问并保全全文时 |
| 开通 Cloudflare Web Analytics 并读回 beacon。 | 新站上线后接测量时。不依赖任何第三方账号,应排在 GSC/GA 之前做 |
| 把域名加进 Cloudflare(zone onboarding)并读回 NS 对——Wrangler 没有 zone 命令,这是补它的缺口。 | 新域名接入 Cloudflare 时。优先仍是操作用户浏览器,本脚本是浏览器不可用时的退路 |
| 扫描各项目 | 开工前查「别的项目有没有现成的」;收工时刷新 |
| 项目记忆体检:缺失文件、超期记录、脚本体检、经验库信号 | |
| 找出并浓缩本项目的 Claude Code / Codex 会话,供 review 提取信号 | |
| Skill 版本检查与自更新 | 每次激活 |
| 项目中立性与凭据泄露的机械门禁 | 改完 Skill 必跑 |
| Script | Purpose | When to Use |
|---|---|---|
| A single script covering all backend-enabled tools from seo.web.cafe: | When asking "Is this keyword hard to rank for?", "Can I break into this SERP?", "Is this backlink worth it?", "What's the background of this domain?". Zero-config, 10 anonymous runs per day |
| Google Trends: popularity comparison, regional distribution, related rising keywords, daily trending searches | When asking "Which is more popular, XX or YY?", "Which country has opportunities?", "What's trending recently?". Automatically creates a venv on first run |
| Drives AI Chatbots that only exist in web form (require login, charge per query, no API), repeatedly asks questions and retrieves complete long answers | When needing to ask continuous questions to a chat-based tool and preserve the full text |
| Enables Cloudflare Web Analytics and retrieves the beacon. | When setting up measurement after a new site launches. Does not rely on any third-party accounts, should be done before GSC/GA |
| Adds a domain to Cloudflare (zone onboarding) and retrieves the NS pair—Wrangler has no zone command, this fills that gap. | When onboarding a new domain to Cloudflare. Priority is to operate the user's browser, this script is a fallback when the browser is unavailable |
| Scans | Check "Does another project have an existing solution?" before starting work; refresh when finishing work |
| Project memory health check: missing files, expired records, script health check, experience library signals | First step of |
| Finds and condenses Claude Code / Codex sessions for the current project, for review to extract signals | Second step of |
| Skill version check and auto-update | On every activation |
| Mechanical gatekeeper for project neutrality and credential leakage | Must run after modifying the Skill |
兄弟 Skill:backlink
(登录态后台取数与外链)
backlinkSibling Skill: backlink
(Authenticated Backend Data Extraction & Backlinks)
backlink任何「从一个要登录的 SaaS 后台把表格数据拿下来」的需求,入口都是这里,不要自己写提取器。
| 脚本 | 干什么 |
|---|---|
| 通用虚拟滚动表格提取器,贴进浏览器代码执行工具跑。 |
| 等下载落齐(文件数达标 且 大小连续两次采样不变)再收拢,防静默丢文件 |
| 合并抓下来的 TSV 成干净 CSV,带重名副本检测 |
| 走 OpenCLI 的流量面板查询(performance / similar-sites)。需要 |
| 几百个域名批量测流量:登录只做一次,之后只换 SPA 的 hash 路由,单域名 5 秒;同步前台跑、逐条追加写盘、按已有输出续跑。要筛一批域名值不值得做时用它,不要用单域名脚本循环,更不要退回 Tranco 这类流行度名单(站群能刷高流行度,实测 73 个站群域名有 48 个在 Tranco top-1M 里) |
| 探一个页面有没有可提交的表单/入口 |
| 受控填表,带提交前护栏 |
| 外链机会队列与投放台账 |
| 跨项目累积的付费外链平台登记表 |
| 数据层机械门禁,改数据必跑 |
配套读物:(表格采集技巧与反爬约束)、。
backlink/references/harvest.mdpaid-platforms.mdFor any requirement to "extract tabular data from an authenticated SaaS backend", the entry point is here—do not write your own extractor.
| Script | Purpose |
|---|---|
| Universal virtual scroll table extractor, run in browser code execution tools. |
| Waits until all downloads are complete (file count meets requirement and file sizes remain unchanged in two consecutive samples) before collecting, to prevent silent file loss |
| Merges captured TSV files into clean CSV, with duplicate detection |
| Queries traffic panels (performance / similar-sites) via OpenCLI. Requires two environment variables: |
| Batch traffic measurement for hundreds of domains: login only once, then only switch the SPA's hash route, 5 seconds per domain; runs synchronously in the foreground, appends to file one by one, resumes based on existing output. Use this when screening a batch of domains to see if they are worth working on—do not loop with single-domain scripts, and do not revert to popularity lists like Tranco (site groups can inflate popularity, 48 out of 73 tested site group domains were in Tranco top-1M) |
| Detects if a page has submitable forms/entries |
| Controlled form filling, with pre-submit guardrails |
| Backlink opportunity queue and placement ledger |
| Cross-project cumulative paid backlink platform registry |
| Mechanical gatekeeper for data layer, must run after modifying data |
Supporting materials: (table collection techniques and anti-scraping constraints), .
backlink/references/harvest.mdpaid-platforms.md落盘:抓到的数据不许留在下载目录
Persistence: Never Leave Captured Data in Download Folder
配合上面任一抓取脚本时,首选本地接收端(页面 POST 到只监听 的服务,直接写进项目目录),退路才是下载目录 + 。完整规则见下面「导出物落盘 SOP」。接收端脚本属于项目侧,在登记表里找现成的,不要重写。
fetch127.0.0.1harvest-collect.shWhen using any of the above capture scripts, prefer local receivers (page POST to a service only listening on , directly write to the project directory), fallback to download folder + . Complete rules are in the "Export Persistence SOP" below. Receiver scripts belong to the project side, find existing ones in the registry, do not rewrite.
fetch127.0.0.1harvest-collect.sh安装、版本与自动更新
Installation, Version & Auto-Update
全局安装
Global installation
npx skills add yan-labs/yan-skills --skill rankup -g -y
npx skills add yan-labs/yan-skills --skill rankup -g -y
全局更新
Global update
npx skills update rankup -g -y
npx skills update rankup -g -y
项目级更新
Project-level update
npx skills update rankup -p -y
本 Skill 的发布版本记录在同目录 `skill.json`。项目的启用时间、已安装版本和最近检查状态记录在 `.rankup/skill-state.json`。
每次激活 `rankup` 时,定位当前 `SKILL.md` 所在目录并执行:
```bash
node "<rankup-skill-dir>/scripts/check-version.mjs" \
--project-root . \
--apply检查脚本默认最多每 24 小时访问一次远端清单。它只更新 Skill,不修改业务代码、不部署网站,也不覆盖项目 。
rankup.rankup/自动更新在两种情况下必须拒绝执行并报告原因:
- 源码检出():仓库根存在
source-checkout标记,说明当前运行的就是 Skill 源码本身,通常还被全局技能目录符号链接过来。此时更新会覆盖未发布的改动,并把符号链接换回实体目录副本,重新变回双份维护。该标记只在仓库根,.skill-source只复制单个 Skill 子目录,因此不会随安装副本分发,也不会误伤项目级安装。skills add/update - 工作区有未提交修改()。
dirty-skill-checkout
若链接已被 换成实体目录,在仓库里运行 即可恢复;被替换掉的实体目录会先备份而不是删除。
skills updatenode scripts/link-skills.mjsinstalledAtrankupnpx skills update rankup -p -y
The release version of this Skill is recorded in the same directory's `skill.json`. The project's activation time, installed version, and latest check status are recorded in `.rankup/skill-state.json`.
Every time `rankup` is activated, locate the directory where the current `SKILL.md` resides and execute:
```bash
node "<rankup-skill-dir>/scripts/check-version.mjs" \
--project-root . \
--applyThe check script defaults to accessing the remote inventory at most once every 24 hours. It only updates the Skill, does not modify business code, deploy websites, or overwrite the project's .
rankup.rankup/Auto-update must be rejected and the reason reported in two cases:
- Source checkout (): A
source-checkoutmarker exists at the root of the repository, indicating that the currently running instance is the Skill source code itself, usually symlinked from the global skill directory. Updating at this point will overwrite unpublished changes and convert the symlink back to an entity directory copy, reverting to dual maintenance. This marker only exists at the repository root, and.skill-sourceonly copies individual Skill subdirectories, so it will not be distributed with installation copies and will not accidentally affect project-level installations.skills add/update - Uncommitted changes in workspace ().
dirty-skill-checkout
If the symlink has been converted to an entity directory by , run in the repository to restore it; the replaced entity directory will be backed up first instead of being deleted.
skills updatenode scripts/link-skills.mjsinstalledAtrankup强制启动协议
Mandatory Startup Protocol
每次使用必须按顺序执行:
- 读取同目录 ,运行上面的版本检查;网络失败时保留当前版本继续,不得伪称已经更新。
skill.json - 读取项目 和
.rankup/INDEX.md;目录不存在时按.rankup/skill-state.json初始化。references/project-memory.md - 读取 及当前任务相关文件,不要无差别加载整个日志目录。
.rankup/PROJECT.md - 三方对账门禁:在回答“接下来做什么”或宣称任何进度之前,必须交叉核对三个来源——、真实路由/页面清单、线上
git log --oneline -25的全量sitemap.xml。<loc>的勾选框、仓库根的.rankup/plan.md、autopilot 状态文件都是滞后指标,读到“未开始”要先去代码里验证。三方结果与记录不一致时,先回写progress.md再继续,不能只在回复里口头更正。Cloudflare、GSC、Stripe、索引、外链等外部状态一律以当前查询结果为准,知识库只当线索不当证据。.rankup/ - 判断任务处于哪个生命周期阶段,只读取需要的参考文件和专项 Skill。若本轮需要某类可复用操作(导数据、查词、抓 SERP 等),先查跨项目资产登记表看别的项目有没有现成脚本,有就取用,不要重写。
- 实施请求范围内的工作,执行与风险相称的测试,并验证真实目标环境。
- 更新 中的事实、决策、计划、发布或日志;同步
.rankup/的更新时间和导航。INDEX.md
已有项目没有 时,只补建项目记忆,不得因此重新初始化技术栈。只有用户确实要求创建新站时才执行建站脚手架。
.rankup/Must execute in order every time:
- Read the same directory's , run the version check above; if network fails, keep the current version and continue, do not falsely claim to have updated.
skill.json - Read the project's and
.rankup/INDEX.md; if the directory does not exist, initialize it according to.rankup/skill-state.json.references/project-memory.md - Read and files related to the current task, do not load the entire log directory indiscriminately.
.rankup/PROJECT.md - Triple Reconciliation Gatekeeper: Before answering "What to do next" or claiming any progress, must cross-verify three sources—, real route/page list, all
git log --oneline -25entries in online<loc>. Checkboxes insitemap.xml,.rankup/plan.mdat the repository root, and autopilot status files are lagging indicators; if reading "not started", first verify in the code. If there is inconsistency between the triple results and records, write back toprogress.mdfirst before continuing, do not only verbally correct in the reply. External statuses such as Cloudflare, GSC, Stripe, indexing, backlinks must all be based on current query results; the knowledge base is only used as a clue, not evidence..rankup/ - Determine which lifecycle stage the task is in, only read required reference files and specialized Skills. If this round requires a type of reusable operation (data export, keyword checking, SERP capture, etc.), first check the cross-project asset registry to see if another project has an existing script, use it if available, do not rewrite.
- Execute work within the scope of the request, perform tests proportional to the risk, and verify the real target environment.
- Update facts, decisions, plans, releases or logs in ; synchronize the update time and navigation in
.rankup/.INDEX.md
For existing projects without , only supplement project memory, do not reinitialize the technology stack. Only execute the website scaffolding when the user explicitly requests to create a new site.
.rankup/可复用操作必须落成脚本
Reusable Operations Must Be Turned into Scripts
任何需要第二次执行的操作,第一次跑通时就必须固化成脚本,不允许下次重新摸索。 浏览器操作是最主要的适用对象:切换 GSC property、导出效果报告、在关键词工具里查一批词、抓 SERP 前十结构——这些每次重新试探都在重复烧上下文,且每次的做法都不一样,结果不可比。
判定与动作:
- 判定:操作满足“会再做一次”或“换个站/换个词就要重跑”时,即为可复用操作。一次性排查不适用。
- 固化:跑通后立即写入 (如
<project>/.rankup/scripts/<动词-对象>.mjs、gsc-switch-property.mjs、gsc-export-queries.mjs)。脚本必须参数化(property、日期范围、词、国家),不得把某一次的具体值写死。serp-top10.mjs - 登记:在 记一行——用途、参数、依赖的登录态、已验证日期。
.rankup/INDEX.md - 复用:之后先执行脚本,不重新摸索 DOM。
- 维护:脚本失败时修脚本,不是绕过它手工再点一遍。页面改版属于正常损耗,修完更新已验证日期。失败原因写进脚本头部注释,下次少走一遍。
脚本与它依赖的登录态、property ID、账号配置都属于项目侧,只放 ,不进本 Skill。本 Skill 只描述方法,不携带任何具体站点的操作参数。
<project>/.rankup/Any operation that needs to be executed a second time must be solidified into a script the first time it runs successfully—re-exploring the process next time is not allowed. Browser operations are the primary applicable objects: switching GSC property, exporting performance reports, checking a batch of keywords in a keyword tool, capturing the top 10 SERP structure—re-exploring these processes every time wastes context, and each approach is different, making results incomparable.
Judgment and Actions:
- Judgment: An operation is reusable if it meets "will be done again" or "needs to be rerun for a different site/keyword". One-time troubleshooting does not apply.
- Solidification: After running successfully, immediately write to (e.g.,
<project>/.rankup/scripts/<verb-object>.mjs,gsc-switch-property.mjs,gsc-export-queries.mjs). Scripts must be parameterized (property, date range, keyword, country), do not hardcode specific values from a single run.serp-top10.mjs - Registration: Record a line in —purpose, parameters, required login state, verified date.
.rankup/INDEX.md - Reuse: Execute the script first in subsequent runs, do not re-explore the DOM.
- Maintenance: Fix the script when it fails, do not bypass it and click manually again. Page revisions are normal wear and tear; update the verified date after fixing. Write the failure reason in the script header comment to avoid repeating the same steps next time.
Scripts and their dependent login states, property IDs, account configurations belong to the project side, only stored in , not included in this Skill. This Skill only describes methods, does not carry any operation parameters for specific sites.
<project>/.rankup/浏览器一律用用户自己的浏览器
Always Use the User's Own Browser for Browser Operations
凡是需要登录态的页面操作,必须驱动用户本机那个真实的、已登录的浏览器,
不得使用运行环境自带的沙箱浏览器。
理由不是偏好。沙箱浏览器是一个干净的独立实例,没有用户的 cookie 和会话,
于是所有要登录的目标要么直接跳登录页、要么以匿名身份返回看起来正常但内容不同的结果
(配额更低、字段更少、国家库不同)。这种失败会伪装成「这个工具没有这项数据」,
而正确的结论其实是「你没登录」。用户的登录态本身就是这类任务能成立的前提。
判定很简单:这个页面如果用无痕窗口打开,还是不是同一个东西? 答案是「不是」,
就必须走用户的浏览器。
- 要登录的一切(第三方 SEO/数据面板、Search Console、社区后台、聊天式 AI 工具)→ 用户的浏览器。
- 沙箱浏览器只在完全不需要身份的场景才可用:读一个公开页面、验证自己刚部署的站点。
即使那样,也先问一句有没有更省事的路径(、公开 API),不要为了看一段公开文本开一个浏览器。
curl
For any page operation requiring login state, must drive the user's local, real, logged-in browser; do not use the sandbox browser provided by the runtime environment.
This is not a matter of preference. The sandbox browser is a clean, independent instance without the user's cookies and sessions, so all targets requiring login will either redirect directly to the login page, or return results that look normal but have different content (lower quotas, fewer fields, different country libraries) when accessed anonymously. This failure will be disguised as "this tool does not have this data", while the correct conclusion is actually "you are not logged in". The user's login state is a prerequisite for such tasks to be feasible.
The judgment is simple: If you open this page in incognito mode, is it the same thing? If the answer is "no", you must use the user's browser.
- Everything requiring login (third-party SEO/data panels, Search Console, community backends, chat-based AI tools) → user's browser.
- Sandbox browser is only available in scenarios that completely do not require identity: reading a public page, verifying a site you just deployed. Even then, first ask if there is a more convenient path (, public API), do not open a browser just to read a piece of public text.
curl
会话/标签页必须按对话隔离
Sessions/Tabs Must Be Isolated by Conversation
用浏览器自动化 CLI(如 OpenCLI)时,会话名就是标签页的所有权声明。
同名会话共用同一个标签页,不同名之间互不干扰。所以「我的标签页被别人抢了」
只有一个成因:两个任务挑了同一个会话名。
症状极其阴险:导航报成功,随后读回来的却是另一个任务打开的页面——
数据是别人的,而全程没有任何报错。
- 不许把字面常量当默认会话名。 默认值必须带一个每次对话唯一的后缀 (宿主会话 id、进程 id 均可),并保留显式覆盖的入口。
- 读回来的页面不是你导航过去的那个,先怀疑会话撞名,再怀疑站点或 CLI。
- 用完主动关闭会话,把标签页的租约还回去。
这条与下一节「接收端端口不能写死」是同一条原则的两个面:
任何跨任务共享的具名资源(会话名、端口、锁文件、固定临时路径),
都必须按调用方派生,并提供一个核对自己连对了没有的手段。
When using browser automation CLIs (such as OpenCLI), the session name is a declaration of tab ownership. Sessions with the same name share the same tab, while sessions with different names do not interfere with each other. So the only cause of "my tab was hijacked by someone else" is: two tasks chose the same session name.
The symptom is extremely insidious: navigation reports success, but the page read back is the page opened by another task—the data belongs to someone else, and there is no error throughout the process.
- Do not use literal constants as the default session name. The default value must include a suffix unique to each conversation (host session ID, process ID, etc.), and retain an entry for explicit override.
- If the page read back is not the one you navigated to, suspect session name collision first, then suspect the site or CLI.
- Actively close the session after use, return the tab lease.
This and the next section "Receiver Port Cannot Be Hardcoded" are two sides of the same principle: Any named resource shared across tasks (session name, port, lock file, fixed temporary path) must be derived from the caller, and provide a way to verify that you are connecting to the correct one.
导出物落盘 SOP(强制)
Export Persistence SOP (Mandatory)
从浏览器、后台或第三方工具导出的任何数据文件,绝不允许留在浏览器默认下载目录。
这不是整洁问题。默认下载目录是所有下载共用的垃圾场:文件会被随手清空、会被同名下载覆盖成
、跨轮次跨项目混在一起无法区分,而这些文件往往是扣了额度或花了几十分钟才拿到、
且无法凭记忆重建的一次性产物。丢了就得重抓。
xxx (1)Any data file exported from browsers, backends or third-party tools must never be left in the browser's default download folder.
This is not a cleanliness issue. The default download folder is a shared dump for all downloads: files will be deleted casually, overwritten with names like by same-name downloads, mixed together across rounds and projects making them indistinguishable, and these files are often one-time products obtained after using quotas or spending dozens of minutes, which cannot be reconstructed from memory. If lost, you have to recapture them.
xxx (1)先问「有没有免费的导出」,再考虑抓取
First Ask "Is There a Free Export", Then Consider Capture
滚动抓取是兜底手段,不是默认手段。抓一页表要几十次滚动、要防节流、要拼行,
而很多后台本来就有一个点一下就给 CSV 的按钮。开抓之前先花一分钟找这个按钮。
同名控件陷阱(已两次踩到):同一个报表上常常并排放着两个名字高度相似的导出控件,
一个走付费配额、一个免费导当前页,行为完全相反。只试了其中一个就写下
「导出被锁,只能抓取」的结论,会把后续所有人都带进沟里,而且这条错误结论会被写进
文档长期生效。判据:凡是要写下「某功能不可用」,先确认你点的是不是同名的另一个控件。
另外,免费导出常常是静默下载——点完页面上没有任何视觉反馈。
不要因为「看起来没反应」就判定失败,去下载目录确认。
同一个工具里,不同报表的导出模型可以完全不同。 在 A 报表上验证出「整包导出被锁、
只能一页一页导」,不构成 B 报表的结论——B 很可能一次就把几千行全给你,而且免费。
在 A 上得出的规避方案照搬到 B,代价是白白多跑几十次翻页。每换一个报表,重新看一眼导出面板。
一个页面上可能有多个长得一样的导出图标。 见过的形态:报表标题栏一个「导出成 PDF」、
表格卡片上一个数据导出,两者挂着同一个属性值,按属性 会稳定取到 PDF 那个,
表现为弹出一个 PDF 设置弹窗然后等不到 CSV 按钮而超时。按文案排除,不要靠出现顺序。
querySelector导出触发器常常是 图标而不是按钮。 SVG 元素没有 方法,
直接调会报 ;要 往上找真正的按钮。
另外这类面板是异步挂载的,实测要两三秒——按坐标点会在这里稳定失联,
必须轮询等目标按钮出现再点,不要用固定 sleep。
<svg>.click()x.click is not a functionclosest('button,[role=button],a')分页导出还有两个反复出现的形态,写驱动时按这个来:
- 分页多半是 URL 驱动的(点下一页后 URL 多出 )。确认之后就可以直接拼 URL, 不必依赖点击。
page=N - 翻页后表格会短暂重挂载,导出按钮会消失几百毫秒。等待条件必须是 「按钮回来了」而不只是「数据变了」——只等后者会稳定地在第 2 页失败。
Scroll capture is a fallback method, not the default. Capturing a table requires dozens of scrolls, anti-throttling measures, and row stitching, while many backends have a button that generates a CSV with one click. Spend one minute looking for this button before starting capture.
Same-Name Control Trap (Encountered Twice): There are often two export controls with highly similar names placed side by side on the same report—one uses paid quotas, one exports the current page for free, with completely opposite behaviors. Writing the conclusion "Export is locked, only capture is possible" after trying only one of them will lead everyone else into a trap, and this wrong conclusion will be written into documents and remain valid for a long time. Criterion: Before writing "a certain function is unavailable", first confirm that you are not clicking a different control with the same name.
In addition, free exports are often silent downloads—there is no visual feedback on the page after clicking. Do not judge failure just because "it seems to have no reaction", check the download folder.
Different reports in the same tool can have completely different export models. Verifying on report A that "full export is locked, only page-by-page export is allowed" does not constitute a conclusion for report B—report B may give you thousands of rows at once for free. Applying the workaround from A to B will result in unnecessarily running dozens of page turns. Check the export panel again every time you switch reports.
There may be multiple identical-looking export icons on a single page. Seen forms: one "Export as PDF" in the report title bar, one data export on the table card, both with the same attribute value, using by attribute will stably retrieve the PDF one, resulting in a PDF settings popup appearing and timing out waiting for the CSV button. Filter by text, do not rely on appearance order.
querySelectorExport triggers are often icons instead of buttons. SVG elements do not have a method; calling it directly will throw ; you need to to find the real button above. In addition, such panels are mounted asynchronously, taking two to three seconds in practice—clicking by coordinates will stably fail here, must poll until the target button appears before clicking, do not use fixed sleep.
<svg>.click()x.click is not a functionclosest('button,[role=button],a')There are two recurring patterns for paginated exports, follow this when writing drivers:
- Pagination is mostly URL-driven (URL adds after clicking next page). After confirming this, you can directly construct the URL instead of relying on clicks.
page=N - The table will be remounted briefly after page turning, and the export button will disappear for hundreds of milliseconds. The waiting condition must be "the button is back" instead of just "data has changed"—waiting only for the latter will stably fail on page 2.
首选:本地接收端,根本不走下载目录
Preferred: Local Receiver, Bypass the Download Folder Entirely
页面 JS 没有文件系统, 只能落到浏览器默认目录 —— 这一步无法从页面内改道。
但可以绕开整条下载链路:在本机起一个只监听 的接收服务,
让页面把数据 过去,服务端直接写进项目目录。
<a download>127.0.0.1fetch(..., {method:'POST'})这是首选方案,因为它一次性消掉四个问题:不需要等文件落齐、不需要归并重名副本、
不受下载目录权限影响、也不占用对话上下文。实测被采集页面的 CSP 通常不拦截到
的请求(先用一个 端点验证连通再开跑)。
127.0.0.1/ping服务端要点:只绑 ;开 CORS(页面在 https 源上,属于跨源);
对路径参数做白名单字符校验防目录穿越;落盘同时写 manifest 并回报行数。
127.0.0.1接收端还应该提供一个只读的 端点,把本机的提取器源码喂给页面,
页面一行 就注入完成。这不是锦上添花:注入提取器的唯一通道本来是
把整份脚本当字符串塞进「在页面执行 JS」的工具,而那会把脚本全文灌进对话上下文——
于是每次都有人为了省这点开销现写一个精简版,也就是重造轮子。加上这个端点,
注入成本归零,重造的动机也就没有了。只允许白名单里的绝对路径,不接受调用方传路径。
GET /script?name=<白名单名>fetch(...).then(eval)接收端的端口不能写死成一个常量,理由和浏览器自动化里「session 名不能写死」完全同构。
端口是跨任务共享的本机资源:两个项目同时开工时,第二个实例 起不来,
而后台常驻的常见写法会把输出丢进 ,于是这个失败是完全静默的。
随后页面的 照样返回 200——打到的是另一个项目的接收端,
数据写进别人的目录, 取到别人的脚本,全程零报错。
这类「报成功、拿到别人的东西」的故障,比直接崩掉难查一个数量级。
EADDRINUSE/dev/nullfetch/script三条一起做,缺一条都堵不住:
- 默认端口按项目根路径派生(哈希到一个固定区间),显式 只在需要固定值时传。
--port - 占用时崩掉并说清占用者是谁,绝不静默退让到别的端口或复用现有实例。
监听失败要打印排查命令,不要只抛一个 。
EADDRINUSE - 回报自己服务的根目录,实际端口写进项目内一个小文件, 页面侧和其它脚本读那个文件而不是硬编码。注入前先核对
/ping的 root 是不是本项目。/ping
同一条原则适用于任何跨任务共享的本机资源:固定端口、固定临时文件名、固定锁文件、
浏览器自动化的会话名。判据:这个名字/端口如果被另一个任务同时用上,我会不会拿到它的数据
却看不出异常? 答案是「会」,就必须按项目派生并加核对。
为什么这条要排在下载法前面:浏览器默认下载目录在部分系统上受隐私保护,
终端与脚本可能根本读不到(实测 shell 与 Node 同时 ),
而这种权限状态可能在任务中途才生效。届时所有已下载的数据都拿不回来。
接收端方案不依赖那个目录,因此不会中途失效。
EPERMPage JS does not have a file system, can only go to the browser's default directory—this step cannot be redirected from within the page. But you can bypass the entire download chain: start a receiver service on the local machine that only listens on , let the page the data to it, and the server writes directly to the project directory.
<a download>127.0.0.1fetch(..., {method:'POST'})This is the preferred solution because it eliminates four problems at once: no need to wait for files to complete, no need to merge duplicate copies, no impact from download folder permissions, and no occupation of conversation context. In practice, the CSP of the captured page usually does not block requests to (verify connectivity with a endpoint first before starting).
127.0.0.1/pingServer requirements: only bind to ; enable CORS (the page is on an https origin, which is cross-origin); whitelist path parameters to prevent directory traversal; write a manifest while persisting and report the number of rows.
127.0.0.1The receiver should also provide a read-only endpoint to feed the local extractor source code to the page, which can be injected with one line of on the page. This is not a nice-to-have: the only way to inject the extractor was to feed the entire script as a string into the "execute JS on page" tool, which would flood the conversation context with the full script text—so every time someone would write a simplified version on the spot to save this overhead, i.e., reinvent the wheel. Adding this endpoint reduces injection cost to zero, eliminating the motivation to reinvent the wheel. Only allow absolute paths in the whitelist, do not accept paths passed by the caller.
GET /script?name=<whitelist-name>fetch(...).then(eval)The receiver's port cannot be hardcoded as a constant, for the exact same reason as "session name cannot be hardcoded" in browser automation. Ports are local resources shared across tasks: when two projects start at the same time, the second instance will fail to start with , and common background resident methods will dump output into , so this failure is completely silent. Then the page's will still return 200—hitting another project's receiver, data is written to someone else's directory, retrieves someone else's script, with zero errors throughout. This type of "reports success, gets someone else's data" failure is an order of magnitude harder to troubleshoot than a direct crash.
EADDRINUSE/dev/nullfetch/scriptDo all three together, missing one will not block the problem:
- Default port is derived from the project root path (hashed to a fixed range), explicit is only passed when a fixed value is needed.
--port - Crash and clearly state who is occupying the port when occupied, never silently fall back to another port or reuse an existing instance. Print troubleshooting commands when listening fails, do not just throw an .
EADDRINUSE - returns the root directory of the service, write the actual port into a small file in the project, and the page side and other scripts read that file instead of hardcoding. Check if the root from
/pingmatches the current project before injection./ping
The same principle applies to any local resource shared across tasks: fixed ports, fixed temporary file names, fixed lock files, session names for browser automation. Criterion: If another task uses this name/port at the same time, will I get its data without noticing? If the answer is "yes", it must be derived by project and verified.
Why this is prioritized over the download method: The browser's default download folder is protected by privacy settings on some systems, and terminals and scripts may not be able to read it at all (tested with shell and Node both throwing ), and this permission state may take effect halfway through the task. At that point, all downloaded data cannot be retrieved. The receiver solution does not rely on that directory, so it will not fail halfway.
EPERM退路:仍然走下载目录时
Fallback: Still Use the Download Folder
若无法起本地服务,则落盘必须由项目侧的一个脚本在抓取结束后立刻完成,
而不是靠事后想起来手工搬。
If a local service cannot be started, persistence must be done immediately after capture by a project-side script, not by manually moving files later when you remember.
强制规则
Mandatory Rules
- 落到项目里。每个项目在 之外维护自己的数据目录(例如
.rankup/、data/<主题>/raw/),原始导出物与派生产物分开放。data/<主题>/out/ - 抓完立刻搬,不允许攒。每一轮抓取结束就跑落盘脚本,中间不插入别的抓取。 攒到最后搬的后果是无法分辨哪个文件属于哪一轮。
- 搬走而非复制。源文件必须从下载目录删除 —— 留一份在那里,问题就还在。
- 规范文件名,且必须自带足以区分轮次的信息:
。用参数拼名字,不要用「导出(3)」这种。
<主题>__<类型>__<切片/参数>__<日期>.<扩展名> - 等齐再搬。Blob/异步下载的最后一个文件常晚几秒落盘,提前搬会静默丢文件 而下游报告看起来完全正常。判据是「文件数达标 且 连续两次采样各文件大小不变」。
- 归并重名副本。浏览器对同名下载不覆盖,而是另存为 、
xxx (1),甚至丢掉扩展名, 且这些副本内容可能不同(重试过的目标必然产生多份)。同一逻辑切片只保留数据行最多的那份, 其余删除,不要让通配符把两份内容不同的文件都算进结果。xxx (2) - 落盘即校验并记 manifest:每个文件的数据行数、字节数、落盘日期写进同目录的
。行数为 0 的文件必须报错退出,不能进入下一轮 —— 空文件是抓取失败的信号, 静默通过会让最终报告缺一整块而无人察觉。
manifest.json - 脚本参数化:主题、类型、期望文件数、超时都从命令行传,不写死。
落盘脚本本身属于可复用操作,按上一节固化进 并登记到 。
具体的表格采集技巧、反爬约束与踩坑清单见
的「登录态后台批量取数」一节。
<project>/.rankup/scripts/INDEX.mdreferences/integrations.md- Persist into the project. Each project maintains its own data directory outside (e.g.,
.rankup/,data/<topic>/raw/), separating original exports and derived products.data/<topic>/out/ - Move immediately after capture, do not accumulate. Run the persistence script immediately after each round of capture, do not insert other captures in between. Accumulating until the end to move will make it impossible to distinguish which file belongs to which round.
- Move instead of copy. Source files must be deleted from the download folder—leaving a copy there means the problem still exists.
- Standardize file names, which must include information sufficient to distinguish rounds: . Use parameters to construct names, do not use names like "Export(3)".
<topic>__<type>__<slice/parameter>__<date>.<extension> - Wait until all files are complete before moving. The last file of Blob/asynchronous downloads often takes a few seconds to persist; moving early will silently lose files while downstream reports look completely normal. Criterion: "File count meets requirement and file sizes remain unchanged in two consecutive samples".
- Merge duplicate copies. The browser does not overwrite same-name downloads, but saves them as ,
xxx (1), even dropping the extension, and these copies may have different content (retrying the target will inevitably produce multiple copies). Only keep the copy with the most data rows for the same logical slice, delete the rest, do not let wildcards include two files with different content in the results.xxx (2) - Validate and write manifest immediately after persistence: Write the number of data rows, byte size, and persistence date of each file into in the same directory. Files with 0 rows must throw an error and exit, cannot proceed to the next round—empty files are a signal of capture failure, and silent passing will make the final report missing a whole block without anyone noticing.
manifest.json - Parameterize the script: Topic, type, expected file count, timeout are all passed from the command line, do not hardcode.
The persistence script itself is a reusable operation, solidified into and registered in according to the previous section. Specific table collection techniques, anti-scraping constraints and troubleshooting lists can be found in the "Batch Data Extraction from Authenticated Backends" section of .
<project>/.rankup/scripts/INDEX.mdreferences/integrations.md跨项目资产登记表
Cross-Project Asset Registry
各项目的 互不可见,默认是信息孤岛:A 项目已经写好的 GSC 导出脚本,在 B 项目里不会有人知道。登记表把这些资产索引到一处。
.rankup/bash
undefinedThe directories of each project are invisible to each other, defaulting to information silos: a GSC export script already written in project A will not be known in project B. The registry indexes these assets in one place.
.rankup/bash
undefined重建名单(扫描各项目 .rankup/,整表覆盖)
Rebuild the list (scan .rankup/ of each project, overwrite entire table)
node "<rankup-skill-dir>/scripts/registry.mjs" scan --roots <存放项目的目录>
node "<rankup-skill-dir>/scripts/registry.mjs" scan --roots <directory storing projects>
查看名单
View the list
node "<rankup-skill-dir>/scripts/registry.mjs" list
- **位置**:Skill 目录下的 `registry.md`,挨着 `SKILL.md`,用的时候一眼看得到(可用 `RANKUP_REGISTRY_PATH` 改道)。它必须写出项目名与绝对路径才有用,因此被 `rankup/.gitignore` 排除,并由 `scripts/validate-rankup.mjs` **断言绝不能被 git 追踪**——`.gitignore` 只是约定,一个 `git add -f` 就能绕过。名单也因此被豁免参与项目中立扫描,而这条豁免的唯一依据就是那条断言。
- **扫描根目录**:来自 `--roots`、环境变量 `RANKUP_PROJECT_ROOTS`,或 `~/.rankup/config.json` 的 `projectRoots`。绝不写死在脚本里。
- **生成而非手写**:每次 `scan` 整表重建,读到的永远是磁盘当前事实。手工维护的索引必然过期,这是已验证的反模式。
- **启动时读它**:本 Skill 激活后若发现当前任务需要某类可复用操作,先查名单看别的项目有没有现成的,有就去对应路径取,不要重写一遍。
- **只索引不复制**:名单不搬运内容。取用别的项目的脚本时连同参数约定一起看;登录态、property ID、账号配置不跨项目照抄。
- **回流信号**:某个脚本被第二个项目用上,说明它足够通用,考虑把**做法**提炼成规则回流本 Skill(仍然不带任何项目信息)。node "<rankup-skill-dir>/scripts/registry.mjs" list
- **Location**: `registry.md` in the Skill directory, next to `SKILL.md`, easily visible when in use (can be redirected with `RANKUP_REGISTRY_PATH`). It must write the project name and absolute path to be useful, so it is excluded by `rankup/.gitignore`, and `scripts/validate-rankup.mjs` **asserts that it must not be tracked by git**—`.gitignore` is only a convention, a `git add -f` can bypass it. The list is therefore exempt from project neutrality scanning, and the only basis for this exemption is that assertion.
- **Scan root directories**: From `--roots`, environment variable `RANKUP_PROJECT_ROOTS`, or `projectRoots` in `~/.rankup/config.json`. Never hardcode in the script.
- **Generated instead of manually written**: The entire table is rebuilt on each `scan`, always reading the current facts on disk. Manually maintained indexes will inevitably become outdated, which is a verified anti-pattern.
- **Read it on startup**: After this Skill is activated, if it finds that the current task requires a type of reusable operation, first check the list to see if another project has an existing solution, retrieve it from the corresponding path if available, do not rewrite.
- **Only index, do not copy**: The list does not move content. When using scripts from other projects, check the parameter conventions together; do not copy login states, property IDs, or account configurations across projects.
- **Signal feedback**: If a script is used by a second project, it means it is universal enough, consider refining the **method** into rules and feeding back to this Skill (still without any project information).命令
Commands
两个入口,覆盖「刚接手」和「回头看」,用户只说 / 即可,不必描述要做什么。
rankup initrankup reviewTwo entry points, covering "just taking over" and "looking back". Users only need to say / , no need to describe what to do.
rankup initrankup reviewrankup init
— 把项目接入 rankup
rankup initrankup init
— Connect the Project to rankup
rankup init适用于全新项目,也适用于已经做了很久但还没有 的项目。后者是常态,不得因为缺记忆就重建技术栈。
.rankup/- 摸清现状再写字:读 、路由/页面清单、部署配置、
package.json,确认框架、技术栈、部署目标与真实生产域名。已上线的再取git log、sitemap.xml、首页与关键页的线上响应。robots.txt - 查外部系统:域名是否解析、Cloudflare/托管方是否在跑、GSC 是否接入、是否有支付。一律实时查询,不采信任何文档里的说法。
- 建目录:按 创建
references/project-memory.md全套。已有事实直接填,取不到的写.rankup/,不要猜。待确认 - 已运行项目补基线:记一次当前流量、索引、性能与收入基线到 ,作为后续对比的起点;同时做一轮技术体检写入
baseline.md。audit.md - 定方向:写阶段目标与放弃条件,
roadmap.md写 P0–P2 及完成判定。plan.md - 建仓并推远端(绿地项目在脚手架跑通后立刻做,不要等「做出点东西再说」):
先确认脚手架是否已自带本地仓库,避免重复 ;提交前扫一遍将要入库的内容, 凭据与账号配置一律不得入库;远端默认私有——未上线项目的仓库里带着选题、 竞品调研与定价策略,公开等于把选题送人,要公开必须用户明确要求。
git init随仓库一起提交,它是这个项目最贵的资产。细节见.rankup/阶段 3 的「Git 与远端」。lifecycle.md - 汇报:填了什么、哪些是 、哪些需要用户提供(账号授权、token、DNS 等)。凭据只登记名称与存放位置,真实值不入库。
待确认
已有 时 不覆盖,转为补齐缺失文件并提示用 。
.rankup/initreviewSuitable for brand new projects, as well as projects that have been running for a long time but do not have . The latter is the norm, do not rebuild the technology stack just because memory is missing.
.rankup/- Understand the current state before writing: Read , route/page list, deployment configuration,
package.json, confirm the framework, technology stack, deployment target and real production domain. For already launched sites, also retrievegit log,sitemap.xml, and online responses of the homepage and key pages.robots.txt - Check external systems: Whether the domain is resolved, whether Cloudflare/host is running, whether GSC is connected, whether there is payment integration. All queries are real-time, do not rely on any statements in documents.
- Create directory: Create the full set of according to
.rankup/. Fill in existing facts directly, write "To be confirmed" for unavailable information, do not guess.references/project-memory.md - Baseline supplement for running projects: Record the current traffic, indexing, performance and revenue baseline to as the starting point for future comparisons; at the same time, perform a technical health check and write to
baseline.md.audit.md - Set direction: Write phase goals and abandonment conditions in , write P0–P2 and completion criteria in
roadmap.md.plan.md - Create repository and push to remote (do this immediately after the scaffolding runs for greenfield projects, do not wait until "something is done"): First confirm whether the scaffolding already includes a local repository to avoid duplicate ; scan the content to be committed before committing, credentials and account configurations must not be committed; remote is private by default—the repository of an unlaunched project contains topic selection, competitor research and pricing strategies, making it public is equivalent to giving away the topic, and it must be explicitly requested by the user to make it public.
git initis committed with the repository, it is the most valuable asset of this project. Details can be found in the "Git and Remote" section of phase 3 in.rankup/.lifecycle.md - Report: What was filled in, which items are "To be confirmed", which require user provision (account authorization, token, DNS, etc.). Only record the name and storage location of credentials, do not commit the actual values.
When already exists, will not overwrite it, but instead supplement missing files and prompt to use .
.rankup/initreviewrankup review
— 回顾、筛选、补做
rankup reviewrankup review
— Review, Filter, Supplement
rankup review定期或阶段结束时执行。先跑体检脚本拿机械结论,再处理需要判断的部分。
bash
node "<rankup-skill-dir>/scripts/review.mjs" --project-root . --days 30脚本只读不改,给出:缺失文件、超期未更新的记录、脚本体检(有无已验证日期、是否参数化)、经验库信号(重复条目、候选回流 Skill 的条目)。
再挖会话记录——最有价值的经验往往还留在对话里,从没进过 :
.rankup/bash
undefinedExecute regularly or at the end of a phase. First run the health check script to get mechanical conclusions, then handle parts that require judgment.
bash
node "<rankup-skill-dir>/scripts/review.mjs" --project-root . --days 30The script is read-only and provides: missing files, expired records, script health check (whether it has a verified date, whether it is parameterized), experience library signals (duplicate entries, candidates for Skill feedback).
Then dig into session records—the most valuable experience is often still in conversations, never entered :
.rankup/bash
undefined先看有哪些会话、各自还有多少没读
First see which sessions exist and how much unread content each has
node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --new-only
node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --new-only
输出浓缩对话(只留人说的话与结论,丢掉工具调用与系统注入)
Output condensed conversations (only keep user's words and conclusions, discard tool calls and system injections)
node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --new-only --dump
node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --new-only --dump
全部消化完之后,才落水位线
Only set the watermark after all content is digested
node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --mark
**默认加 `--new-only`。** 水位线按字节偏移记在 `.rankup/review-state.json`:上次 review 读到哪,这次就从哪接着读;同一个会话后续续聊也只读新增那段。不加的话每次 review 都会把同样的对话重读一遍,纯属浪费。
`--mark` 是**独立一步,必须等信号真的提取完再执行**。中途失败或输出被预算截断时不落水位,下次仍会重读那一段——宁可重读,不可漏读。
覆盖当前项目的 Claude Code 与 Codex 会话,按记录里的 `cwd` 归属,worktree 与含空格的路径都能认。读浓缩稿时找四类东西:
- **用户的纠正**——「不对,应该是……」后面那句通常就是一条该沉淀的规则。
- **验证过的结论**——附了证据的判断;只有猜测没有验证的不要收。
- **踩过的坑与其根因**——尤其是排查花了很久的,写清判据让下次一眼认出。
- **已经推翻旧记录的事实**——`.rankup/` 里的对应条目要**修订**,不是并列再写一条。
在此之上完成:
1. **对账**:`plan.md` 的勾选是滞后指标,与 `git log`、路由清单、线上 `sitemap.xml` 三方交叉;不一致先回写再继续。
2. **筛信号**:`experience.md` 里合并重复、删除已过时、修订被证伪的条目——**修订原条目,不并列保留冲突结论**。未验证的猜测直接删。
3. **提炼回流**:剥离站点后仍成立的规则回流本 Skill,证据出处与数字留在项目侧。回流内容不得含站名、域名、流量数字、property ID。
4. **补脚本**:本轮有没有第二次重复的操作却没固化?脚本头部的已验证日期是否过期、还能不能跑?坏了就修,不绕过。
5. **补缺口**:`roadmap.md` 是否断更、`iterations.md` 是否漏记失败轮次(失败必须写清被证伪的假设)。
6. **刷新名单**:`node "<rankup-skill-dir>/scripts/registry.mjs" scan --roots <存放项目的目录>`。
7. **产出**:一页结论——修了什么、删了什么、回流了什么、下一轮唯一改进。能当场修的直接修,不要只列清单。node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --mark
**`--new-only` is enabled by default.** The watermark is recorded by byte offset in `.rankup/review-state.json`: where the last review stopped, this time continues from there; only the new part is read for subsequent chats in the same session. Without it, the same conversations will be reread every time, which is a pure waste.
`--mark` is an **independent step, must be executed only after signals are truly extracted**. Do not set the watermark if it fails halfway or the output is truncated by budget, the same section will be reread next time—it is better to reread than to miss.
Covers Claude Code and Codex sessions for the current project, attributed by `cwd` in the records, worktrees and paths with spaces are recognized. Look for four types of content when reading condensed transcripts:
- **User's corrections**——The sentence after "No, it should be..." is usually a rule that should be preserved.
- **Verified conclusions**——Judgments with evidence; do not collect guesses without verification.
- **Pitfalls encountered and their root causes**——Especially those that took a long time to troubleshoot, write clear criteria to recognize them at a glance next time.
- **Facts that have overturned old records**——The corresponding entries in `.rankup/` must be **revised**, not written alongside.
On this basis, complete:
1. **Reconciliation**: Checkboxes in `plan.md` are lagging indicators, cross-verify with `git log`, route list, and online `sitemap.xml`; write back first if inconsistent before continuing.
2. **Filter signals**: Merge duplicates, delete outdated entries, revise falsified entries in `experience.md`——**Revise the original entry, do not keep conflicting conclusions side by side**. Delete unverified guesses directly.
3. **Refine feedback**: Rules that still hold after stripping site-specific information are fed back to the relevant reference files of this Skill. Evidence sources and numbers remain in the project's `experience.md`.
4. **Supplement scripts**: Are there any operations repeated a second time in this round but not solidified? Is the verified date in the script header expired, can it still run? Fix it if broken, do not bypass.
5. **Fill gaps**: Is `roadmap.md` outdated, is `iterations.md` missing failed rounds (failed rounds must clearly write the falsified hypothesis)?
6. **Refresh the list**: `node "<rankup-skill-dir>/scripts/registry.mjs" scan --roots <directory storing projects>`.
7. **Output**: A page of conclusions——what was fixed, what was deleted, what was fed back, the only improvement for the next round. Fix what can be fixed immediately, do not just list items.任务路由
Task Routing
| 请求 | 必读参考 | 专项能力 |
|---|---|---|
| 新站、SaaS、工具站、产品设计、架构 | | 设计或开发相关 Skill |
| Cloudflare、Worker、数据库、存储、部署 | | Wrangler、workers-best-practices |
| 上线后接测量与品牌资产(favicon/图标集、分析、站长工具) | | |
| 新域名接入 Cloudflare、拿 NS、切 NS、DNSSEC | | 优先驱动用户的浏览器点 Add a domain;不可用时 |
| 支付、订阅、账单、Stripe | | stripe-best-practices |
| SEO、GSC、排名、关键词、CTR、索引、内容 | | SEO 或研究能力 |
| 关键词难度、SERP 盘面、页面体检、域名与外链估值 | | |
| 老站救不救、多语言怎么上、多站会不会自我重复、品牌名不显示、KGR 怎么算、页面下限 | | 无需工具,是裁定集 |
| 搜索热度对比、地区分布、相关飙升词、每日热搜、模糊方向扩词并收敛成可做站的词 | | |
| 从登录态后台批量取数(没有 API / API 收费 / 导出扣点数) | | backlink(读 |
| 「数据面板」「数据勘测」「查一下这个站/这个词的数据」 —— 用户说这些词时指的是第三方数据平台 | — | backlink(读 |
| 能力只有聊天网页形态(要登录、按条扣费、无 API),需反复提问并取回全文 | | |
| 外链、分发、竞品引用域 | | backlink |
| 付费外链平台、「竞品在哪买的链接」、投放平台估价 | | backlink(读 |
| 复盘、经验沉淀、自我进化、规则升级 | | 必要时使用独立 checker |
| 已有项目下一步、迭代、排障 | | 按缺口选择 |
找不到合适能力时,先按 使用 find-skills 搜索,不要先在 中复制一个新的专项 Skill。
integrations.mdrankup| Request | Required References | Specialized Capabilities |
|---|---|---|
| New site, SaaS, tool site, product design, architecture | | Design or development-related Skills |
| Cloudflare, Worker, database, storage, deployment | | Wrangler, workers-best-practices |
| Post-launch measurement and brand assets (favicon/icon set, analytics, webmaster tools) | Phase 7.5 of | |
| New domain onboarding to Cloudflare, obtain NS, switch NS, DNSSEC | "8.5 Domain Onboarding" in | Prioritize driving the user's browser to click Add a domain; use |
| Payment, subscription, billing, Stripe | | stripe-best-practices |
| SEO, GSC, rankings, keywords, CTR, indexing, content | | SEO or research capabilities |
| Keyword difficulty, SERP analysis, page health check, domain and backlink valuation | | |
| Should I rescue an old site, how to launch multilingual, will multiple sites self-compete, brand name not showing, how to calculate KGR, page lower limit | | No tools needed, it is a ruling set |
| Search popularity comparison, regional distribution, related rising keywords, daily trending searches, expand vague directions into keywords suitable for site building | | |
| Batch data extraction from authenticated backends (no API / API is paid / export uses quotas) | | backlink (read |
| "Data panel", "data survey", "Check data for this site/keyword" —— Users refer to third-party data platforms when saying these terms | — | backlink (read |
| Capability only exists in chat web form (requires login, charges per query, no API), need to ask repeated questions and retrieve full text | "Web-based AI Chatbot Answer Retrieval" in | |
| Backlinks, distribution, competitor reference domains | | backlink |
| Paid backlink platforms, "Where do competitors buy links", placement platform valuation | "After capturing competitor backlinks, must feed back to | backlink (read |
| Review, experience preservation, self-evolution, rule upgrade | | Use independent checker if necessary |
| Next steps for existing projects, iteration, troubleshooting | | Select based on gaps |
If no suitable capability is found, first use find-skills according to to search, do not first copy a new specialized Skill in .
integrations.mdrankup网站生命周期
Website Lifecycle
完整输入、动作、产出和完成门槛见 。总流程为:
references/lifecycle.md- 恢复项目上下文并与真实状态对账。
- 调研用户、需求、竞争、关键词和付费机会。
- 定义产品、页面、数据模型、架构和实施计划。
- 初始化或审计 Monorepo;新站使用批准的 TanStack Start 脚手架。
- 建立 Cloudflare SSR、API、数据、存储、环境和 bindings。
- 小步开发,完成类型、测试、构建和迁移验证。
- 按需接入 Stripe、邮件、分析、搜索平台等专项能力。
- 部署并验证真实域名、SSR、API、数据、上传、鉴权和回调。
- 执行技术 SEO、内容、索引和转化优化。
- 分析并执行合规的分发与外链工作。
- 监控、实验、复盘、记录并进入下一轮。
已有网站从当前相关阶段进入,不要求从阶段 1 重走全部流程。
Complete inputs, actions, outputs and completion thresholds can be found in . The overall process is:
references/lifecycle.md- Restore project context and reconcile with real status.
- Research users, needs, competition, keywords and paid opportunities.
- Define product, pages, data models, architecture and implementation plan.
- Initialize or audit Monorepo; use approved TanStack Start scaffolding for new sites.
- Set up Cloudflare SSR, API, data, storage, environment and bindings.
- Iterative development, complete type checking, testing, building and migration verification.
- Integrate specialized capabilities like Stripe, email, analytics, search platforms as needed.
- Deploy and verify real domain, SSR, API, data, upload, authentication and callbacks.
- Execute technical SEO, content creation, indexing and conversion optimization.
- Analyze and execute compliant distribution and backlink building.
- Monitor, experiment, review, record and enter the next round.
Existing websites enter from the relevant current phase, do not require re-running the entire process from phase 1.
默认建站栈
Default Website Building Stack
新建项目默认使用:
bash
pnpm dlx shadcn@latest init \
--preset b1D0eCA4 \
--template start \
--monorepo \
--rtl \
--pointer默认采用 Cloudflare-first:
- TanStack Start SSR、API 与服务端逻辑:Workers。
- 关系型和事务型数据:D1。
- 文件、图片、导出物和用户上传:R2。
- 缓存与读多写少配置:KV,不作为事务真源。
- 异步和多步骤任务:Queues / Workflows。
- 强一致协调与有状态实例:Durable Objects。
- 真实密钥:Worker Secrets、Cloudflare Secrets Store 或 CI Secrets。
资源必须按实际需求启用,不因“以后可能需要”提前创建。具体配置、环境隔离、迁移和线上验证见 。
references/cloudflare-stack.mdNew projects use by default:
bash
pnpm dlx shadcn@latest init \
--preset b1D0eCA4 \
--template start \
--monorepo \
--rtl \
--pointerDefault to Cloudflare-first:
- TanStack Start SSR, API and server-side logic: Workers.
- Relational and transactional data: D1.
- Files, images, exports and user uploads: R2.
- Caching and read-heavy configurations: KV, not used as transactional source of truth.
- Asynchronous and multi-step tasks: Queues / Workflows.
- Strongly consistent coordination and stateful instances: Durable Objects.
- Real secrets: Worker Secrets, Cloudflare Secrets Store or CI Secrets.
Resources must be enabled based on actual needs, do not create them in advance "just in case". Specific configuration, environment isolation, migration and online verification can be found in .
references/cloudflare-stack.md.rankup/
项目记忆
.rankup/.rankup/
Project Memory
.rankup/.rankup/references/project-memory.md最低要求:
- :导航、推荐阅读顺序、最近更新时间。
INDEX.md - :用户、定位、商业模式、目标和非目标。
PROJECT.md - :应用、数据、服务边界。
architecture.md - :环境、域名、Cloudflare 资源和非敏感 bindings。
infrastructure.md - :Stripe、邮件、分析和搜索平台状态。
integrations.md - :只记录名称、用途、环境、保管位置、负责人、访问与轮换状态。
secrets.md - :本地版本、启用时间、检查与更新时间。
skill-state.json - :长期方向、阶段目标、各阶段的判定条件与放弃条件。跨会话可续,不随单轮任务改写。
roadmap.md - :每轮迭代一段——做了什么、判据是什么、结果、下一轮唯一改进。失败轮次同样要记,且必须写清被证伪的假设。
iterations.md - :可复用操作脚本(见「可复用操作必须落成脚本」)。
scripts/ - :本站可复用结论的完整原文,含证据出处与数字。
experience.md - 、
baseline.md、keywords.md、decisions.md、audit.md、plan.md、experiments.md。releases.md - :按日期记录有复用价值的实施、运营、排障和增长过程。
journal/
沉淀义务与是否调用本 Skill 无关。 只要项目里存在 ,该项目中任何任务——不限于 SEO,包括功能开发、重构、排障、发版——完成后都必须回写可复用结论、裁决与长期规划。判据是“下次遇到同类问题能否少走一遍”,不是“这轮有没有走 rankup 流程”。用户没有显式要求也要写,写完在回复里提一句即可,不必请示。
.rankup/严禁在 Skill、、Git、测试或回复中保存真实密钥、token、密码、私钥、webhook secret、支付敏感数据或个人敏感信息。
.rankup/.rankup/references/project-memory.mdMinimum requirements:
- : Navigation, recommended reading order, latest update time.
INDEX.md - : Users, positioning, business model, goals and non-goals.
PROJECT.md - : Application, data, service boundaries.
architecture.md - : Environment, domain, Cloudflare resources and non-sensitive bindings.
infrastructure.md - : Stripe, email, analytics and search platform status.
integrations.md - : Only record name, purpose, environment, storage location, responsible person, access and rotation status.
secrets.md - : Local version, activation time, check and update time.
skill-state.json - : Long-term direction, phase goals, criteria and abandonment conditions for each phase. Can be continued across sessions, not rewritten with single-round tasks.
roadmap.md - : One section per iteration——what was done, what were the criteria, results, the only improvement for the next round. Failed rounds must also be recorded, and clearly write the falsified hypothesis.
iterations.md - : Reusable operation scripts (see "Reusable Operations Must Be Turned into Scripts").
scripts/ - : Full text of reusable conclusions for this site, including evidence sources and numbers.
experience.md - ,
baseline.md,keywords.md,decisions.md,audit.md,plan.md,experiments.md.releases.md - : Record reusable implementation, operation, troubleshooting and growth processes by date.
journal/
Persistence obligation is independent of whether this Skill is called. As long as exists in the project, any task in the project—not limited to SEO, including feature development, refactoring, troubleshooting, release—must write back reusable conclusions, rulings and long-term plans after completion. The criterion is "Can I take fewer steps next time when encountering similar problems", not "Did this round follow the rankup process". Write it even if the user does not explicitly request it, just mention it in the reply, no need to ask for permission.
.rankup/Strictly prohibit storing real secrets, tokens, passwords, private keys, webhook secrets, payment sensitive data or personal sensitive information in Skills, , Git, tests or replies.
.rankup/令牌统一放 Skill 根目录的 .env
.envTokens Are Unified in .env
at Skill Root Directory
.env本 Skill 依赖的第三方令牌,只有一份,放在 Skill 根目录的 ,所有项目共用。
.env<rankup-skill-dir>/.env # KEY=value,每行一个;已被本仓库 .gitignore 排除为什么是这里而不是各项目自己存:这些令牌属于工具账号(关键词难度、SERP、体检这类第三方服务),不属于任何一个站点。放进项目就会出现同一个令牌在 N 个项目里各存一份,过期时要改 N 处,而漏掉的那几处会以“配额用尽”“未授权”的面貌出现,排查方向完全错。放在 Skill 这一层,一处更新,全部项目立刻生效。
与项目侧 的分工不变,且不冲突:
secrets.md| 放什么 | 例子 | |
|---|---|---|
Skill 的 | 跨项目的工具账号令牌真实值 | 关键词/SERP 服务的 API 令牌 |
项目的 | 本项目专属凭据的名称、用途、保管位置,绝不写真实值 | 站点的部署密钥、支付密钥 |
规则:
- 必须被 排除,且要断言。 只写进
.gitignore不够——一个.gitignore就能绕过,所以由git add -f断言它不被 git 追踪,违反即构建失败。这与登记表scripts/validate-rankup.mjs用的是同一条防线。registry.md - 脚本读取顺序统一为:环境变量优先,再退到 Skill 的 。 两处都读得到时以环境变量为准,便于临时覆盖。
.env - 调用方脚本必须和驱动脚本用同一套解析。 只看环境变量的调用方会在令牌明明配好的情况下判定“没有令牌”,退回匿名档并撞上配额,而报错却在教人去设一个已经设好的变量——这类误诊极难排查,属于必须避免的失败形态。
- 令牌失效时更新这一个文件,不要在项目里另建副本。 发现某处读不到,正确动作是修读取逻辑,不是再抄一份。
- 真实值不出现在任何回复、日志、提交或落盘数据里。 需要说明时只说键名与所在文件。
安装本 Skill 后 不存在是正常状态:首次需要令牌时创建它,写入键值即可,无需其他配置。
.envThird-party tokens relied on by this Skill are stored in a single file at the Skill root directory, shared by all projects.
.env<rankup-skill-dir>/.env # KEY=value, one per line; excluded by this repository's .gitignoreWhy here instead of storing in each project: These tokens belong to tool accounts (third-party services like keyword difficulty, SERP, health check), not any single site. Storing them in projects will result in the same token being stored in N projects, requiring N changes when expired, and the missed ones will appear as "quota exhausted" or "unauthorized", leading to completely wrong troubleshooting directions. Storing at the Skill level, one update takes effect for all projects immediately.
The division of labor with the project's remains unchanged and does not conflict:
secrets.md| What to Store | Examples | |
|---|---|---|
Skill's | Actual values of cross-project tool account tokens | API tokens for keyword/SERP services |
Project's | Name, purpose, storage location of project-specific credentials, never write actual values | Site deployment secrets, payment secrets |
Rules:
- Must be excluded by and asserted. Only writing to
.gitignoreis not enough—a.gitignorecan bypass it, sogit add -fasserts that it is not tracked by git, and build fails if violated. This uses the same defense as the registryscripts/validate-rankup.mjs.registry.md - Unified script reading order: environment variables take priority, then fall back to Skill's . When both are available, environment variables take precedence for easy temporary override.
.env - Caller scripts must use the same parsing as driver scripts. Callers that only look at environment variables will determine "no token" even when the token is configured, fall back to anonymous mode and hit quotas, while the error message tells people to set a variable that is already set—this type of misdiagnosis is extremely hard to troubleshoot and must be avoided.
- Update this single file when tokens expire, do not create copies in projects. If a script cannot read the token somewhere, the correct action is to fix the reading logic, not copy it again.
- Actual values must not appear in any replies, logs, commits or persisted data. Only mention the key name and the file it is in when necessary.
It is normal for not to exist after installing this Skill: create it when tokens are first needed, write the key-value pairs, no other configuration required.
.env完成标准
Completion Criteria
一次 工作只有同时满足以下条件才算完成:
rankup- 用户要求的产出已经存在。
- 相关类型检查、测试、构建或迁移验证通过。
- 若涉及发布,真实线上目标和关键路径已验证;上传成功或 Worker Ready 不能单独证明完成。 若本轮初始化了绿地项目,远端仓库必须存在且当前状态已推送—— 只存在于单机上的脚手架不算完成。
- 相关 文件已更新,过时的交叉引用已一并修正。
.rankup/ - 说明完成内容、验证证据、仍存在的风险和需要用户处理的外部事项。
A task is only considered complete if all of the following conditions are met:
rankup- The output requested by the user exists.
- Relevant type checking, testing, building or migration verification passes.
- If release is involved, the real online target and critical path have been verified; successful upload or Worker Ready alone cannot prove completion. If a greenfield project was initialized in this round, the remote repository must exist and the current state has been pushed—a scaffolding only existing on a single machine does not count as complete.
- Relevant files have been updated, and outdated cross-references have been corrected together.
.rankup/ - Explain what was completed, verification evidence, remaining risks and external matters requiring user handling.
经验回流与版本升级
Experience Feedback and Version Upgrade
详细的失败分类、证据阶梯、适应性重试、规则晋升和淘汰流程见 。
references/evolution.md- 只对当前项目成立的事实、数字和排障过程写入项目 。
.rankup/ - 换一个项目仍成立且经过验证的规则,才可回流本 Skill 的相关参考文件。
- 本 Skill 必须保持项目中立与机器中立:站点名、域名、流量数字、证据出处、account/property ID、本机路径与代理、凭据位置一律不进 Skill。回流一条经验时只带走剥离站点后仍成立的规则,证据留在项目侧的 。此约束由
experience.md断言,违反即构建失败。scripts/validate-rankup.mjs - 不记录未验证猜测;若旧经验被证伪,应修订原条目而不是并列保留冲突结论。
- patch:文字、兼容性修复和小经验补充。
- minor:向后兼容的新工作流、集成或模板。
- major:目录协议、核心行为或兼容性发生破坏性变化。
- 发布新版本时,同时更新 的
SKILL.md、metadata.version、验证脚本预期和 README。skill.json
Detailed failure classification, evidence ladder, adaptive retry, rule promotion and elimination processes can be found in .
references/evolution.md- Facts, numbers and troubleshooting processes that only apply to the current project are written into the project's .
.rankup/ - Verified rules that still hold for other projects can be fed back to the relevant reference files of this Skill.
- This Skill must remain project-neutral and machine-neutral: Site names, domains, traffic numbers, evidence sources, account/property IDs, local paths and proxies, credential locations must never enter the Skill. When feeding back an experience, only take the rules that still hold after stripping site-specific information, evidence remains in the project's . This constraint is asserted by
experience.md, build fails if violated.scripts/validate-rankup.mjs - Do not record unverified guesses; if old experiences are falsified, revise the original entry instead of keeping conflicting conclusions side by side.
- patch: Text, compatibility fixes and small experience supplements.
- minor: Backward-compatible new workflows, integrations or templates.
- major: Destructive changes to directory protocols, core behaviors or compatibility.
- When releasing a new version, update in
metadata.version,SKILL.md, validation script expectations and README at the same time.skill.json