papilot 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +126 -2
- package/README.zh-CN.md +127 -0
- package/bin/papilot.mjs +113 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/Inconsolatazi4-Regular-Dbtq7t_r.otf +0 -0
- package/dist/assets/TeXGyrePagellaX-Bold-CEtYdOXj.otf +0 -0
- package/dist/assets/TeXGyrePagellaX-Italic-CSuYIstn.otf +0 -0
- package/dist/assets/TeXGyrePagellaX-Regular-DQJjZE_L.otf +0 -0
- package/dist/assets/cursor-editorTextHighlight-kG3uUOwL.svg +8 -0
- package/dist/assets/index-BhQFCMTx.js +131 -0
- package/dist/assets/index-CAV3-87U.css +1 -0
- package/dist/assets/pdf-view-DJo0X38w.js +598 -0
- package/dist/assets/pdf.worker.min-CjEcRF4W.mjs +28 -0
- package/dist/favicon.png +0 -0
- package/dist/index.html +4 -0
- package/examples/papilot-paper/.latex-review.json +4 -0
- package/examples/papilot-paper/appendix/proofs.tex +60 -0
- package/examples/papilot-paper/appendix/reference.tex +54 -0
- package/examples/papilot-paper/main.tex +57 -0
- package/examples/papilot-paper/preamble.tex +53 -0
- package/examples/papilot-paper/references.bib +158 -0
- package/examples/papilot-paper/sections/01-introduction.tex +66 -0
- package/examples/papilot-paper/sections/02-using.tex +134 -0
- package/examples/papilot-paper/sections/03-background.tex +97 -0
- package/examples/papilot-paper/sections/04-model.tex +185 -0
- package/examples/papilot-paper/sections/05-conflicts.tex +99 -0
- package/examples/papilot-paper/sections/06-building.tex +70 -0
- package/examples/papilot-paper/sections/07-geometry.tex +193 -0
- package/examples/papilot-paper/sections/08-notes.tex +104 -0
- package/examples/papilot-paper/sections/09-agents.tex +106 -0
- package/examples/papilot-paper/sections/10-usage.tex +56 -0
- package/examples/papilot-paper/sections/11-git.tex +62 -0
- package/examples/papilot-paper/sections/12-security.tex +41 -0
- package/examples/papilot-paper/sections/13-evaluation.tex +106 -0
- package/examples/papilot-paper/sections/14-related.tex +38 -0
- package/examples/papilot-paper/sections/15-conclusion.tex +27 -0
- package/package.json +85 -4
- package/scripts/demo.ts +21 -0
- package/scripts/service.ts +35 -0
- package/src/notes.ts +40 -0
- package/src/server/agents.ts +343 -0
- package/src/server/codex.ts +63 -0
- package/src/server/frontend.ts +15 -0
- package/src/server/main.ts +202 -0
- package/src/server/manuscript.ts +337 -0
- package/src/server/paths.ts +10 -0
- package/src/server/pdf.ts +27 -0
- package/src/server/review.ts +53 -0
- package/src/server/security.ts +15 -0
- package/src/server/store.ts +60 -0
- package/src/server/workspace.ts +529 -0
- package/src/shared.ts +28 -0
- package/vendor/latex-review/LICENSE +21 -0
- package/vendor/latex-review/dist/web/assets/TeXGyrePagellaX-Bold-CEtYdOXj.otf +0 -0
- package/vendor/latex-review/dist/web/assets/TeXGyrePagellaX-Regular-DQJjZE_L.otf +0 -0
- package/vendor/latex-review/dist/web/assets/index-DyzYnIGk.css +1 -0
- package/vendor/latex-review/dist/web/assets/index-HxBK-dls.js +19 -0
- package/vendor/latex-review/dist/web/index.html +18 -0
- package/vendor/latex-review/package-lock.json +3114 -0
- package/vendor/latex-review/package.json +49 -0
- package/vendor/latex-review/src/cli.ts +494 -0
- package/vendor/latex-review/src/client.ts +198 -0
- package/vendor/latex-review/src/core/build.ts +296 -0
- package/vendor/latex-review/src/core/changes.ts +126 -0
- package/vendor/latex-review/src/core/config.ts +270 -0
- package/vendor/latex-review/src/core/diff.ts +54 -0
- package/vendor/latex-review/src/core/files.ts +96 -0
- package/vendor/latex-review/src/core/git.ts +317 -0
- package/vendor/latex-review/src/core/outline.ts +314 -0
- package/vendor/latex-review/src/core/process.ts +111 -0
- package/vendor/latex-review/src/core/publish.ts +339 -0
- package/vendor/latex-review/src/core/review.ts +734 -0
- package/vendor/latex-review/src/core/store.ts +66 -0
- package/vendor/latex-review/src/core/tasks.ts +237 -0
- package/vendor/latex-review/src/render/inline.ts +805 -0
- package/vendor/latex-review/src/render/locate.ts +481 -0
- package/vendor/latex-review/src/render/pdf.ts +281 -0
- package/vendor/latex-review/src/render/pdfdiff.ts +272 -0
- package/vendor/latex-review/src/render/round.ts +236 -0
- package/vendor/latex-review/src/render/worker.ts +10 -0
- package/vendor/latex-review/src/runtime.ts +23 -0
- package/vendor/latex-review/src/server.ts +401 -0
- package/vendor/latex-review/src/types.ts +283 -0
- package/vendor/latex-review/src/web/ChangeMap.tsx +212 -0
- package/vendor/latex-review/src/web/PdfStrip.tsx +77 -0
- package/vendor/latex-review/src/web/fonts/GUST-FONT-LICENSE.txt +29 -0
- package/vendor/latex-review/src/web/fonts/LPPL.txt +415 -0
- package/vendor/latex-review/src/web/fonts/MANIFEST-newpx.txt +20 -0
- package/vendor/latex-review/src/web/fonts/README-newpx.txt +473 -0
- package/vendor/latex-review/src/web/fonts/README.md +12 -0
- package/vendor/latex-review/src/web/fonts/TeXGyrePagellaX-Bold.otf +0 -0
- package/vendor/latex-review/src/web/fonts/TeXGyrePagellaX-Regular.otf +0 -0
- package/vendor/latex-review/src/web/index.html +17 -0
- package/vendor/latex-review/src/web/main.tsx +10 -0
- package/vendor/latex-review/src/web/model.ts +153 -0
- package/vendor/latex-review/src/web/overview.tsx +146 -0
- package/vendor/latex-review/src/web/review.tsx +991 -0
- package/vendor/latex-review/src/web/style.css +1249 -0
package/dist/favicon.png
ADDED
|
Binary file
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content"/><meta name="theme-color" content="#ffffff"/><meta name="description" content="Revise LaTeX papers with an agent and review the PDF changes."/><link rel="icon" type="image/png" href="/favicon.png"/><link rel="apple-touch-icon" href="/apple-touch-icon.png"/><title>Papilot</title> <script type="module" crossorigin src="/assets/index-BhQFCMTx.js"></script>
|
|
3
|
+
<link rel="stylesheet" crossorigin href="/assets/index-CAV3-87U.css">
|
|
4
|
+
</head><body><div id="root"></div></body></html>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
\section{Proofs}
|
|
2
|
+
\label{app:proofs}
|
|
3
|
+
|
|
4
|
+
\subsection{Expected rounds}
|
|
5
|
+
|
|
6
|
+
We prove \cref{prop:rounds}. Write $q = 1 - p$. The rounds of different changes are independent, so
|
|
7
|
+
$\Prob(R_{\max} \le r) = \Prob(R \le r)^{m} = (1 - q^{r})^{m}$, and since
|
|
8
|
+
$R_{\max}$ takes values in $\N$,
|
|
9
|
+
\begin{equation}
|
|
10
|
+
\E[R_{\max}] = \sum_{r \ge 0} \Prob(R_{\max} > r)
|
|
11
|
+
= \sum_{r \ge 0} \Bigl( 1 - \bigl(1 - q^{r}\bigr)^{m} \Bigr).
|
|
12
|
+
\end{equation}
|
|
13
|
+
By the binomial theorem,
|
|
14
|
+
$1 - (1 - q^{r})^{m} = \sum_{k=1}^{m} (-1)^{k+1} \binom{m}{k} q^{rk}$. The inner
|
|
15
|
+
sum is finite, so the two sums may be exchanged, and
|
|
16
|
+
$\sum_{r \ge 0} q^{rk} = 1 / (1 - q^{k})$ gives \cref{eq:rounds}.
|
|
17
|
+
|
|
18
|
+
For the asymptotics, $1 - q^{k} = 1 - (1-p)^{k} = kp + O(p^2)$ as $p \to 0$, so
|
|
19
|
+
\begin{equation}
|
|
20
|
+
\E[R_{\max}] = \frac{1}{p} \sum_{k=1}^{m} \frac{(-1)^{k+1}}{k} \binom{m}{k}
|
|
21
|
+
+ O(1)
|
|
22
|
+
= \frac{H_m}{p} + O(1),
|
|
23
|
+
\end{equation}
|
|
24
|
+
using the identity $\sum_{k=1}^{m} \frac{(-1)^{k+1}}{k}\binom{m}{k} = H_m$,
|
|
25
|
+
which follows by integrating $\bigl(1 - (1-x)^{m}\bigr)/x
|
|
26
|
+
= \sum_{j=0}^{m-1} (1-x)^{j}$ from $0$ to $1$. \qed
|
|
27
|
+
|
|
28
|
+
\subsection{Mid-line drift}
|
|
29
|
+
|
|
30
|
+
We prove \cref{thm:drift}. Let $\gamma = \Cov(\delta_i, \delta_j)$ for $i \ne j$, which does not depend on the
|
|
31
|
+
pair by exchangeability. Since $\sum_{i=1}^{N} \delta_i = 0$,
|
|
32
|
+
\begin{equation}
|
|
33
|
+
0 = \Var\Bigl(\sum_{i=1}^{N} \delta_i\Bigr) = N v + N(N-1)\, \gamma,
|
|
34
|
+
\qquad\text{so}\qquad \gamma = -\frac{v}{N-1} .
|
|
35
|
+
\end{equation}
|
|
36
|
+
With $j = k - 1$ terms in $\varepsilon_k$,
|
|
37
|
+
\begin{equation}
|
|
38
|
+
\Var(\varepsilon_k) = j v + j(j-1)\, \gamma
|
|
39
|
+
= j v \Bigl(1 - \frac{j - 1}{N - 1}\Bigr)
|
|
40
|
+
= v\, \frac{j\,(N - j)}{N - 1}
|
|
41
|
+
= v\, \frac{(k-1)(N-k+1)}{N-1} .
|
|
42
|
+
\end{equation}
|
|
43
|
+
The product $j(N-j)$ is largest at $j = N/2$, where it equals $N^2/4$, and
|
|
44
|
+
$N^2/(4(N-1)) \approx N/4$ for large $N$. \qed
|
|
45
|
+
|
|
46
|
+
\subsection{Partial commits}
|
|
47
|
+
|
|
48
|
+
We prove \cref{prop:partial}. Papilot commits $P$ in two steps. First, adding $P$ to the index sets
|
|
49
|
+
$I(\pi) = W(\pi)$ for every $\pi \in P$ that exists on disk and removes from the
|
|
50
|
+
index every $\pi \in P$ that does not, leaving the entries for $\overline{P}$
|
|
51
|
+
unchanged:
|
|
52
|
+
\begin{equation}
|
|
53
|
+
I_1 = I|_{\overline{P}} \cup W|_{P} .
|
|
54
|
+
\end{equation}
|
|
55
|
+
Second, a commit restricted to $P$ builds its tree from $H$ with the entries
|
|
56
|
+
for $P$ taken from the working tree and ignores the entries of the index for
|
|
57
|
+
$\overline{P}$, which gives $T_c = H|_{\overline{P}} \cup W|_{P}$. It then
|
|
58
|
+
updates the index entries for $P$ and keeps the others, so $I' = I_1$. For a
|
|
59
|
+
rename from $\pi$ to $\pi'$, the entry for $\pi$ is absent from $W$; including
|
|
60
|
+
$\pi$ in $P$ removes it from $T_c$, and including $\pi'$ adds the new path. \qed
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
\section{Notation and keyboard}
|
|
2
|
+
\label{app:reference}
|
|
3
|
+
|
|
4
|
+
\subsection{Notation}
|
|
5
|
+
|
|
6
|
+
\begin{center}
|
|
7
|
+
\small
|
|
8
|
+
\begin{tabular}{@{}lll@{}}
|
|
9
|
+
\toprule
|
|
10
|
+
Symbol & Meaning & Where \\
|
|
11
|
+
\midrule
|
|
12
|
+
$x_k$, $F$ & auxiliary state of the build, one run & \cref{eq:fixed-point} \\
|
|
13
|
+
$T_{rm}$, $T_m$ & text rendering and text matrices & \cref{eq:trm} \\
|
|
14
|
+
$\doc$, $n$ & manuscript source and its length & \cref{sec:model} \\
|
|
15
|
+
$e = (a, b, w)$, $\delta(e)$ & edit replacing $[a, b)$ by $w$, its shift & \cref{eq:apply} \\
|
|
16
|
+
$e \perp e'$ & compatible edits & \cref{eq:compatible} \\
|
|
17
|
+
$\tau(e', e)$ & $e'$ rebased past $e$ & \cref{eq:transform} \\
|
|
18
|
+
$\theta$, $\alpha$ & decision state, action & \cref{eq:round,eq:idempotent} \\
|
|
19
|
+
$p$, $R_{\max}$, $r_{\eta}$ & acceptance probability, rounds, rounds with confidence & \cref{eq:rounds,eq:rounds-confidence} \\
|
|
20
|
+
$\ell$, $k_i$, $\nu$ & edit length, edits per task, clustered fraction & \cref{eq:conflict,eq:clustered} \\
|
|
21
|
+
$T$, $\key(W)$ & snapshot tree, build key & \cref{eq:snapshot,eq:key} \\
|
|
22
|
+
$s$, $V_s$, $R_{\phi}$ & viewer scale, viewport, rotation & \cref{eq:viewport} \\
|
|
23
|
+
$r$, $b(r)$, $d$ & adjustment ratio, badness, demerits & \cref{eq:ratio,eq:badness,eq:demerits} \\
|
|
24
|
+
$\varepsilon_k$, $\sigma$, $\beta_k$ & text layer drift, stretch factor, bias & \cref{eq:drift,eq:bias} \\
|
|
25
|
+
$\mathcal{S}$, $\letters$, $\dist$ & SyncTeX query, letter normalisation, line distance & \cref{sec:notes} \\
|
|
26
|
+
$\epsilon$, $\kappa$, $q$ & effort, tokens per turn, acceptance per turn & \cref{eq:effort-cost} \\
|
|
27
|
+
$c$, $A$, $C(c, A)$ & slots, offered load, waiting probability & \cref{eq:erlang} \\
|
|
28
|
+
$u_w$, $B_w$, $S(t)$ & window utilisation, budget, usage process & \cref{eq:utilisation,eq:compound} \\
|
|
29
|
+
$H$, $I$, $W$, $P$ & Git trees, index, working tree, chosen paths & \cref{eq:partial} \\
|
|
30
|
+
$\anc(X)$ & commits reachable from $X$ & \cref{eq:ahead-behind} \\
|
|
31
|
+
$\chi$, $\mathcal{O}$, $o$ & request token, allowed origins, owner & \cref{eq:allow} \\
|
|
32
|
+
\bottomrule
|
|
33
|
+
\end{tabular}
|
|
34
|
+
\end{center}
|
|
35
|
+
|
|
36
|
+
\subsection{Keyboard}
|
|
37
|
+
|
|
38
|
+
\begin{center}
|
|
39
|
+
\small
|
|
40
|
+
\begin{tabular}{@{}ll@{}}
|
|
41
|
+
\toprule
|
|
42
|
+
Key & Action \\
|
|
43
|
+
\midrule
|
|
44
|
+
\texttt{A}, \texttt{R}, \texttt{C} & accept, reject or comment on the current change \\
|
|
45
|
+
\texttt{J}, \texttt{K} & next and previous change \\
|
|
46
|
+
\texttt{N} & next undecided change \\
|
|
47
|
+
\texttt{S} & show the \LaTeX{} source of the current change \\
|
|
48
|
+
$\text{\texttt{Cmd}} + \text{\texttt{F}}$ & find in the PDF \\
|
|
49
|
+
$\text{\texttt{Cmd}} + \text{\texttt{+}}$, $\text{\texttt{Cmd}} + \text{\texttt{-}}$, $\text{\texttt{Cmd}} + \text{\texttt{0}}$ & zoom in, zoom out, fit width \\
|
|
50
|
+
\texttt{Enter}, \texttt{Shift+Enter} & send, new line \\
|
|
51
|
+
\texttt{Esc} & close a menu, cancel a note, stop marking a region \\
|
|
52
|
+
\bottomrule
|
|
53
|
+
\end{tabular}
|
|
54
|
+
\end{center}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
\documentclass[11pt]{article}
|
|
2
|
+
\input{preamble}
|
|
3
|
+
|
|
4
|
+
\title{Papilot: Reviewable Agent Edits for \LaTeX{} Manuscripts}
|
|
5
|
+
\author{The Papilot Authors}
|
|
6
|
+
\date{}
|
|
7
|
+
|
|
8
|
+
\begin{document}
|
|
9
|
+
\maketitle
|
|
10
|
+
|
|
11
|
+
\begin{abstract}
|
|
12
|
+
Papilot is a personal workspace for revising \LaTeX{} papers with an AI agent
|
|
13
|
+
and reviewing every resulting change as a PDF difference before it reaches the
|
|
14
|
+
manuscript. Each editing task runs in an isolated Git worktree, may be driven
|
|
15
|
+
by Codex, Claude or Antigravity, and proceeds in review rounds in which the
|
|
16
|
+
author accepts, rejects or comments on individual changes. This paper describes
|
|
17
|
+
the system through a sequence of small formal models. We define edits and
|
|
18
|
+
review rounds as operators on a document, prove that compatible edits commute
|
|
19
|
+
and can be rebased, and bound the number of rounds a task needs. We estimate
|
|
20
|
+
how often concurrent tasks conflict, both for uniformly placed and for
|
|
21
|
+
clustered edits. We then treat the geometry of the PDF view: the chain of
|
|
22
|
+
matrices from a glyph to a pixel, why a line-wide text layer drifts from the
|
|
23
|
+
printed words, and how per-word runs bound that drift. We show how a mark on
|
|
24
|
+
the page becomes a source location, model agent scheduling as a queue and
|
|
25
|
+
usage limits as a compound Poisson process, and give the index algebra behind
|
|
26
|
+
partial commits. A model-based evaluation tabulates the resulting quantities.
|
|
27
|
+
The paper doubles as Papilot's example manuscript: every equation in it is a
|
|
28
|
+
place to try a review.
|
|
29
|
+
\end{abstract}
|
|
30
|
+
|
|
31
|
+
\tableofcontents
|
|
32
|
+
\clearpage
|
|
33
|
+
|
|
34
|
+
\input{sections/01-introduction}
|
|
35
|
+
\input{sections/02-using}
|
|
36
|
+
\input{sections/03-background}
|
|
37
|
+
\input{sections/04-model}
|
|
38
|
+
\input{sections/05-conflicts}
|
|
39
|
+
\input{sections/06-building}
|
|
40
|
+
\input{sections/07-geometry}
|
|
41
|
+
\input{sections/08-notes}
|
|
42
|
+
\input{sections/09-agents}
|
|
43
|
+
\input{sections/10-usage}
|
|
44
|
+
\input{sections/11-git}
|
|
45
|
+
\input{sections/12-security}
|
|
46
|
+
\input{sections/13-evaluation}
|
|
47
|
+
\input{sections/14-related}
|
|
48
|
+
\input{sections/15-conclusion}
|
|
49
|
+
|
|
50
|
+
\appendix
|
|
51
|
+
\input{appendix/proofs}
|
|
52
|
+
\input{appendix/reference}
|
|
53
|
+
|
|
54
|
+
\bibliographystyle{plainnat}
|
|
55
|
+
\bibliography{references}
|
|
56
|
+
|
|
57
|
+
\end{document}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
% Packages and notation shared by every chapter.
|
|
2
|
+
\usepackage[margin=1in]{geometry}
|
|
3
|
+
\usepackage[T1]{fontenc}
|
|
4
|
+
\usepackage{lmodern}
|
|
5
|
+
\usepackage{microtype}
|
|
6
|
+
\usepackage{amsmath,amssymb,amsthm,mathtools}
|
|
7
|
+
\usepackage{bm}
|
|
8
|
+
\usepackage{booktabs}
|
|
9
|
+
\usepackage{enumitem}
|
|
10
|
+
\usepackage{caption}
|
|
11
|
+
\usepackage{algorithm}
|
|
12
|
+
\usepackage[noend]{algpseudocode}
|
|
13
|
+
\usepackage{tikz}
|
|
14
|
+
\usetikzlibrary{automata,positioning,arrows.meta,calc,decorations.pathreplacing}
|
|
15
|
+
\usepackage{pgfplots}
|
|
16
|
+
\pgfplotsset{compat=1.18}
|
|
17
|
+
\usepackage[numbers,sort&compress]{natbib}
|
|
18
|
+
\usepackage[colorlinks=true,linkcolor=blue!50!black,citecolor=blue!50!black,urlcolor=blue!50!black]{hyperref}
|
|
19
|
+
\usepackage[nameinlink]{cleveref}
|
|
20
|
+
|
|
21
|
+
% thmtools lets cleveref name each kind of statement correctly although they
|
|
22
|
+
% share one counter.
|
|
23
|
+
\usepackage{thmtools}
|
|
24
|
+
\declaretheorem[style=plain, numberwithin=section]{theorem}
|
|
25
|
+
\declaretheorem[style=plain, sibling=theorem]{proposition}
|
|
26
|
+
\declaretheorem[style=plain, sibling=theorem]{lemma}
|
|
27
|
+
\declaretheorem[style=plain, sibling=theorem]{corollary}
|
|
28
|
+
\declaretheorem[style=definition, sibling=theorem]{definition}
|
|
29
|
+
\declaretheorem[style=definition, sibling=theorem]{example}
|
|
30
|
+
\declaretheorem[style=definition, sibling=theorem]{assumption}
|
|
31
|
+
\declaretheorem[style=remark, sibling=theorem]{remark}
|
|
32
|
+
\numberwithin{equation}{section}
|
|
33
|
+
|
|
34
|
+
\newcommand{\R}{\mathbb{R}}
|
|
35
|
+
\newcommand{\N}{\mathbb{N}}
|
|
36
|
+
\newcommand{\Z}{\mathbb{Z}}
|
|
37
|
+
\newcommand{\E}{\mathbb{E}}
|
|
38
|
+
\newcommand{\Prob}{\mathbb{P}}
|
|
39
|
+
\newcommand{\Var}{\operatorname{Var}}
|
|
40
|
+
\newcommand{\Cov}{\operatorname{Cov}}
|
|
41
|
+
\newcommand{\doc}{D}
|
|
42
|
+
\newcommand{\edit}{\Delta}
|
|
43
|
+
\newcommand{\apply}{\oplus}
|
|
44
|
+
\newcommand{\letters}{\lambda}
|
|
45
|
+
\newcommand{\anc}{\operatorname{anc}}
|
|
46
|
+
\newcommand{\ind}{\mathbf{1}}
|
|
47
|
+
\DeclareMathOperator{\key}{key}
|
|
48
|
+
\DeclareMathOperator{\dist}{dist}
|
|
49
|
+
\DeclareMathOperator*{\argmin}{arg\,min}
|
|
50
|
+
\DeclarePairedDelimiter{\abs}{\lvert}{\rvert}
|
|
51
|
+
\DeclarePairedDelimiter{\norm}{\lVert}{\rVert}
|
|
52
|
+
\DeclarePairedDelimiter{\floor}{\lfloor}{\rfloor}
|
|
53
|
+
\DeclarePairedDelimiter{\ceil}{\lceil}{\rceil}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
@article{laurens2008,
|
|
2
|
+
author = {J{\'e}r{\^o}me Laurens},
|
|
3
|
+
title = {Direct and reverse synchronization with {SyncTeX}},
|
|
4
|
+
journal = {TUGboat},
|
|
5
|
+
volume = {29},
|
|
6
|
+
number = {3},
|
|
7
|
+
pages = {365--371},
|
|
8
|
+
year = {2008}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@article{erlang1917,
|
|
12
|
+
author = {A. K. Erlang},
|
|
13
|
+
title = {Solution of some problems in the theory of probabilities of significance in automatic telephone exchanges},
|
|
14
|
+
journal = {Elektroteknikeren},
|
|
15
|
+
volume = {13},
|
|
16
|
+
pages = {5--13},
|
|
17
|
+
year = {1917}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@book{chacon2014,
|
|
21
|
+
author = {Scott Chacon and Ben Straub},
|
|
22
|
+
title = {Pro Git},
|
|
23
|
+
edition = {Second},
|
|
24
|
+
publisher = {Apress},
|
|
25
|
+
year = {2014}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@book{knuth1984,
|
|
29
|
+
author = {Donald E. Knuth},
|
|
30
|
+
title = {The {\TeX}book},
|
|
31
|
+
publisher = {Addison-Wesley},
|
|
32
|
+
year = {1984}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@article{knuth1981,
|
|
36
|
+
author = {Donald E. Knuth and Michael F. Plass},
|
|
37
|
+
title = {Breaking paragraphs into lines},
|
|
38
|
+
journal = {Software: Practice and Experience},
|
|
39
|
+
volume = {11},
|
|
40
|
+
number = {11},
|
|
41
|
+
pages = {1119--1184},
|
|
42
|
+
year = {1981}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@book{lamport1994,
|
|
46
|
+
author = {Leslie Lamport},
|
|
47
|
+
title = {{\LaTeX}: A Document Preparation System},
|
|
48
|
+
edition = {Second},
|
|
49
|
+
publisher = {Addison-Wesley},
|
|
50
|
+
year = {1994}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@inproceedings{ellis1989,
|
|
54
|
+
author = {C. A. Ellis and S. J. Gibbs},
|
|
55
|
+
title = {Concurrency control in groupware systems},
|
|
56
|
+
booktitle = {Proceedings of the 1989 ACM SIGMOD International Conference on Management of Data},
|
|
57
|
+
pages = {399--407},
|
|
58
|
+
year = {1989}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@inproceedings{shapiro2011,
|
|
62
|
+
author = {Marc Shapiro and Nuno Pregui{\c{c}}a and Carlos Baquero and Marek Zawirski},
|
|
63
|
+
title = {Conflict-free replicated data types},
|
|
64
|
+
booktitle = {Stabilization, Safety, and Security of Distributed Systems (SSS 2011)},
|
|
65
|
+
series = {Lecture Notes in Computer Science},
|
|
66
|
+
volume = {6976},
|
|
67
|
+
pages = {386--400},
|
|
68
|
+
publisher = {Springer},
|
|
69
|
+
year = {2011}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@article{myers1986,
|
|
73
|
+
author = {Eugene W. Myers},
|
|
74
|
+
title = {An {$O(ND)$} difference algorithm and its variations},
|
|
75
|
+
journal = {Algorithmica},
|
|
76
|
+
volume = {1},
|
|
77
|
+
number = {1--4},
|
|
78
|
+
pages = {251--266},
|
|
79
|
+
year = {1986}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@techreport{hunt1976,
|
|
83
|
+
author = {James W. Hunt and M. Douglas McIlroy},
|
|
84
|
+
title = {An algorithm for differential file comparison},
|
|
85
|
+
institution = {Bell Laboratories},
|
|
86
|
+
type = {Computing Science Technical Report},
|
|
87
|
+
number = {41},
|
|
88
|
+
year = {1976}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@article{little1961,
|
|
92
|
+
author = {John D. C. Little},
|
|
93
|
+
title = {A proof for the queuing formula: {$L = \lambda W$}},
|
|
94
|
+
journal = {Operations Research},
|
|
95
|
+
volume = {9},
|
|
96
|
+
number = {3},
|
|
97
|
+
pages = {383--387},
|
|
98
|
+
year = {1961}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@book{kleinrock1975,
|
|
102
|
+
author = {Leonard Kleinrock},
|
|
103
|
+
title = {Queueing Systems, Volume 1: Theory},
|
|
104
|
+
publisher = {Wiley},
|
|
105
|
+
year = {1975}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@book{feller1968,
|
|
109
|
+
author = {William Feller},
|
|
110
|
+
title = {An Introduction to Probability Theory and Its Applications, Volume 1},
|
|
111
|
+
edition = {Third},
|
|
112
|
+
publisher = {Wiley},
|
|
113
|
+
year = {1968}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@book{billingsley1999,
|
|
117
|
+
author = {Patrick Billingsley},
|
|
118
|
+
title = {Convergence of Probability Measures},
|
|
119
|
+
edition = {Second},
|
|
120
|
+
publisher = {Wiley},
|
|
121
|
+
year = {1999}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@manual{iso32000,
|
|
125
|
+
organization = {International Organization for Standardization},
|
|
126
|
+
title = {{ISO} 32000-1:2008, Document management --- Portable document format --- Part 1: {PDF} 1.7},
|
|
127
|
+
year = {2008}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@inproceedings{barth2008,
|
|
131
|
+
author = {Adam Barth and Collin Jackson and John C. Mitchell},
|
|
132
|
+
title = {Robust defenses for cross-site request forgery},
|
|
133
|
+
booktitle = {Proceedings of the 15th ACM Conference on Computer and Communications Security (CCS '08)},
|
|
134
|
+
pages = {75--88},
|
|
135
|
+
year = {2008}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@misc{latexdiff,
|
|
139
|
+
author = {Frederik Tilmann},
|
|
140
|
+
title = {latexdiff: Determine and mark up significant differences between {\LaTeX} files},
|
|
141
|
+
howpublished = {\url{https://ctan.org/pkg/latexdiff}}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@misc{pdfjs,
|
|
145
|
+
author = {{Mozilla}},
|
|
146
|
+
title = {{PDF.js}: A general-purpose, web standards-based platform for parsing and rendering {PDFs}},
|
|
147
|
+
howpublished = {\url{https://mozilla.github.io/pdf.js/}}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@article{shannon1951,
|
|
151
|
+
author = {Claude E. Shannon},
|
|
152
|
+
title = {Prediction and entropy of printed {English}},
|
|
153
|
+
journal = {Bell System Technical Journal},
|
|
154
|
+
volume = {30},
|
|
155
|
+
number = {1},
|
|
156
|
+
pages = {50--64},
|
|
157
|
+
year = {1951}
|
|
158
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
\section{Introduction}
|
|
2
|
+
\label{sec:introduction}
|
|
3
|
+
|
|
4
|
+
Writing a research paper is a long sequence of small decisions. A sentence is
|
|
5
|
+
shortened, a definition is moved before its first use, a symbol is renamed so
|
|
6
|
+
that it no longer collides with another, a proof gains the step a referee
|
|
7
|
+
asked for. An agent that edits \LaTeX{} can propose many of these decisions
|
|
8
|
+
quickly, but a proposal is only useful when the author can see what it changes
|
|
9
|
+
in the typeset paper, decide, and say why. Papilot is built around that loop.
|
|
10
|
+
|
|
11
|
+
\subsection{Three commitments}
|
|
12
|
+
|
|
13
|
+
Papilot organises the loop around three commitments.
|
|
14
|
+
|
|
15
|
+
\begin{enumerate}[label=(C\arabic*)]
|
|
16
|
+
\item \emph{Isolation.} Every task edits its own Git worktree, never the
|
|
17
|
+
manuscript checkout, so that unreviewed text cannot leak into the paper.
|
|
18
|
+
\item \emph{Typeset review.} Changes are reviewed as differences between two
|
|
19
|
+
compiled PDFs, with the \LaTeX{} source one click away.
|
|
20
|
+
\item \emph{Explicit acceptance.} Only accepted changes are merged into the
|
|
21
|
+
working tree, and every decision can be undone.
|
|
22
|
+
\end{enumerate}
|
|
23
|
+
|
|
24
|
+
The first commitment is about safety, the second about legibility and the
|
|
25
|
+
third about authority. Together they turn an agent from a co-author that writes
|
|
26
|
+
into the manuscript into an assistant that proposes to it.
|
|
27
|
+
|
|
28
|
+
\subsection{What this paper does}
|
|
29
|
+
|
|
30
|
+
The rest of this paper makes the commitments precise and studies their
|
|
31
|
+
consequences with small, explicit models. Our contributions are:
|
|
32
|
+
|
|
33
|
+
\begin{itemize}
|
|
34
|
+
\item an algebra of edits and review rounds, with a proof that compatible
|
|
35
|
+
edits commute and can be rebased onto each other (\cref{sec:model}), and
|
|
36
|
+
tight bounds on the number of rounds a task needs;
|
|
37
|
+
\item an estimate of the conflict rate between concurrent tasks under uniform
|
|
38
|
+
and clustered edits (\cref{sec:conflicts});
|
|
39
|
+
\item a content-addressed build scheme in which undoing a decision never
|
|
40
|
+
recompiles (\cref{sec:build});
|
|
41
|
+
\item a geometric account of the PDF view, explaining why a line-wide text
|
|
42
|
+
layer drifts from the printed words and proving that per-word runs bound
|
|
43
|
+
the drift (\cref{sec:geometry});
|
|
44
|
+
\item an algorithm that turns a mark on the page into source lines, and an
|
|
45
|
+
analysis of when its matches are unique (\cref{sec:notes});
|
|
46
|
+
\item queueing and usage models for agents (\cref{sec:agents,sec:usage}),
|
|
47
|
+
the index algebra behind partial commits (\cref{sec:git}) and a security
|
|
48
|
+
model (\cref{sec:security});
|
|
49
|
+
\item a model-based evaluation that tabulates the quantities above
|
|
50
|
+
(\cref{sec:evaluation}).
|
|
51
|
+
\end{itemize}
|
|
52
|
+
|
|
53
|
+
\Cref{sec:using} describes Papilot as an author uses it, \cref{sec:background}
|
|
54
|
+
collects the background on \TeX{}, PDF, Git and SyncTeX that the later sections
|
|
55
|
+
rely on, \cref{sec:related} discusses related
|
|
56
|
+
work, and \cref{sec:conclusion} concludes. Longer proofs are in
|
|
57
|
+
\cref{app:proofs}; \cref{app:reference} lists the notation and the keyboard
|
|
58
|
+
shortcuts.
|
|
59
|
+
|
|
60
|
+
\subsection{A note on this document}
|
|
61
|
+
|
|
62
|
+
This paper is also Papilot's example manuscript. It is deliberately dense with
|
|
63
|
+
displayed mathematics, theorems and cross-references, because those are the
|
|
64
|
+
places where an agent's edit is easiest to get subtly wrong and a typeset
|
|
65
|
+
review most useful. The reader is invited to start a task against any equation
|
|
66
|
+
and to review the result.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
\section{Using Papilot}
|
|
2
|
+
\label{sec:using}
|
|
3
|
+
|
|
4
|
+
This section describes Papilot as an author meets it. The later sections
|
|
5
|
+
explain why it behaves as it does.
|
|
6
|
+
|
|
7
|
+
\subsection{Running it}
|
|
8
|
+
|
|
9
|
+
Papilot needs Node.js~22.22 or later, Git, a \TeX{} installation with
|
|
10
|
+
\texttt{latexmk} and \texttt{synctex}, and a signed-in agent on the host. It is
|
|
11
|
+
installed and started with
|
|
12
|
+
\begin{verbatim}
|
|
13
|
+
npm install -g papilot
|
|
14
|
+
papilot
|
|
15
|
+
\end{verbatim}
|
|
16
|
+
and then opened at \texttt{http://127.0.0.1:4317}. \emph{Add paper} registers a
|
|
17
|
+
\LaTeX{} Git repository on the host; later papers are added and switched from
|
|
18
|
+
the paper menu at the top of the sidebar. A repository must have at least one
|
|
19
|
+
commit and compile with \texttt{latexmk}; a custom root document is named in a
|
|
20
|
+
\texttt{.latex-review.json} file. To try a sample first, \texttt{papilot demo}
|
|
21
|
+
copies this paper into a separate repository and registers it as
|
|
22
|
+
\emph{Papilot paper}, without touching any existing manuscript.
|
|
23
|
+
|
|
24
|
+
\subsection{A task from start to finish}
|
|
25
|
+
|
|
26
|
+
\begin{enumerate}
|
|
27
|
+
\item Select \emph{New task}, describe the revision and press Enter. The first
|
|
28
|
+
line of the prompt becomes the task's title, and the task runs on the paper
|
|
29
|
+
selected in the sidebar. Below the prompt, choose the agent, its model and
|
|
30
|
+
its reasoning effort; Papilot remembers all three for the next task.
|
|
31
|
+
\item Follow the conversation and answer the agent's questions or permission
|
|
32
|
+
requests. When both execution slots are busy, further tasks queue
|
|
33
|
+
(\cref{sec:agents}).
|
|
34
|
+
\item When the agent finishes, Papilot builds the PDF review automatically.
|
|
35
|
+
Accept, reject or comment on each change in the typeset review.
|
|
36
|
+
\item Send the saved comments, or write further instructions in the
|
|
37
|
+
conversation. Either starts the next round, which carries the review
|
|
38
|
+
feedback with it (\cref{sec:model}).
|
|
39
|
+
\end{enumerate}
|
|
40
|
+
|
|
41
|
+
While the agent works, the composer shows a stop button that pauses the task.
|
|
42
|
+
The desktop workspace offers three views, \emph{Review}, \emph{Split} and
|
|
43
|
+
\emph{Chat}, and remembers the choice; on a phone the header switches between
|
|
44
|
+
the review and the chat. The review toolbar shows the round's progress, accepts
|
|
45
|
+
or rejects every undecided change at once, opens the full PDF of the round,
|
|
46
|
+
builds the review again, and opens it in a separate tab. \emph{Accept all} and
|
|
47
|
+
\emph{Reject all} act only on changes not yet decided, and one undo reverses the
|
|
48
|
+
whole batch.
|
|
49
|
+
|
|
50
|
+
Conversation drafts are saved per task in the browser; Enter sends, Shift+Enter
|
|
51
|
+
adds a line, and an input method's composition is never sent by Enter. Closing
|
|
52
|
+
the browser does not stop a run. After a restart of the host process, turns that
|
|
53
|
+
were in flight are marked interrupted and can be continued, and queued messages
|
|
54
|
+
are kept. If the outcome of a request is uncertain, the task offers
|
|
55
|
+
\emph{Check status}, and further decisions wait until it is resolved.
|
|
56
|
+
|
|
57
|
+
\subsection{Reading the paper}
|
|
58
|
+
|
|
59
|
+
\emph{PDF}, under the paper in the sidebar, shows the manuscript as it is on
|
|
60
|
+
disk, including accepted but uncommitted changes (\cref{sec:build}). It behaves
|
|
61
|
+
like a local PDF reader: continuous pages with crisp text at any zoom,
|
|
62
|
+
selectable text, working links and cross-references, and search across the
|
|
63
|
+
whole document.
|
|
64
|
+
\begin{itemize}
|
|
65
|
+
\item \emph{Contents} lists the PDF's bookmarks, which \texttt{hyperref}
|
|
66
|
+
writes for every section, highlights the section being read, and jumps to
|
|
67
|
+
any entry. The same list opens from the toolbar.
|
|
68
|
+
\item A page number or the arrows change page; the zoom buttons, the zoom
|
|
69
|
+
menu, the keyboard and a pinch change the zoom, which is remembered.
|
|
70
|
+
\item Find (Cmd+F) searches every page, with Enter and Shift+Enter stepping
|
|
71
|
+
through the matches.
|
|
72
|
+
\end{itemize}
|
|
73
|
+
|
|
74
|
+
\subsection{Notes on the PDF}
|
|
75
|
+
|
|
76
|
+
To ask for a change directly on the PDF, select text and choose \emph{Add note},
|
|
77
|
+
or mark a region around a figure or an equation, then describe the change. The
|
|
78
|
+
selection follows the printed words exactly (\cref{sec:geometry}), each note is
|
|
79
|
+
settled on the source lines that produced it (\cref{sec:notes}), and every
|
|
80
|
+
pending note is sent to the agent as one task.
|
|
81
|
+
|
|
82
|
+
\subsection{The Git panel}
|
|
83
|
+
|
|
84
|
+
Beside the PDF, a small source-control panel shows the branch and how it
|
|
85
|
+
compares with its upstream, the last commit, and the uncommitted changes with
|
|
86
|
+
their line counts. Selecting a file shows its difference. Ticking files,
|
|
87
|
+
writing a message and pressing Enter commits exactly those files as they are on
|
|
88
|
+
disk; fetch, a fast-forward pull and push keep the branch in step with its
|
|
89
|
+
remote (\cref{sec:git}).
|
|
90
|
+
|
|
91
|
+
\subsection{Agents}
|
|
92
|
+
|
|
93
|
+
Each task runs on one agent: Codex through its app server, Claude through the
|
|
94
|
+
Claude Agent SDK, or Antigravity through its command line. Every agent uses its
|
|
95
|
+
own login on the host, and an agent that is not installed or signed in is listed
|
|
96
|
+
as unavailable. When an agent reports usage, the new-task page shows each usage
|
|
97
|
+
window with how much is used and when it resets (\cref{sec:usage}).
|
|
98
|
+
|
|
99
|
+
\subsection{Working from another device}
|
|
100
|
+
|
|
101
|
+
Papilot binds only to \texttt{127.0.0.1}. To reach it from a phone or another
|
|
102
|
+
computer, it is published on a private Tailscale network, and the server checks
|
|
103
|
+
the host, the browser's origin and the Tailscale identity of every remote
|
|
104
|
+
request (\cref{sec:security}):
|
|
105
|
+
\begin{verbatim}
|
|
106
|
+
export PAPILOT_PUBLIC_ORIGIN=https://your-mac.your-tailnet.ts.net:8443
|
|
107
|
+
export PAPILOT_TAILSCALE_LOGIN=your-tailscale-login
|
|
108
|
+
papilot service install
|
|
109
|
+
tailscale serve --bg --https=8443 http://127.0.0.1:4317
|
|
110
|
+
\end{verbatim}
|
|
111
|
+
A background service starts Papilot after login, restarts it if it exits and
|
|
112
|
+
keeps the computer from sleeping while it runs. Without Tailscale, an SSH
|
|
113
|
+
tunnel serves the same purpose.
|
|
114
|
+
|
|
115
|
+
\subsection{Configuration}
|
|
116
|
+
|
|
117
|
+
\begin{center}
|
|
118
|
+
\small
|
|
119
|
+
\begin{tabular}{@{}lp{0.62\linewidth}@{}}
|
|
120
|
+
\toprule
|
|
121
|
+
Variable & Purpose \\
|
|
122
|
+
\midrule
|
|
123
|
+
\texttt{PAPILOT\_PORT} & local HTTP port, $4317$ by default \\
|
|
124
|
+
\texttt{PAPILOT\_DATA} & state and generated example, \texttt{\textasciitilde/.papilot} by default \\
|
|
125
|
+
\texttt{PAPILOT\_CODEX\_BIN} & Codex executable \\
|
|
126
|
+
\texttt{ANTHROPIC\_API\_KEY} & API key for Claude tasks \\
|
|
127
|
+
\texttt{PAPILOT\_AGY\_BIN} & Antigravity command line \\
|
|
128
|
+
\texttt{PAPILOT\_AGY\_PROXY} & HTTP proxy used only for Antigravity \\
|
|
129
|
+
\texttt{PAPILOT\_REVIEW\_ENGINE} & review engine directory \\
|
|
130
|
+
\texttt{PAPILOT\_PUBLIC\_ORIGIN} & exact browser origin for remote access \\
|
|
131
|
+
\texttt{PAPILOT\_TAILSCALE\_LOGIN} & Tailscale login allowed to connect \\
|
|
132
|
+
\bottomrule
|
|
133
|
+
\end{tabular}
|
|
134
|
+
\end{center}
|