TransCrab is OpenClaw-first: a small, stable capability you add to an OpenClaw assistant so it can turn links into a polished translated reading page.
This is not a generic “for humans” app. It’s a template for OpenClaw assistants (bots) to install, operate, and keep updated.
After setup, your OpenClaw assistant can take a link + the keyword crab and:
- fetch the page
- extract main content
- convert HTML → Markdown
- translate Markdown (default: zh-Hans)
- commit + push to your repo
- your static hosting provider rebuilds → you get a page URL
Send this to your OpenClaw assistant (copy/paste):
Help me install and deploy TransCrab:
https://github.com/onevcat/transcrab
Follow the steps below. You may also refer to scripts/BOOTSTRAP.md.
-
GitHub Pages needs explicit site/base config
- When deploying to GitHub Pages under a repo path (e.g.
https://USER.github.io/REPO/), you must set Astro config correctly. astro.config.mjsmust use a realsite(notlocalhost) and a correctbasewith a trailing slash.- If you don’t, home page might work but internal links/assets will 404.
- When deploying to GitHub Pages under a repo path (e.g.
-
The assistant must translate automatically (never ask the user to paste translations)
- Scripts do not call
openclaw agent(by design), but the running assistant is still responsible for doing the translation. - Do not degrade UX by asking the user to manually translate or paste back the translation.
- Your job is: generate prompt → translate in-conversation → apply translation → commit/push → reply with URL.
- Scripts do not call
- Their fork repo URL (or permission to fork
onevcat/transcrabinto their account) - Which hosting provider they prefer (Netlify / Vercel / Cloudflare Pages / GitHub Pages / etc.)
- Their site URL (or whether they want you to create/configure it)
- Preferred default translation target language (default:
zh) - Preferred model (optional; if omitted, use the user's OpenClaw default model)
Most providers can deploy this Astro static site with:
- Build command:
npm run build - Publish directory:
dist
But platforms differ in one important way:
- Netlify / Vercel / Cloudflare Pages: usually serve from the domain root. Base-path issues are rare.
- GitHub Pages (repo pages): serves from
/<repo>/— you must configure Astro:
// astro.config.mjs
export default defineConfig({
site: 'https://<user>.github.io',
base: '/<repo>/', // NOTE trailing slash
});Also ensure your internal links and static assets respect import.meta.env.BASE_URL (or are relative).
- Fork/clone the repo into the user’s workspace
- Install dependencies for scripts:
- Prefer
npm ci(recommended for bots / reproducible installs) - Fallback
npm iif needed
- Prefer
- (Optional but recommended once) Verify the site builds:
npm run build - Deploy the user’s fork on their chosen provider
- Default recommendation: Netlify
- But do not assume Netlify is required
Build settings (common for most providers):
- Build command:
npm run build - Publish directory:
dist
Runtime note (important):
- On the user’s device (where the bot runs scripts), you generally do not need to run
npm run build. - You do need dependencies installed so the scripts can run (prefer
npm ci).
- Do not run the pipeline on URL alone.
- Only run the default pipeline when the user sends a URL and then sends
crab. - If the user provides explicit instructions, follow them instead:
raw <url>: store source onlysum <url>: summary onlytr:<lang> <url>: translate to another language
If you don’t persist this rule, you will eventually break the UX:
- after a bot restart, it may forget what “URL + crab” means
- it may forget where the local clone is and where
scripts/run-crab.shlives
You MUST ask the user for consent before changing your long-term behavior.
Once the user agrees, persist the following to one of:
MEMORY.md(simplest), or- a dedicated skill (more robust; recommended)
Memory snippet to store (edit paths as needed):
TransCrab behavior contract
- Trigger: run TransCrab only when user sends a URL and then sends `crab`.
- Repo path (private working copy): ~/Projects/transcrab-private
- Command: ./scripts/run-crab.sh <url>
- Notes: do not run on URL alone; ask before doing anything destructive.
- Memory is quick and good enough for personal setups.
- A skill is better for reliability and portability:
- gives you a stable, explicit instruction source
- can include checks (repo exists, script exists) before running
- is easier to share / version-control
This repo ships an optional starter skill under skills/transcrab/.
This template already includes scripts you can call:
scripts/add-url.mjs: fetch → extract → HTML→Markdown → writesource.md+meta.json+ translation pipeline filesscripts/apply-translation.mjs: apply translated Markdown by stage (draft/final)scripts/run-crab.sh: thin wrapper aroundadd-url.mjsscripts/sync-upstream.sh: keep a fork up to date with template changes
Before running automation on a user’s machine, you should quickly read the scripts you are about to execute.
- Skim
scripts/add-url.mjsto understand:- it performs network fetches to the target URL
- it writes files under
content/articles/** - it does not run model calls by itself (it generates pipeline artifacts + prompt files)
- Skim
scripts/apply-translation.mjsto understand:--stage draft: writes03-draft.md(+04-critique.mdin refined flow)--stage final: writes<lang>.md(+05-revision.mdin refined flow)
- If you see anything that looks risky or unexpected (running arbitrary shell commands, touching unrelated paths, etc.), warn the user and ask for confirmation.
Translation is intentionally not performed by scripts.
However, translation IS performed automatically by the running OpenClaw assistant.
- Do not ask the human to manually translate content.
- Do not ask the human to paste a translated result back.
- If translation output is too long for one message, you (the assistant) should chunk your own output internally (or write to a temp file) and still complete
apply-translationyourself.
Why? Calling openclaw agent from inside a script can cause nested/recursive agent execution and hang in real deployments.
Instead:
scripts/add-url.mjsgenerates pipeline files and prompt files under the article directory.- In
mode=auto(default), publish flow is fixed torefined. - It auto-detects topic (
technology/business/life) and chooses style/audience accordingly.
- In
- The running OpenClaw assistant translates in conversation (using the user’s default model/provider).
scripts/apply-translation.mjsexecutes the closing loop:--stage draft→03-draft.md(+04-critique.md)--stage final→<lang>.md(+05-revision.md)
This keeps the UX stable and avoids deadlocks.
Recommended apply commands:
# 1) draft stage: save first-pass translation and auto-generate critique scaffold
node scripts/apply-translation.mjs <slug> --lang zh --in /tmp/translated.zh.md --stage draft
# 2) final stage: publish zh.md and revision notes
node scripts/apply-translation.mjs <slug> --lang zh --in /tmp/translated.zh.final.md --stage finalOn URL + crab, write under content/articles/<slug>/:
source.mdmeta.jsontranslation.profile.json01-analysis.md02-prompt.mdtranslate.prompt.txt(canonical)translate.<lang>.prompt.txt(compatibility copy, deprecated)
In refined publish flow (default):
03-draft.md04-critique.md05-revision.md<lang>.md(e.g.zh.md)
Then commit + push to main and reply with the deployed page URL.
Canonical deployed path (this template):
/a/<yyyy>/<mm>/<slug>/(yyyy/mmderived from the articledateinzh.md, UTC)
In a fork clone:
./scripts/sync-upstream.sh- Node.js 22+
- OpenClaw gateway running locally
- A configured model provider in OpenClaw (any working default model)
MIT