olcli 是 Overleaf 的命令行界面,用于在终端中同步、管理和编译 LaTeX 项目。用户可以在本地用常用编辑器编辑文件、用 Git 做版本控制,并同步到 Overleaf 云端编译。
主要能力
- 列出所有 Overleaf 项目;创建空白或示例项目。
- 拉取(pull)项目文件到本地目录离线编辑;推送(push)本地更改回 Overleaf;双向同步(sync)并带智能冲突检测。
- 推送前用 diff 对比本地文件与线上远端内容(每次运行都重新拉取远端,a/ 为远端、b/ 为本地,+ 行为推送将上传的内容,- 行为将被覆盖的内容)。
- 生成带修订标记的 PDF:diff --latexdiff 输出删除线/下划线效果,满足导师和期刊要求。
- 将 Overleaf 作为原生 Git 远程仓库使用(Git remote helper)。
- 双向删除:本地删除的文件在下次同步时会在 Overleaf 上删除(可用 --no-delete 关闭)。
- 按路径删除或重命名远程文件;智能忽略 LaTeX 构建产物与系统噪音,可用 .olignore 扩展。
- 调用 Overleaf 远程编译器编译 PDF;下载单个文件或整个项目归档;上传文件。
- 审阅评论:列出、添加、解决、重开、删除和回复评论线程。
- 推送嵌套文件时保留目录结构;可配置超时;自托管实例可用密码登录(无需浏览器)。
- 支持自托管 Overleaf/ShareLaTeX。
- 输出编译产物(.bbl、.log、.aux,便于 arXiv 投稿)。
- 面向 AI 助手的 MCP 服务器。
适用场景
- 在 Vim、VS Code、Emacs 等偏好的编辑器中编辑 LaTeX。
- 使用 Overleaf 编译器的同时用 Git 做版本控制。
- 自动化工作流和 CI/CD 流水线。
- 离线工作并定期同步。
安装与使用
- Homebrew(macOS/Linux);npm(所有平台);也可用 npx 免安装运行。
- 面向 AI 代理(通过 AgentSkills)使用。
- 认证:支持会话 cookie(overleaf.com 与自托管)和邮箱/密码(自托管、无 reCAPTCHA 时)。密码仅在传入 --save-password 时保存;无论如何都会保存会话 cookie,后续命令使用该 cookie。脚本中可设置 OVERLEAF_EMAIL 和 OVERLEAF_PASSWORD,所有命令都会读取,脚本化运行无需执行 olcli auth。
- 从已同步目录(含 .olcli.json)运行命令时会自动检测项目。
编译选项 compile、pdf、output 等编译相关命令支持相关参数。多文档项目中,每次 -r 运行会将指定文件当作主文档编译。
同步与 diff 说明
- pull 下载 Overleaf 上所有文件,跳过上次拉取后本地修改过的文件(不覆盖你的改动),用 --force 可覆盖本地更改。
- push 上传上次拉取后修改过的文件,保留嵌套目录结构,过滤 LaTeX 构建产物和系统噪音;用 --all 上传全部文件,用 --dry-run 预览。
- sync 先拉取远端更改再推送本地更改,本地修改较新时以本地为准;会传播本地删除(用 --no-delete 可退出);用 --dry-run 预览而不实际应用。
- diff 比较本地文件字节与项目当前内容并打印统一 diff;远端每次运行都重新拉取,描述的是当时项目状态(即后续 push 会覆盖的内容),而非与上次 pull 比较。.olcli.json 记录的是远端路径而非远端内容,因此没有存储快照可比。仅字节不同的非文本文件(PDF、图片)会报告为 Binary files ... differ。两侧都经过相同忽略层,Overleaf 上的构建产物不会被报告为本地删除。
- diff --name-only 与 push --dry-run 回答不同问题,可能不一致:push --dry-run 列出修改时间晚于上次拉取的文件(即会推送的内容);diff 列出内容真正不同的文件。仅被 touch 而未编辑的文件会出现在前者而非后者。
latexdiff 与检查模式
- --latexdiff 需要 PATH 中有 latexdiff,它随 TeX Live 和 MacTeX 提供;olcli diff 的其他部分不需要外部工具。
- --pdf 在 Overleaf 上编译,因此无需本地 TeX 安装。编译端点只能构建项目内存在的文件,因此标记文档会以 olcli-latexdiff.tex 上传到根文档旁、编译、下载后删除。命令会事先说明,若同名文件已存在则拒绝覆盖,清理失败时会打印确切的 olcli rm 命令。
- \input 和 \include 会在比较前内联(用 --no-flatten 退出)。否则远端编译会针对项目中旧内容解析,导致 PDF 显示每个输入文件都未更改。
- 输出到 .olcli-diff/(带点号,push 和 sync 不会拾取);-o <path> 可改到别处。根文档是声明 \documentclass 的 .tex 文件;若有多个,用 --main <path> 指定。--latexdiff-opt 原样传递其他选项,如 --latexdiff-opt --math-markup=0。
- 一个限制:--pdf 针对项目编译而非工作目录,因此标记所需内容必须已在 Overleaf 上。本地新增的 .sty 或 .cls 会导致编译失败(失败时编译日志写在标记源旁);本地新增的图片不会导致失败,Overleaf 会画一个标有缺失文件名的占位框,PDF 其余部分正常。
- --exit-code 将命令变为检查,使用 diff(1) 的状态码。1 与 2 的区分是重点:没有它,流水线无法区分文件更改与会话 cookie 过期。其他 olcli 命令失败时报告为 1,olcli diff 在未加 --exit-code 时仍如此,因此该标志不会改变现有脚本看到的行为。检查覆盖所比较的内容:--file main.tex 缩小到单个文件,类似 git diff --exit-code pathspec;--file 匹配不到任何文件时为 0 而非错误。在 --latexdiff 下仍报告整个项目(更改的图片是真实差异,尽管标记根文档无法显示)。注意这是与 Overleaf 当前状态比较,而非与上次 pull 比较,因此该检查是"是否有人偏离了这里提交的内容",值得按计划运行,也值得在推送时运行。
删除传播 olcli 在 .olcli.json 中记录远端文件清单。下次同步时:本地缺失 + 远端仍存在 → 在 Overleaf 上删除;本地新增 → 上传;本地修改 → 上传(本地优先);仅远端存在 → 下载。首次同步跳过删除阶段(无先前清单可比)。
忽略规则 后面层覆盖前面层,支持否定(!important.aux)。特殊 PDF 规则:仅当同文件夹存在 X.tex(或 .ltx)时,X.pdf 才被忽略。
凭据与存储
- 凭据按顺序检查:环境变量 OVERLEAF_SESSION、当前目录的 .olauth 文件、全局配置(运行 olcli check 查看确切路径)。全局配置路径依赖平台,macOS 在 ~/Library/Preferences/ 下,Linux 在 ~/.config/ 下;olcli auth 会打印它写入的路径。
- 注意:olcli auth --save-local 会把 .olauth 写入当前目录(通常是你的 LaTeX 项目),提交前请将其加入该项目的 .gitignore。
- 所有内容以明文存储:olcli check 报告存在什么而不打印任何秘密;olcli logout 清除全局配置和当前目录的 .olauth,然后列出它移除了什么;它无法取消环境变量,因此若设置了 OVERLEAF_SESSION 或 OVERLEAF_EMAIL/OVERLEAF_PASSWORD,它会指出这一点,而非暗示你已登出——这些优先级高于磁盘上的任何内容。
自托管与超时 可传入 olcli --base-url https://latex.example.org list。超时优先级:--timeout > OVERLEAF_TIMEOUT > 配置 > 默认(10000ms)。
库 API @aloth/olcli 作为库暴露 OverleafClient 和所有公共接口。
进一步文档 MCP 服务器(AI 助手集成:Claude、Cursor、Windsurf);Git Remote Helper(将 Overleaf 作为原生 git 远程仓库);故障排查(会话过期——从浏览器获取新 cookie 并重新运行 olcli auth;编译失败——在 Overleaf 网编辑器查看详细错误日志,如缺失宏包、语法错误、缺失参考文献文件)。
架构说明 docs/ARCHITECTURE.md 说明客户端如何工作——没有公开的 Overleaf API,因此它像浏览器会话一样认证。许可证为 MIT © Alexander Loth。