Rankup 2.0
is a master control Skill for the entire lifecycle of a website: it restores project context, determines the current phase, loads necessary specialized capabilities, completes real verification, and writes project facts, decisions and experiences back to
.
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
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);
- Current project's
<project>/.rankup/scripts/
;
- None of the above → only then write a new script.
Included in This Skill
| Script | Purpose | When to Use |
|---|
| A single script covering all backend-enabled tools from seo.web.cafe: for keyword difficulty + top 9 SERP analysis, for page health check, for ranking attribution, for backlink valuation, for website valuation, for domain background, for in-site SEO Agent | 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 |
scripts/chatbot-drive.browser.js
| 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 |
scripts/cf-analytics-setup.mjs
| Enables Cloudflare Web Analytics and retrieves the beacon. for read-only detection, to turn it on | When setting up measurement after a new site launches. Does not rely on any third-party accounts, should be done before GSC/GA |
scripts/cf-zone-setup.mjs
| Adds a domain to Cloudflare (zone onboarding) and retrieves the NS pair—Wrangler has no zone command, this fills that gap. for read-only detection, to set up a zone | 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 of each project to rebuild the cross-project asset registry | 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 , defaults to |
scripts/check-version.mjs
| Skill version check and auto-update | On every activation |
scripts/validate-rankup.mjs
| Mechanical gatekeeper for project neutrality and credential leakage | Must run after modifying the Skill |
Sibling Skill: (Authenticated Backend Data Extraction & Backlinks)
For any requirement to "extract tabular data from an authenticated SaaS backend", the entry point is here—do not write your own extractor.
| Script | Purpose |
|---|
backlink/scripts/harvest.browser.js
| Universal virtual scroll table extractor, run in browser code execution tools. → (do not await) → to poll → ; for batches, use HARVEST.crawl([{name,seed,type,hash}])
then poll . Modern data grids do not have , it reconstructs rows by Y-coordinate clustering and adapts column positions automatically |
backlink/scripts/harvest-collect.sh
| 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 |
backlink/scripts/harvest-merge.mjs
| Merges captured TSV files into clean CSV, with duplicate detection |
backlink/scripts/similarweb-query.mjs
| Queries traffic panels (performance / similar-sites) via OpenCLI. Requires two environment variables: TOOLS_SHARE_DASHBOARD_URL
and , will throw an error directly if not set instead of guessing |
backlink/scripts/similarweb-batch.mjs
| 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) |
backlink/scripts/inspect-page.mjs
| Detects if a page has submitable forms/entries |
backlink/scripts/safe-fill.mjs
| Controlled form filling, with pre-submit guardrails |
backlink/scripts/discovery-queue.mjs
/ | Backlink opportunity queue and placement ledger |
backlink/scripts/paid-platform-registry.mjs
| Cross-project cumulative paid backlink platform registry |
backlink/scripts/validate-data.mjs
| Mechanical gatekeeper for data layer, must run after modifying data |
Supporting materials:
backlink/references/harvest.md
(table collection techniques and anti-scraping constraints),
.
Persistence: Never Leave Captured Data in Download Folder
When 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.
Installation, Version & Auto-Update
bash
# Global installation
npx skills add yan-labs/yan-skills --skill rankup -g -y
# Global update
npx skills update rankup -g -y
# Project-level update
npx skills update rankup -p -y
The release version of this Skill is recorded in the same directory's
. The project's activation time, installed version, and latest check status are recorded in
.
Every time
is activated, locate the directory where the current
resides and execute:
bash
node "<rankup-skill-dir>/scripts/check-version.mjs" \
--project-root . \
--apply
The 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
.
Auto-update must be rejected and the reason reported in two cases:
- Source checkout (): A marker 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 only copies individual Skill subdirectories, so it will not be distributed with installation copies and will not accidentally affect project-level installations.
- Uncommitted changes in workspace ().
If the symlink has been converted to an entity directory by
, run
node scripts/link-skills.mjs
in the repository to restore it; the replaced entity directory will be backed up first instead of being deleted.
is the activation time recorded when the current project was first initialized or identified by
; the Skills CLI does not have a reliable post-install hook, so it must not be described as the exact time the CLI copied files.
Mandatory Startup Protocol
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.
- Read the project's and ; if the directory does not exist, initialize it according to
references/project-memory.md
.
- Read and files related to the current task, do not load the entire log directory indiscriminately.
- Triple Reconciliation Gatekeeper: Before answering "What to do next" or claiming any progress, must cross-verify three sources—, real route/page list, all entries in online . Checkboxes in , at 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 to first 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.
- 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 .
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.
Reusable Operations Must Be Turned into Scripts
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
<project>/.rankup/scripts/<verb-object>.mjs
(e.g., , , ). Scripts must be parameterized (property, date range, keyword, country), do not hardcode specific values from a single run.
- Registration: Record a line in —purpose, parameters, required login state, verified date.
- 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.
Always Use the User's Own Browser for Browser Operations
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.
Sessions/Tabs Must Be Isolated by Conversation
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.
Export Persistence SOP (Mandatory)
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.
First Ask "Is There a Free Export", Then Consider Capture
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.
Export triggers are often icons instead of buttons. SVG elements do not have a
method; calling it directly will throw
x.click is not a function
; you need to
closest('button,[role=button],a')
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.
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.
- 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
Page 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
fetch(..., {method:'POST'})
the data to it, and the server writes directly to the project directory.
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).
Server 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.
The receiver should also provide a read-only GET /script?name=<whitelist-name>
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.
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.
Do 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.
- 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 .
- 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 matches the current project before injection.
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.
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
- Persist into the project. Each project maintains its own data directory outside (e.g., , ), separating original exports and derived products.
- 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:
<topic>__<type>__<slice/parameter>__<date>.<extension>
. Use parameters to construct names, do not use names like "Export(3)".
- 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 , , 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.
- 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.
- 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
<project>/.rankup/scripts/
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
references/integrations.md
.
Cross-Project Asset Registry
The
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.
bash
# Rebuild the list (scan .rankup/ of each project, overwrite entire table)
node "<rankup-skill-dir>/scripts/registry.mjs" scan --roots <directory storing projects>
# View the list
node "<rankup-skill-dir>/scripts/registry.mjs" list
- Location: in the Skill directory, next to , easily visible when in use (can be redirected with ). It must write the project name and absolute path to be useful, so it is excluded by , and
scripts/validate-rankup.mjs
asserts that it must not be tracked by git— is only a convention, a 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 , environment variable , or in . Never hardcode in the script.
- Generated instead of manually written: The entire table is rebuilt on each , 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
Two entry points, covering "just taking over" and "looking back". Users only need to say
/
, no need to describe what to do.
— Connect the Project to rankup
Suitable 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.
- Understand the current state before writing: Read , route/page list, deployment configuration, , confirm the framework, technology stack, deployment target and real production domain. For already launched sites, also retrieve , , and online responses of the homepage and key pages.
- 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
references/project-memory.md
. Fill in existing facts directly, write "To be confirmed" for unavailable information, do not guess.
- 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 .
- Set direction: Write phase goals and abandonment conditions in , write P0–P2 and completion criteria in .
- 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. is 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 .
- 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
.
— Review, Filter, Supplement
Execute 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 30
The 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 :
bash
# 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
# 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
# Only set the watermark after all content is digested
node "<rankup-skill-dir>/scripts/sessions.mjs" --project-root . --days 14 --mark
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.
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
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 must be revised, not written alongside.
On this basis, complete:
- Reconciliation: Checkboxes in are lagging indicators, cross-verify with , route list, and online ; write back first if inconsistent before continuing.
- Filter signals: Merge duplicates, delete outdated entries, revise falsified entries in ——Revise the original entry, do not keep conflicting conclusions side by side. Delete unverified guesses directly.
- 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 .
- 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.
- Fill gaps: Is outdated, is missing failed rounds (failed rounds must clearly write the falsified hypothesis)?
- Refresh the list:
node "<rankup-skill-dir>/scripts/registry.mjs" scan --roots <directory storing projects>
.
- 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
| 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 | scripts/cf-analytics-setup.mjs
; prioritize driving the user's browser for search platforms |
| 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 scripts/cf-zone-setup.mjs
when unavailable |
| 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 | | (one script covers all tools, zero-config) |
| 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 | | (automatically creates venv and installs pytrends on first run) |
| 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 references/authorized-data-sources.md
). Use one product for asking "How big is the site, where does traffic come from, what are similar sites", use another for asking "How much volume does the keyword have, how hard is it to rank, who is ranking, what do backlinks look like". The "traffic" definitions are different (organic search estimation vs total visits), must specify which one in conclusions |
| 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 | scripts/chatbot-drive.browser.js
|
| 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 's platform registry" in | backlink (read references/paid-platforms.md
, feed ) |
| Review, experience preservation, self-evolution, rule upgrade | , | Use independent checker if necessary |
| Next steps for existing projects, iteration, troubleshooting | + task-related references | 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
.
Website Lifecycle
Complete inputs, actions, outputs and completion thresholds can be found in
. The overall process is:
- 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
New projects use by default:
bash
pnpm dlx shadcn@latest init \
--preset b1D0eCA4 \
--template start \
--monorepo \
--rtl \
--pointer
Default 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
.
Project Memory
is the long-term project log and fact base for the current website, not the Skill release directory. Complete structure and templates can be found in
references/project-memory.md
.
Minimum requirements:
- : Navigation, recommended reading order, latest update time.
- : Users, positioning, business model, goals and non-goals.
- : Application, data, service boundaries.
- : Environment, domain, Cloudflare resources and non-sensitive bindings.
- : Stripe, email, analytics and search platform status.
- : Only record name, purpose, environment, storage location, responsible person, access and rotation status.
- : Local version, activation time, check and update time.
- : Long-term direction, phase goals, criteria and abandonment conditions for each phase. Can be continued across sessions, not rewritten with single-round tasks.
- : 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.
- : Reusable operation scripts (see "Reusable Operations Must Be Turned into Scripts").
- : Full text of reusable conclusions for this site, including evidence sources and numbers.
- , , , , , , .
- : Record reusable implementation, operation, troubleshooting and growth processes by date.
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.
Strictly prohibit storing real secrets, tokens, passwords, private keys, webhook secrets, payment sensitive data or personal sensitive information in Skills,
, Git, tests or replies.
Tokens Are Unified in at Skill Root Directory
Third-party tokens relied on by this Skill are stored in a single file at the Skill root directory, shared by all projects.
<rankup-skill-dir>/.env # KEY=value, one per line; excluded by this repository's .gitignore
Why 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:
| 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 is not enough—a can bypass it, so
scripts/validate-rankup.mjs
asserts that it is not tracked by git, and build fails if violated. This uses the same defense as the registry .
- 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.
- 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.
Completion Criteria
A
task is only considered complete if all of the following conditions are met:
- 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.
- Explain what was completed, verification evidence, remaining risks and external matters requiring user handling.
Experience Feedback and Version Upgrade
Detailed failure classification, evidence ladder, adaptive retry, rule promotion and elimination processes can be found in
.
- Facts, numbers and troubleshooting processes that only apply to the current project are written into the project's .
- 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
scripts/validate-rankup.mjs
, build fails if violated.
- 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 , , validation script expectations and README at the same time.