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
14 changes: 13 additions & 1 deletion docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Select **PDF** under the paper in the sidebar to read the manuscript as it is on

Beside the PDF, **Git** is a small source-control panel: the branch and how it compares with its upstream, the last commit, and the uncommitted changes with line counts (the sidebar shows a one-line summary). Select a file to read its diff. Tick the files to include, write a message and press Enter or **Commit**; exactly those files are committed as they are on disk, and anything you staged elsewhere for other files stays staged. New build output (LaTeX's `.aux`, `.log`, `.synctex.gz` and the like, minted's `_minted*` cache, and macOS's `.DS_Store`) starts unticked, and when any of it is untracked the panel offers **Add to .gitignore**: one click adds a pattern for each kind of file (such as `*.aux`) to the repository's `.gitignore`, without repeating patterns it already has, and `.gitignore` then appears as a change to commit. The ✨ button in the message box writes the commit message, like Cursor's: the agent chosen on the new-task page reads the ticked files' changes, the titles of the tasks that changed them and the repository's recent commit subjects, whose style and language it follows, and answers in one read-only turn with its lightest reasoning. No file is changed, and Codex does not keep the turn in its history. Edit the message before committing if you like. When the repository has a remote, **Fetch** checks for new commits, **Pull** fast-forwards, and **Push** sends your commits, or **Publish branch** pushes a branch that has no upstream yet. When your branch and its upstream have both moved on, for example after a coauthor pushed from Overleaf, **Merge** takes Pull's place and merges the upstream into your branch (it never rebases). A merge without conflicts commits itself. One with conflicts stops, and the panel shows how many files still have conflict markers (marked **!**): **Resolve with** the agent chosen on the new-task page edits only those files in the manuscript checkout, keeping both sides' changes where they fit and saying where it had to choose, and its summary appears in the panel. Read each file's diff, then **Commit merge**, or **Abort merge** to return to where you were. Until the merge is committed or aborted, accepting, rejecting and undoing review changes, other commits, pull and push are refused with a message saying so. Remote operations use the host's own Git credentials and never prompt; if a credential is missing they fail with Git's message. The PDF recompiles when the working tree changes and reopens at the same page and zoom; **Recompile** retries a failed build and **Open the PDF file** opens the PDF itself. A temporary Git index captures the working tree, so your index, branches and files are not touched. Builds reuse the review engine's cache in the repository's `.git/latex-review` folder. On phones, switch between **PDF**, **Notes** and **Git** in the header.

To ask for changes directly on the PDF, select the text and choose **Add note**, then describe the change and press Enter. Selection follows the printed words exactly: the server reads every word's place from the PDF, and the viewer puts one selectable run on each word (pdf.js on its own lays a whole line out in a stand-in font, which drifts from the printed words mid-line). A drag that starts or ends inside a word takes the whole word; one that starts or ends between words takes just the words it covers. For a figure, an equation or anything else without selectable text, turn on **Mark region** in the toolbar and drag across it. Nothing is recognized from images: the marked text comes from the PDF's own text layer, and SyncTeX, which the TeX engine writes while compiling, maps the first and last marked character of each line back to the LaTeX file and lines that produced them. SyncTeX records spaces rather than characters, so a word that starts a printed line can be credited to the source line before it; Papilot then matches the printed line around each end of the selection against the nearby source lines to settle on the exact lines. Each note stores that location and the source lines themselves, so formulas reach the agent as LaTeX rather than as extracted PDF text, and the note stays meaningful after the PDF recompiles. Notes are shared across devices, highlighted on the page with a numbered tag in the margin, and listed under **Notes** with their LaTeX source; select a number to find it on the page or × to delete it. **Send notes to the agent** turns every pending note into one new task that quotes each marked passage and its source location, and opens that task.
To leave a note directly on the PDF, select the text and choose **Add note**, then write the comment and press Enter. Click the note text to edit it; Enter, Esc, or clicking outside saves the edit, and Esc or clicking outside also closes the card. Selection follows the printed words exactly: the server reads every word's place from the PDF, and the viewer puts one selectable run on each word (pdf.js on its own lays a whole line out in a stand-in font, which drifts from the printed words mid-line). A drag that starts or ends inside a word takes the whole word; one that starts or ends between words takes just the words it covers. For a figure, an equation or anything else without selectable text, turn on **Mark region** in the toolbar and drag across it. Nothing is recognized from images: the marked text comes from the PDF's own text layer, and SyncTeX, which the TeX engine writes while compiling, maps the first and last marked character of each line back to the LaTeX file and lines that produced them. SyncTeX records spaces rather than characters, so a word that starts a printed line can be credited to the source line before it; Papilot then matches the printed line around each end of the selection against the nearby source lines to settle on the exact lines. Each note stores that location and the source lines themselves, so formulas reach the agent as LaTeX rather than as extracted PDF text, and the note stays meaningful after the PDF recompiles. Notes are shared across devices, highlighted on the page with a numbered tag in the margin, and listed under **My notes** with their LaTeX source. Select a number to find a note on the page, click its text to edit it, or use the trash button to delete it. Notes remain saved without being sent to an agent. The right arrow quotes a note into the new-task draft; the left arrow removes it from that draft. Starting the task sends only the explicitly selected notes with their marked passages and source locations.

Titles (the brand, paper names, task and page headings) use the manuscript's TeX Gyre Pagella; the rest of the interface uses the system sans, and code uses Inconsolata. The fonts are bundled in `src/web/fonts` with their licenses. Colours are clean neutral greys with one blue (#2563EB) for primary actions, links and selection, and green and red only where they mean accept and reject; the embedded review viewer uses the same palette. **Settings** at the bottom of the sidebar chooses the **Appearance**, **Light**, **Dark** or **System**; the choice is saved in this browser, applies before the page first paints, and the review viewer follows it. In the dark theme PDF pages turn dark too, in the review and in the PDF view: their lightness is inverted and their hue kept, so removed and added text stay red and green and links stay blue. Figures are inverted the same way, and Notes and search marks keep their colours.

Expand Down Expand Up @@ -139,6 +139,18 @@ Messages and queued runs are saved in `papilot.sqlite` in the data folder. Closi

Turn on **Settings → Notifications** to receive browser notifications while Papilot is in another tab or app. Under **Notify me about**, choose **Push** or **Off** separately for questions, approval requests, reviews ready, tasks finished without changes to review, and task errors. Choices are saved in this browser and kept when the main switch is turned off. Clicking a notification opens the task. Browsers allow notifications only on HTTPS or localhost, so remotely use the Tailscale HTTPS address.

## AI review

In **Manuscript → New task**, choose the **AI review** skill from the composer’s **+** menu, or type `/ai-review`. Optionally describe a focus (for example, assumptions, argument structure, or clarity), choose Codex, Claude, or GLM, and send it like any other skill. Compile the current manuscript first. Papilot builds and preserves a PDF from the task's own manuscript copy. The reviewer reads its extracted text and produces comments anchored to its actual lines. It runs in read-only mode and cannot publish or apply manuscript edits.

Open **AI suggestions** in the task's PDF toolbar to read findings beside the relevant passages. With a suggestion open and the PDF focused, **← / →** move between findings, and **Esc** or a click outside closes the card. Comments aim for one short, actionable sentence anchored to a specific sentence or equation, usually 1–3 lines; the conversation shows only a brief summary. Opening the PDF keeps the review task available.

Suggestions stay in the task until you click their bookmark (**Keep on manuscript**). This copies only that annotation to the main manuscript, without changing its text; the bookmark fills after success. You can ignore a suggestion and undo that action. Copies already kept on the manuscript survive ignoring the original or deleting its review task. To request edits later, explicitly quote a kept suggestion into a normal editing task. Personal reading notes also stay private until explicitly quoted into a task; click their text to edit them directly. Notes are saved in Papilot and displayed over the PDF, not embedded in downloaded PDF files.

Follow-ups in the review conversation continue reviewing the same preserved PDF. Start a new AI review to review a newer manuscript. When keeping a suggestion after the manuscript has changed, Papilot locates its passage in the current compiled manuscript. If that location cannot be matched reliably, it reports the problem and leaves the original suggestion in the task.

This version reviews selectable text, including text extracted from equations and captions; it does not inspect figure images or page appearance. A review accepts up to 180,000 extracted characters and returns at most 30 suggestions. Scanned PDFs without selectable text cannot be reviewed. An invalid model response saves no partial annotations and can be retried in the same conversation.

## Task attachments

Use **+ → Add files…** in a new task or an existing conversation, drag files onto the composer, or paste an image from the clipboard. Uploaded files appear above the message, with image thumbnails and a remove action. A failed upload offers **Retry**; sending waits until every selected file has uploaded or been removed. Uploaded attachments stay with their paper or task when you navigate away or reload. Sending review feedback separately leaves your draft attachments in place.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"doctor": "node bin/papilot.mjs doctor",
"service:install": "tsx scripts/service.ts install",
"service:stop": "tsx scripts/service.ts stop",
"test:ui": "npm run build && node scripts/check-ui.mjs && node scripts/check-appearance.mjs && node scripts/check-updates.mjs && node scripts/check-papers.mjs && node scripts/check-imports.mjs && node scripts/check-compilation.mjs && node scripts/check-build-problems.mjs && node scripts/check-review-notes.mjs && node --import tsx scripts/check-note-groups.mjs && node scripts/check-note-selection.mjs && node --import tsx scripts/check-note-results.mjs && node --import tsx scripts/check-review-flow.mjs && node scripts/check-skills.mjs && node --import tsx scripts/check-skill-library.mjs && node scripts/check-attachments.mjs && node --import tsx scripts/check-accounts.mjs",
"test:ui": "npm run build && node scripts/check-ui.mjs && node scripts/check-appearance.mjs && node scripts/check-updates.mjs && node scripts/check-papers.mjs && node scripts/check-imports.mjs && node scripts/check-compilation.mjs && node scripts/check-build-problems.mjs && node scripts/check-review-notes.mjs && node --import tsx scripts/check-note-groups.mjs && node scripts/check-note-selection.mjs && node scripts/check-ai-review.mjs && node --import tsx scripts/check-note-results.mjs && node --import tsx scripts/check-review-flow.mjs && node scripts/check-skills.mjs && node --import tsx scripts/check-skill-library.mjs && node scripts/check-attachments.mjs && node --import tsx scripts/check-accounts.mjs",
"site": "node scripts/build-site.mjs",
"test:site": "npm run site && node scripts/check-site.mjs",
"prepack": "npm run build && npm run setup:review"
Expand Down
Loading
Loading