简体中文 · English
Use an authenticated Claude Code or Codex CLI as a local OpenAI-compatible translation
backend for pdf2zh, then produce translated, bilingual, and left/right paper PDFs. No separate
OpenAI-compatible API key is required. An optional Zotero 7+ plugin, PaperBridge, runs the same
pipeline locally or over SSH.
Independent community software. It is not affiliated with Anthropic, OpenAI, pdf2zh, or Zotero. You are responsible for complying with the terms and usage limits of the CLI provider you use.
- Reuses a locally authenticated official CLI instead of storing another translation API key.
- Isolates Claude Code from the user's
CLAUDE.md, memory, hooks, and plugins. - Replaces the coding-agent system prompt with a concise academic-translation prompt.
- Removes pdf2zh's verbose client instruction wrapper before each CLI call and rejects any translated prompt text that still appears in a segment or assembled PDF.
- Rejects translated PDFs before they can be translated a second time.
- Detects reasoning/tool leakage, unexpected Japanese kana in Chinese output, unsupported semantic anomalies, and missing placeholders or citations; failed segments are retried from source.
- Keeps italic prose and bold headings out of pdf2zh's formula placeholders, then audits the assembled PDF for high-confidence untranslated fragments before publishing any result paths.
- Repairs residual figure captions and rotated outer-margin labels, and removes stale link boxes from translated and side-by-side layouts.
- Normalizes invalid scientific-notation operands emitted in some figure streams, so strict PDF readers preserve the intended transforms without parser warnings.
- Versions the pdf2zh cache with the prompt policy, so prompt upgrades cannot reuse old translations.
- Separates cache namespaces by CLI backend and selected model, so switching from Claude to Codex cannot silently reuse the other backend's translation.
- Automatically restarts a stale shim when
shim.pychanges. - Pins the isolated Codex translation backend to
gpt-5.5withhighreasoning effort and gives each Codex segment a bounded 600-second window. - Runs CLI calls without session persistence and serializes OAuth refresh at expiry to prevent concurrent workers from corrupting the shared credential file.
- Runs remote PaperBridge translations as detached server jobs with SSH keepalive and polling, so a dropped long-lived SSH channel cannot kill the translation before download. A server-side hard limit finishes before the client polling deadline and cleans partial status files.
PDF -> pdf2zh -> OpenAI-compatible localhost shim -> claude -p / codex exec
|
deterministic quality gate
|
translated PDF + dual PDF + left/right side-by-side PDF
run.sh is the single production entrypoint used by the shell wrapper and PaperBridge. Its stdout
contains only SIDEBYSIDE=, DUAL=, and MONO= paths; progress goes to stderr.
- Linux or WSL (macOS should work when
lsof, Bash, and Poppler-compatible tooling are available). - Python 3.10+ and either
uvorvenv/pip. - An installed and authenticated Claude Code or Codex CLI.
curl; remote PaperBridge hosts also need GNUtimeout(normally provided by coreutils);zipis required only to build the Zotero plugin.
git clone https://github.com/myheart521/cli2openai.git
cd cli2openai
chmod +x install.sh run.sh translate.sh scripts/build-paperbridge.sh
./install.shVerify your chosen backend independently:
claude -p --model fable "Return exactly OK."
# or
codex exec "Return exactly OK."Claude model names use aliases such as fable, opus, and sonnet, or full IDs such as
claude-fable-5. fable5 is not a valid CLI model name.
./translate.sh /path/to/paper.pdf
./translate.sh /path/to/paper.pdf zh claude 2
CLI2OPENAI_MODEL=sonnet ./translate.sh /path/to/paper.pdf zh claude 2Outputs are written under out/:
paper-sidebyside.pdf: translated page on the left, original page on the right;paper-dual.pdf: pdf2zh bilingual layout;paper-mono.pdf: translated-only layout.
The default Claude model is fable; override it with CLI2OPENAI_MODEL. Keep concurrency at 2
unless you know the provider limit. Set CLI2OPENAI_IGNORE_CACHE=1 for a forced fresh translation.
PDF2ZH_VFONT can override the conservative math-font regex for a paper with unusual formula fonts.
SHIM_CALL_TIMEOUT controls the per-segment CLI limit (default: Claude 300 seconds, Codex 600);
CAPTION_REPAIR_TIMEOUT defaults to 30 seconds longer than that limit. Codex calls are fixed to
gpt-5.5 with a one-run model_reasoning_effort="high" override. These choices do not modify the
user's Codex configuration.
If Claude authentication is missing or expired, run.sh fails before pdf2zh starts and asks you to
run claude auth login.
The pre-flight guard exits with code 3 when the first pages already contain substantial target
language text or known contamination signatures. Select the original paper, not a generated PDF.
python3 shim.py --backend claude --model fable --port 8765 --max-concurrency 2
curl http://127.0.0.1:8765/healthzPoint a client at http://127.0.0.1:8765/v1 with any non-empty dummy API key. The request's
model field is intentionally ignored; operators select the real CLI model with --model or
CLI2OPENAI_MODEL for Claude, while the Codex backend remains fixed to gpt-5.5.
Do not expose the shim to a network. It has no authentication and launches local CLI processes.
Build the plugin:
make plugin
# dist/paperbridge.xpiIn Zotero 7+, open Tools -> Plugins -> gear icon -> Install Plugin From File, then choose the XPI. PaperBridge can:
- run
run.shon the local computer; or - upload the source PDF with SCP, invoke
run.shover SSH, and download the outputs.
Remote hosts, usernames, key paths, and output paths are user preferences and are never bundled in
the XPI. Generated attachments are tagged [PaperBridge]; selecting one as input is rejected, which
prevents translation-of-a-translation loops. Attaching outputs back to Zotero is off by default.
See the plugin guide for platform-specific configuration. Installed copies can use Tools -> Plugins -> gear icon -> Check for Updates because the XPI contains the repository's version-feed URL.
The quality gate is deliberately conservative: it blocks high-confidence corruption and retries the source segment, but it cannot prove that every technical statement is translated perfectly. Review critical claims against the original. Complex figures, vertical text, unusual embedded fonts, and scanned PDFs remain subject to pdf2zh layout limitations. The generated side-by-side PDF keeps the original page beside the translation for verification.
Changing the prompt, filter, or quality policy requires bumping PROMPT_VERSION in shim.py; this
creates a clean cache namespace. Do not patch pdf2zh's SQLite cache manually.
The repository intentionally excludes papers, job folders, outputs, logs, local environments,
credentials, private keys, hosts, and personal paths. Claude authentication is linked at runtime into
the ignored .claude-clean/ directory. Read SECURITY.md before publishing a fork.
make test
make pluginEvery observed leak or marker corruption should become a synthetic regression test. Do not commit real paper segments or user transcripts as fixtures.
MIT. Third-party tools and CLIs retain their own licenses and terms.
