Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@

All notable changes to this project will be documented in this file.

## [0.3.0] - 2026-04-27

### ⚠ Behavior change
- `push` and `sync` now **filter local files through a built-in ignore list** before uploading to Overleaf. LaTeX build artifacts (`.aux`, `.bbl`, `.log`, `.out`, `.fls`, `.fdb_latexmk`, `.synctex.gz`, beamer/biber/glossaries/minted intermediates, etc.) and OS noise (`.DS_Store`, `Thumbs.db`, `*.swp`) are no longer uploaded.
- Previously, locally compiling a project (e.g. with `pdflatex` or `latexmk`) would upload dozens of build artifacts to Overleaf, which could break Overleaf's own compile (stale `.aux` / `.bbl`) or pollute the remote project.
- **PDF special rule:** `X.pdf` is ignored only if a same-named `X.tex` (or `.ltx`) exists in the same folder. Hand-uploaded `figures/diagram.pdf` is still synced.
- To restore the old behavior on a per-run basis, use `--no-default-ignore` (only respects `.olignore`) or `--no-ignore` (uploads everything).

### Added
- **`.olignore` file support** — gitignore-style syntax for project-level ignore patterns. Negation (`!important.aux`) is supported.
- **`.olignore.local` file support** — machine-specific patterns that should not be committed to version control.
- **`olcli ignored [dir]`** command — lists all ignore patterns currently in effect for a project, grouped by source.
- `push --no-default-ignore` / `sync --no-default-ignore` — disable built-in defaults (only `.olignore` applies).
- `push --no-ignore` / `sync --no-ignore` — disable all ignore filtering (escape hatch).
- `push --show-ignored` / `sync --show-ignored` — print files that were skipped by ignore rules.
- New dependency: [`ignore`](https://www.npmjs.com/package/ignore) (~30KB, zero deps, gitignore-compatible matcher used by ESLint/Prettier).

### Fixed
- **#19** — `sync` no longer uploads LaTeX build artifacts, breaking Overleaf compile.

### Internal
- New module `src/ignore.ts` with `DEFAULT_IGNORE_PATTERNS`, `loadIgnore()`, `shouldIgnore()`, and `buildTexSiblingSet()`.
- New e2e test `test/e2e-ignore.sh` covering defaults, `.olignore`, `.olignore.local`, negation, the PDF sibling rule, and the `--no-*` escape hatches.


## [0.2.0] - 2026-04-27

### ⚠ Behavior change
Expand Down
66 changes: 61 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ Work with Overleaf projects directly from your command line. Edit locally with y
- ⬇️ **Pull** project files to local directory for offline editing
- ⬆️ **Push** local changes back to Overleaf
- 🔄 **Sync** bidirectionally with smart conflict detection
- ✌️ **Two-way deletions** — files removed locally are deleted on Overleaf on the next sync (opt out with `--no-delete`)
- 🗑️ **Delete** and ✏️ **rename** remote files by path
- 🚫 **Smart ignore** — LaTeX build artifacts (`.aux`, `.bbl`, `.log`, `.synctex.gz`, …) and OS noise are filtered out automatically; extend with `.olignore` (gitignore-style)
- 📄 **Compile** PDFs using Overleaf's remote compiler
- 📦 **Download** individual files or full project archives
- 📤 **Upload** files to projects
- 🗂️ **Preserve folder structure** when pushing nested files
- 🧹 **Skip generated `output.pdf`** during push/sync so compiled artifacts are not uploaded back to Overleaf
- ⚙️ **Support self-hosted Overleaf/ShareLaTeX instances** via configurable base URL and session cookie name
- 📊 **Output** compile artifacts (`.bbl`, `.log`, `.aux` for arXiv submissions)

Expand Down Expand Up @@ -165,8 +167,9 @@ All commands auto-detect the project when run from a synced directory (contains
| `olcli sync [dir]` | Bidirectional sync (pull + push) |
| `olcli upload <file> [project]` | Upload a single file |
| `olcli download <file> [project]` | Download a single file |
| `olcli delete <file> [project]` | Delete a remote file by path |
| `olcli rename <oldname> <newname> [project]` | Rename a remote file by path |
| `olcli delete <file> [project]` | Delete a remote file or folder by path (alias: `rm`) |
| `olcli rename <oldname> <newname> [project]` | Rename a remote file or folder by path (alias: `mv`) |
| `olcli ignored [dir]` | List ignore patterns currently in effect |
| `olcli zip [project]` | Download project as zip archive |
| `olcli compile [project]` | Trigger PDF compilation |
| `olcli pdf [project]` | Compile and download PDF |
Expand Down Expand Up @@ -252,16 +255,69 @@ olcli output --list
### Push
- Uploads files modified after last pull
- Preserves nested folder structure when uploading
- Skips generated `output.pdf`
- Filters out LaTeX build artifacts and OS noise (see [Ignoring files](#ignoring-files))
- Use `--all` to upload all files
- Use `--dry-run` to preview changes
- Use `--show-ignored` to see what was filtered out

### Sync
- Pulls remote changes
- Preserves local modifications (local wins if newer)
- Pushes local changes to remote
- Skips generated `output.pdf` during upload phase
- **Propagates local deletions to the remote** — if you delete a file locally, it's deleted on Overleaf on the next sync. Use `--no-delete` to opt out.
- Filters out LaTeX build artifacts and OS noise
- Use `--verbose` to see detailed file operations
- Use `--dry-run` to preview without applying

#### How deletion propagation works

On every sync, `olcli` records a manifest of remote files in `.olcli.json`. The next sync compares the manifest against your local working tree:

- File missing locally **and** still present on remote → deleted on Overleaf
- File new locally → uploaded
- File modified locally after last pull → uploaded (local wins)
- File only on remote → downloaded

First-time syncs skip the deletion phase (no manifest exists yet to distinguish "never had it" from "deleted it").

## Ignoring files

`olcli` automatically filters local files through a layered ignore list before uploading. This keeps LaTeX build artifacts (from local `pdflatex`/`latexmk` runs) and OS noise out of your Overleaf project.

### Three layers

| Layer | File | Purpose |
|---|---|---|
| 1 | (built-in) | LaTeX intermediates (`.aux`, `.bbl`, `.log`, `.fls`, `.synctex.gz`, beamer/biber/glossaries/minted), OS noise (`.DS_Store`, `Thumbs.db`, `*.swp`), common build dirs (`build/`, `out/`, `_minted-*/`). Always on; opt out with `--no-default-ignore`. |
| 2 | `.olignore` | Project-level patterns, gitignore syntax. Commit alongside your `.tex` sources. |
| 3 | `.olignore.local` | Machine-specific patterns. Add to `.gitignore`. |

Later layers override earlier ones, just like git. Negation (`!important.aux`) is supported.

### Special PDF rule

`X.pdf` is ignored only if a same-named `X.tex` (or `.ltx`) exists in the same folder. So `thesis.pdf` next to `thesis.tex` is filtered, but a hand-uploaded `figures/diagram.pdf` still syncs.

### Example `.olignore`

```gitignore
# Drafts that should never reach Overleaf
*.draft.tex
notes/
chapters/scratch/

# But keep this one auxiliary file
!important.aux
```

### Inspecting and overriding

```bash
olcli ignored # list patterns currently in effect
olcli push --show-ignored # see what was skipped on this run
olcli sync --no-default-ignore # only .olignore applies
olcli sync --no-ignore # escape hatch — upload everything
```

## Configuration

Expand Down
30 changes: 27 additions & 3 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Sync and manage Overleaf LaTeX projects from the command line. Pull
license: MIT
metadata:
author: aloth
version: "1.1"
version: "1.2"
cli: olcli
install: brew tap aloth/tap && brew install olcli
---
Expand Down Expand Up @@ -64,7 +64,25 @@ cd My_Paper/
```bash
# After editing files locally
olcli push # Upload changes only
olcli sync # Bidirectional sync (pull + push)
olcli sync # Bidirectional sync (pull + push, propagates local deletions)
olcli sync --no-delete # Sync without propagating local deletions to remote
```

### Delete or rename remote files

```bash
olcli delete chapters/old.tex # remove a file from the project
olcli rm figures/old.pdf # alias
olcli rename old.tex new.tex # rename a file
olcli mv chapters/draft.tex chapters/intro.tex # alias
```

### Inspect ignore rules

```bash
olcli ignored # list active patterns (built-ins + .olignore + .olignore.local)
olcli push --show-ignored # see what was filtered on this run
olcli sync --no-ignore # escape hatch: upload everything
```

### Compile and download PDF
Expand Down Expand Up @@ -137,6 +155,9 @@ zip arxiv.zip *.tex main.bbl figures/*.pdf
| `olcli sync [dir]` | Bidirectional sync |
| `olcli upload <file> [project]` | Upload a single file |
| `olcli download <file> [project]` | Download a single file |
| `olcli delete <file> [project]` | Delete a remote file or folder by path (alias: `rm`) |
| `olcli rename <old> <new> [project]` | Rename a remote file or folder (alias: `mv`) |
| `olcli ignored [dir]` | List active ignore patterns |
| `olcli zip [project]` | Download as zip archive |
| `olcli compile [project]` | Trigger compilation |
| `olcli pdf [project]` | Compile and download PDF |
Expand All @@ -145,7 +166,10 @@ zip arxiv.zip *.tex main.bbl figures/*.pdf
## Tips

- **Auto-detect project**: Run commands from a synced directory (contains `.olcli.json`) to skip the project argument
- **Dry run**: Use `olcli push --dry-run` to preview changes before uploading
- **Dry run**: Use `olcli push --dry-run` or `olcli sync --dry-run` to preview before applying
- **Force overwrite**: Use `olcli pull --force` to overwrite local changes
- **Two-way deletes**: `olcli sync` propagates *local* deletions to the remote; use `--no-delete` to opt out per run
- **Build artifacts**: `.aux`, `.bbl`, `.log`, `.synctex.gz` etc. are filtered by default. Add custom patterns to a `.olignore` file (gitignore-style)
- **PDF rule**: `thesis.pdf` next to `thesis.tex` is auto-ignored; standalone `figures/diagram.pdf` is preserved
- **Project ID**: You can use project ID instead of name (24-char hex from URL)
- **Debug auth**: Run `olcli check` to see where credentials are loaded from
9 changes: 7 additions & 2 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
<body>

<section class="hero">
<div class="hero-badge">v0.1.6 · <code>MIT Licensed</code> · Node.js</div>
<div class="hero-badge">v0.3.0 · <code>MIT Licensed</code> · Node.js</div>
<h1>Overleaf,<br>from your <span class="accent">terminal.</span></h1>
<p>Pull, push, sync, and compile LaTeX projects without leaving your editor. Works with Git, CI/CD, and AI agents.</p>

Expand Down Expand Up @@ -176,7 +176,12 @@ <h2>Everything you need</h2>
<div class="feature-card">
<div class="feature-icon">🔄</div>
<h3>Bidirectional Sync</h3>
<p>Smart conflict detection. Local wins if newer, remote changes pulled automatically.</p>
<p>Smart conflict detection. Local wins if newer, remote changes pulled automatically. Local deletions propagate to Overleaf.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🚫</div>
<h3>Smart Ignore</h3>
<p>LaTeX build artifacts (.aux, .bbl, .log, .synctex.gz) filtered automatically. Customize with <code>.olignore</code> (gitignore-style).</p>
</div>
<div class="feature-card">
<div class="feature-icon">📄</div>
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aloth/olcli",
"version": "0.2.0",
"version": "0.3.0",
"description": "Command-line interface for Overleaf — Sync, manage, and compile LaTeX projects from your terminal",
"type": "module",
"bin": {
Expand Down Expand Up @@ -49,6 +49,7 @@
"cheerio": "^1.0.0",
"commander": "^12.1.0",
"conf": "^13.0.0",
"ignore": "^7.0.5",
"ora": "^8.0.1",
"tough-cookie": "^4.1.4"
},
Expand Down
Loading