papilot 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -75,7 +75,7 @@ npm install -g papilot
75
75
  papilot demo
76
76
  ```
77
77
 
78
- Open **http://127.0.0.1:4317** and choose **PDF** in the sidebar. The demo adds an example paper to revise: a 26-page LaTeX paper about Papilot itself, full of equations. When you are ready, run `papilot` and choose **Add paper** to add any LaTeX project in a Git repository.
78
+ Open **http://127.0.0.1:7274** and choose **PDF** in the sidebar. The demo adds an example paper to revise: a 26-page LaTeX paper about Papilot itself, full of equations. When you are ready, run `papilot` and choose **Add paper** to add any LaTeX project in a Git repository.
79
79
 
80
80
  ## 🤖 Agents
81
81
 
package/README.zh-CN.md CHANGED
@@ -75,7 +75,7 @@ npm install -g papilot
75
75
  papilot demo
76
76
  ```
77
77
 
78
- 打开 **http://127.0.0.1:4317**,在侧栏选择 **PDF**。demo 会添加一篇示例论文供你修改:一篇讲 Papilot 本身的 26 页 LaTeX 论文,满是公式。准备好之后,运行 `papilot`,选择 **Add paper**,即可添加任何放在 Git 仓库里的 LaTeX 项目。
78
+ 打开 **http://127.0.0.1:7274**,在侧栏选择 **PDF**。demo 会添加一篇示例论文供你修改:一篇讲 Papilot 本身的 26 页 LaTeX 论文,满是公式。准备好之后,运行 `papilot`,选择 **Add paper**,即可添加任何放在 Git 仓库里的 LaTeX 项目。
79
79
 
80
80
  ## 🤖 智能体
81
81
 
package/bin/papilot.mjs CHANGED
@@ -8,7 +8,7 @@ import { fileURLToPath } from 'node:url';
8
8
 
9
9
  const usage = `Usage: papilot [demo | codex <args> | service install | service stop] [--port <number>] [--data <folder>]
10
10
 
11
- papilot Start Papilot at http://127.0.0.1:4317
11
+ papilot Start Papilot at http://127.0.0.1:7274
12
12
  papilot demo Add the example paper, then start
13
13
  papilot codex login Sign in to Codex with the Codex that Papilot uses
14
14
  papilot service install Run Papilot in the background after login (macOS)
@@ -106,7 +106,7 @@ if (service) {
106
106
  await import('../src/server/main.ts');
107
107
  } catch (error) {
108
108
  if (error?.code !== 'EADDRINUSE') throw error;
109
- console.error(`Port ${process.env.PAPILOT_PORT || 4317} is already in use. Is Papilot already running? Start another copy with --port <number>.`);
109
+ console.error(`Port ${process.env.PAPILOT_PORT || 7274} is already in use. Is Papilot already running? Start another copy with --port <number>.`);
110
110
  process.exit(1);
111
111
  }
112
112
  if (!tex) console.warn('\nlatexmk was not found, so PDFs cannot be built yet. Install MacTeX or TeX Live (the full distribution), open a new terminal and run papilot again.');
@@ -13,7 +13,7 @@ installed and started with
13
13
  npm install -g papilot
14
14
  papilot
15
15
  \end{verbatim}
16
- and then opened at \texttt{http://127.0.0.1:4317}. \emph{Add paper} registers a
16
+ and then opened at \texttt{http://127.0.0.1:7274}. \emph{Add paper} registers a
17
17
  \LaTeX{} Git repository on the host; later papers are added and switched from
18
18
  the paper menu at the top of the sidebar. A repository must have at least one
19
19
  commit and compile with \texttt{latexmk}; a custom root document is named in a
@@ -106,7 +106,7 @@ request (\cref{sec:security}):
106
106
  export PAPILOT_PUBLIC_ORIGIN=https://your-mac.your-tailnet.ts.net:8443
107
107
  export PAPILOT_TAILSCALE_LOGIN=your-tailscale-login
108
108
  papilot service install
109
- tailscale serve --bg --https=8443 http://127.0.0.1:4317
109
+ tailscale serve --bg --https=8443 http://127.0.0.1:7274
110
110
  \end{verbatim}
111
111
  A background service starts Papilot after login, restarts it if it exits and
112
112
  keeps the computer from sleeping while it runs. Without Tailscale, an SSH
@@ -120,7 +120,7 @@ tunnel serves the same purpose.
120
120
  \toprule
121
121
  Variable & Purpose \\
122
122
  \midrule
123
- \texttt{PAPILOT\_PORT} & local HTTP port, $4317$ by default \\
123
+ \texttt{PAPILOT\_PORT} & local HTTP port, $7274$ by default \\
124
124
  \texttt{PAPILOT\_DATA} & state and generated example, \texttt{\textasciitilde/.papilot} by default \\
125
125
  \texttt{PAPILOT\_CODEX\_BIN} & Codex executable \\
126
126
  \texttt{ANTHROPIC\_API\_KEY} & API key for Claude tasks \\
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "papilot",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A Cursor-like workspace for your papers: annotate and review PDFs directly without ever touching LaTeX.",
5
5
  "keywords": [
6
6
  "latex",
@@ -1,7 +1,7 @@
1
1
  import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';
2
2
  import { createInterface } from 'node:readline';
3
3
  import { EventEmitter } from 'node:events';
4
- import { CODEX, ROOT } from './paths.ts';
4
+ import { CODEX, ROOT, VERSION } from './paths.ts';
5
5
 
6
6
  export class RpcResponseError extends Error {}
7
7
 
@@ -34,7 +34,7 @@ export class Codex extends EventEmitter {
34
34
  };
35
35
  child.once('error', failed);
36
36
  child.once('exit', (code, signal) => failed(new Error(`Codex exited (${signal || code})`)));
37
- await this.request('initialize', { clientInfo: { name: 'papilot', title: 'Papilot', version: '0.1.0' } });
37
+ await this.request('initialize', { clientInfo: { name: 'papilot', title: 'Papilot', version: VERSION } });
38
38
  this.notify('initialized', {}); this.ready = true;
39
39
  }
40
40
  private receive(message: any) {
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import { randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
7
7
  import { Store } from './store.ts';
8
8
  import { Workspace } from './workspace.ts';
9
- import { ROOT, DATA, PORT, PUBLIC_ORIGIN, OWNER } from './paths.ts';
9
+ import { ROOT, DATA, PORT, PUBLIC_ORIGIN, OWNER, VERSION } from './paths.ts';
10
10
  import { reviewClient, allowedReviewRoute, rewriteReviewHtml, rewriteReviewJson, confirmedReviewResponse, annotateReviewState } from './review.ts';
11
11
  import { authorize } from './security.ts';
12
12
  import { fullPaperPdf } from './pdf.ts';
@@ -27,7 +27,7 @@ app.addHook('onRequest', async (request, reply) => {
27
27
  if (request.method === 'POST' && !request.url.startsWith('/review/') && !equals(String(request.headers['x-papilot-token'] || ''), csrf)) return reply.code(403).send({ error: 'This page has expired. Refresh it and try again.' });
28
28
  });
29
29
  app.setErrorHandler((error, _request, reply) => { reply.code((error as any).statusCode || 400).send({ error: (error as Error).message }); });
30
- app.get('/api/health', () => ({ ok: true, name: 'Papilot', version: '0.1.0' }));
30
+ app.get('/api/health', () => ({ ok: true, name: 'Papilot', version: VERSION }));
31
31
  app.get('/api/state', () => ({ ...workspace.snapshot(), csrf }));
32
32
  app.get('/api/events', (request, reply) => {
33
33
  reply.hijack();
@@ -4,7 +4,8 @@ import { fileURLToPath } from 'node:url';
4
4
  export const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
5
5
  export const DATA = path.resolve(process.env.PAPILOT_DATA || path.join(ROOT, '.papilot'));
6
6
  export const ENGINE = path.resolve(process.env.PAPILOT_REVIEW_ENGINE || path.join(ROOT, 'vendor/latex-review'));
7
- export const PORT = Number(process.env.PAPILOT_PORT || 4317);
7
+ export const VERSION: string = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8')).version;
8
+ export const PORT = Number(process.env.PAPILOT_PORT || 7274);
8
9
  export const PUBLIC_ORIGIN = process.env.PAPILOT_PUBLIC_ORIGIN || '';
9
10
  export const OWNER = process.env.PAPILOT_TAILSCALE_LOGIN || '';
10
11
  export const CODEX = process.env.PAPILOT_CODEX_BIN || (fs.existsSync(path.join(ROOT, 'node_modules/.bin/codex')) ? path.join(ROOT, 'node_modules/.bin/codex') : 'codex');
@@ -8,6 +8,7 @@ import { Store } from './store.ts';
8
8
  import { Codex, RpcResponseError } from './codex.ts';
9
9
  import { AGENT_NAMES, AntigravityAgent, ClaudeAgent, type AgentRuntime } from './agents.ts';
10
10
  import { reviewClient, taskRoute, confirmedReviewResponse, type ReviewClient } from './review.ts';
11
+ import { VERSION } from './paths.ts';
11
12
  import type { Task, Run, TimelineItem, PendingRequest, RuntimeStatus, Snapshot, PendingReview, AgentModel, Usage, AgentId } from '../shared.ts';
12
13
 
13
14
  const execute = promisify(execFile);
@@ -83,7 +84,7 @@ export class Workspace extends EventEmitter {
83
84
  if (id === 'codex') this.loaded.clear();
84
85
  this.emit('change');
85
86
  }
86
- snapshot(): Snapshot { return { version: '0.1.0', projects: this.store.projects(), tasks: this.store.tasks(), requests: [...this.requests.values()].map(({ rpcId: _, agent: __, ...r }) => r), runtime: this.runtime, runtimes: this.runtimes }; }
87
+ snapshot(): Snapshot { return { version: VERSION, projects: this.store.projects(), tasks: this.store.tasks(), requests: [...this.requests.values()].map(({ rpcId: _, agent: __, ...r }) => r), runtime: this.runtime, runtimes: this.runtimes }; }
87
88
  async connect() {
88
89
  if (this.connecting) return this.connecting;
89
90
  this.connecting = Promise.all(AGENTS.map(id => this.connectAgent(id))).then(() => { this.emit('change'); this.schedule(); }).finally(() => { this.connecting = null; });