pagecite 2.0.0__tar.gz

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.
@@ -0,0 +1,11 @@
1
+ # Copy to ~/.pagecite/.env (or a .env in the folder you run from).
2
+
3
+ # Needed for `summarize` and `ask` (or log in once with `ant auth login`).
4
+ ANTHROPIC_API_KEY=sk-ant-...
5
+
6
+ # Write every summary into this folder as a Markdown note (e.g. a folder in your Obsidian vault).
7
+ PAGECITE_NOTES_DIR=
8
+
9
+ # Tuning
10
+ PAGECITE_MODEL=claude-opus-5-5
11
+ PAGECITE_DB=~/.pagecite/library.db
@@ -0,0 +1,20 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.10", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v5
16
+ - uses: actions/setup-python@v6
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - run: pip install -e '.[dev]'
20
+ - run: pytest -q
@@ -0,0 +1,30 @@
1
+ # Push a version tag (e.g. v2.0.0) to test, build and publish to PyPI via Trusted Publishing (no tokens).
2
+ # The run finishes green only once pip can install the new version.
3
+ name: Publish to PyPI
4
+
5
+ on:
6
+ push:
7
+ tags: ["v*"]
8
+
9
+ jobs:
10
+ publish:
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ permissions:
14
+ id-token: write # lets PyPI verify this workflow instead of a stored token
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ - uses: actions/setup-python@v6
18
+ with:
19
+ python-version: "3.12"
20
+ - run: pip install -e '.[dev]' build
21
+ - run: pytest -q
22
+ - run: python -m build
23
+ - uses: pypa/gh-action-pypi-publish@release/v1
24
+ - name: Wait until pip can install it # PyPI's CDN can serve the old index for a few minutes after upload
25
+ run: |
26
+ for i in $(seq 30); do
27
+ pip download --no-deps --no-cache-dir -q -d /tmp/check "pagecite==${GITHUB_REF_NAME#v}" && exit 0
28
+ sleep 10
29
+ done
30
+ exit 1
@@ -0,0 +1,12 @@
1
+ .env
2
+ __pycache__/
3
+ *.pyc
4
+ .DS_Store
5
+ .venv/
6
+ venv/
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .pytest_cache/
11
+ *.db
12
+ .claude/
pagecite-2.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Owen Alderson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.5
2
+ Name: pagecite
3
+ Version: 2.0.0
4
+ Summary: Summarise research PDFs where every claim cites its page, and every quote and number is checked against the PDF text. CLI + MCP server, Obsidian notes.
5
+ Project-URL: Homepage, https://github.com/owen-alderson/pagecite
6
+ Author: Owen Alderson
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Keywords: citations,claude,mcp,obsidian,pdf,research,summarization
10
+ Classifier: Environment :: Console
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
13
+ Classifier: Topic :: Text Processing
14
+ Requires-Python: >=3.10
15
+ Requires-Dist: anthropic>=1.11
16
+ Requires-Dist: pymupdf>=1.24
17
+ Requires-Dist: truststore>=0.10
18
+ Provides-Extra: dev
19
+ Requires-Dist: mcp>=2.3; extra == 'dev'
20
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
21
+ Requires-Dist: pytest>=8; extra == 'dev'
22
+ Provides-Extra: mcp
23
+ Requires-Dist: mcp>=2.3; extra == 'mcp'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # pagecite
27
+
28
+ **Summaries of research PDFs you can actually trust: every claim cites its page, and every quote
29
+ and number is checked against the PDF before you see it.**
30
+
31
+ Point it at a paper, an analyst report or a pitch deck (a file, a folder or a URL). Claude writes
32
+ the TL;DR, key arguments, data points, quotes worth keeping and open questions. Then pagecite
33
+ checks each one against the PDF's own text, with no model involved: is the quote really on the
34
+ cited page? Do the numbers appear there? Anything that fails is kept but marked **⚠ not
35
+ verified**, with the reason, so a wrong page or a mangled figure never passes as fact.
36
+
37
+ [![CI](https://github.com/owen-alderson/pagecite/actions/workflows/ci.yml/badge.svg)](https://github.com/owen-alderson/pagecite/actions/workflows/ci.yml)
38
+ [![PyPI](https://img.shields.io/pypi/v/pagecite)](https://pypi.org/project/pagecite/)
39
+ ![License: MIT](https://img.shields.io/badge/license-MIT-blue)
40
+
41
+ ![pagecite demo: a checked summary with five verified claims and two flagged ones](docs/demo.gif)
42
+
43
+ <sub>`pagecite demo`: a fictional report and a sample summary bundled with pagecite (no API call),
44
+ with two claims deliberately wrong. The checks are the real ones.</sub>
45
+
46
+ ## Why
47
+
48
+ AI summaries read well and are hard to audit. The usual failure isn't a summary that's obviously
49
+ wrong. It's a plausible sentence with a number that drifted ("27%" where the report says 22%), or a
50
+ quote that's real but from a different section than the claim it supports. You only catch those
51
+ by rereading the document, which is what the summary was supposed to save you.
52
+
53
+ pagecite splits the work:
54
+
55
+ | | Who | What |
56
+ |---|---|---|
57
+ | **Writes** | Claude (`claude-opus-5-5`) | Reads the PDF page by page and returns a structured summary. Every argument and data point carries its page numbers and a verbatim quote. |
58
+ | **Checks** | Plain code, [`verify.py`](pagecite/verify.py) | Finds each quote on its cited page and each number in the data points on that page. No model, so no second opinion that can also be wrong. |
59
+ | **Decides** | You | Verified claims are marked ✓. Flagged ones stay in, marked ⚠ with the reason ("quote is on p. 7, not the cited p. 5", "27 not on the cited page"). |
60
+
61
+ ## What it does
62
+
63
+ - **Any PDF source:** a file, every PDF in a folder, or an `http(s)` URL.
64
+ - **Checked summary:** TL;DR, key arguments, data points, quotes worth keeping, open questions and
65
+ tags, each with page numbers. Quotes and figures are verified; open questions and the TL;DR show
66
+ their pages but have nothing quotable to check.
67
+ - **Obsidian notes:** `-o ~/Vault/Papers` writes each summary as a Markdown note with YAML
68
+ frontmatter (source, pages, model, verified/flagged counts, tags) and the flags inline.
69
+ - **A library:** every PDF you read is stored with its page text, keyed by its SHA-256. Summarising
70
+ the same file again (even under another name) costs nothing. `pagecite search` runs full-text
71
+ search over every page you've read.
72
+ - **Ask with citations:** `pagecite ask "what drives the cost gap?" --doc 3` answers from the
73
+ document with [citations](https://platform.claude.com/docs/en/build-with-claude/search-results)
74
+ returned by the API itself, so every sentence points to a page. For one document all its pages
75
+ are sent with a cache breakpoint, so follow-up questions read them from the prompt cache. Without
76
+ `--doc`, the best-matching pages across your library are sent.
77
+ - **MCP server:** Claude Desktop, Claude Code or any MCP client can summarise PDFs, search your
78
+ library, read pages and ask cited questions.
79
+
80
+ ## Quickstart
81
+
82
+ ```bash
83
+ pipx install pagecite
84
+ pagecite demo # a checked summary on a fictional report, no key needed
85
+ ```
86
+
87
+ With your own documents:
88
+
89
+ ```bash
90
+ mkdir -p ~/.pagecite && echo 'ANTHROPIC_API_KEY=sk-ant-...' >> ~/.pagecite/.env # or `ant auth login`
91
+
92
+ pagecite summarize paper.pdf
93
+ pagecite summarize ~/Downloads/reports -o ~/Obsidian/Papers # a whole folder, as notes
94
+ pagecite summarize https://arxiv.org/pdf/1706.03762
95
+ pagecite ask "what did they measure, and on what data?" --doc 1
96
+ ```
97
+
98
+ | Command | |
99
+ |---|---|
100
+ | `pagecite summarize SOURCE… [-o DIR] [--refresh]` | Summarise files, folders or URLs (alias `sum`) |
101
+ | `pagecite ask QUESTION [--doc ID]` | Answer from one document or the whole library, with page citations |
102
+ | `pagecite list` | The PDFs in your library (alias `ls`) |
103
+ | `pagecite show ID [--markdown]` | Print a stored summary, or its Obsidian note |
104
+ | `pagecite search QUERY [--doc ID]` | Full-text search over every page |
105
+ | `pagecite mcp` | Run the MCP server over stdio |
106
+ | `pagecite demo` | The demo above |
107
+
108
+ ## What counts as verified
109
+
110
+ [`verify.py`](pagecite/verify.py) is short and has no dependencies, so the rules are easy to check:
111
+
112
+ - **Quotes** must appear on the page(s) they cite. Matching ignores case, punctuation, spacing,
113
+ ligatures (`fi`) and words split across lines (`con-`/`straint`), but keeps decimal points, so
114
+ "4.2" never matches "42". An ellipsis splits a quote into parts that must appear in order.
115
+ Quotes under four words are flagged as too short to prove anything.
116
+ - **Numbers** in a data point's value must all appear on the cited page: "USD 115 per kWh, down
117
+ 14%" needs both 115 and 14 there. Thousands separators are normalised (`3,200` = `3200` =
118
+ `3 200`).
119
+ - **Pages** must exist in the document.
120
+ - When a quote is on a different page, the flag says where it really is. pagecite never moves
121
+ the citation for you.
122
+
123
+ What it can't check: whether a sentence in Claude's own words fairly represents its quote.
124
+ That's why each claim shows the quote right under it.
125
+
126
+ Scanned PDFs without a text layer are refused (OCR them first). Documents too long for one pass
127
+ are refused rather than silently truncated.
128
+
129
+ ### What leaves your machine
130
+
131
+ | | Sent to Anthropic |
132
+ |---|---|
133
+ | `summarize` | the extracted text of the whole PDF |
134
+ | `ask --doc ID` | every page of that document |
135
+ | `ask` | only the best-matching pages from your library |
136
+ | `list`, `show`, `search`, `demo` | nothing |
137
+
138
+ Your library is one SQLite file, `~/.pagecite/library.db`.
139
+
140
+ ## MCP
141
+
142
+ Add to Claude Desktop's `claude_desktop_config.json` (or `claude mcp add pagecite -- pagecite mcp`
143
+ in Claude Code):
144
+
145
+ ```json
146
+ {
147
+ "mcpServers": {
148
+ "pagecite": { "command": "pagecite", "args": ["mcp"] }
149
+ }
150
+ }
151
+ ```
152
+
153
+ Install with `pipx install 'pagecite[mcp]'`. Tools: `summarize_pdf` (returns each claim with its
154
+ check result), `ask_library`, `search`, `read` (page text) and `documents`. `search`, `read` and
155
+ `documents` need no API key.
156
+
157
+ ## Configuration
158
+
159
+ In `~/.pagecite/.env` or the environment (see [`.env.example`](.env.example)):
160
+
161
+ | Variable | Default | |
162
+ |---|---|---|
163
+ | `ANTHROPIC_API_KEY` | | Or log in once with `ant auth login` |
164
+ | `PAGECITE_NOTES_DIR` | | Always write notes here (e.g. a folder in your vault) |
165
+ | `PAGECITE_MODEL` | `claude-opus-5-5` | |
166
+ | `PAGECITE_DB` | `~/.pagecite/library.db` | |
167
+
168
+ ## How it works
169
+
170
+ ```mermaid
171
+ flowchart LR
172
+ In[file · folder · URL] --> PDF[pdf.py<br/>page texts + SHA-256]
173
+ PDF --> Lib[(library.db<br/>pages, FTS5)]
174
+ Lib -->|new file| Sum[summarize.py<br/>Claude: structured summary]
175
+ Sum --> Lib
176
+ Lib --> Verify[verify.py<br/>quotes + numbers vs page text]
177
+ Verify --> Out[terminal · Obsidian note · MCP]
178
+ Lib --> Ask[ask.py<br/>search-result blocks, cited answers]
179
+ ```
180
+
181
+ Verification runs every time a summary is shown, against the stored page text, so a stored
182
+ summary never carries a stale result.
183
+
184
+ ## Development
185
+
186
+ ```bash
187
+ git clone https://github.com/owen-alderson/pagecite && cd pagecite
188
+ python -m venv .venv && . .venv/bin/activate
189
+ pip install -e '.[dev]'
190
+ pytest # no network: Claude and HTTP are faked, test PDFs are generated
191
+ ```
192
+
193
+ Releases: push a `vX.Y.Z` tag and GitHub Actions publishes to PyPI. Re-record the demo with
194
+ `vhs docs/demo.tape`.
195
+
196
+ The original Streamlit app (pdf-research-summarizer) is kept at tag
197
+ [`v1-streamlit`](https://github.com/owen-alderson/pagecite/tree/v1-streamlit).
198
+
199
+ ## License
200
+
201
+ MIT
@@ -0,0 +1,176 @@
1
+ # pagecite
2
+
3
+ **Summaries of research PDFs you can actually trust: every claim cites its page, and every quote
4
+ and number is checked against the PDF before you see it.**
5
+
6
+ Point it at a paper, an analyst report or a pitch deck (a file, a folder or a URL). Claude writes
7
+ the TL;DR, key arguments, data points, quotes worth keeping and open questions. Then pagecite
8
+ checks each one against the PDF's own text, with no model involved: is the quote really on the
9
+ cited page? Do the numbers appear there? Anything that fails is kept but marked **⚠ not
10
+ verified**, with the reason, so a wrong page or a mangled figure never passes as fact.
11
+
12
+ [![CI](https://github.com/owen-alderson/pagecite/actions/workflows/ci.yml/badge.svg)](https://github.com/owen-alderson/pagecite/actions/workflows/ci.yml)
13
+ [![PyPI](https://img.shields.io/pypi/v/pagecite)](https://pypi.org/project/pagecite/)
14
+ ![License: MIT](https://img.shields.io/badge/license-MIT-blue)
15
+
16
+ ![pagecite demo: a checked summary with five verified claims and two flagged ones](docs/demo.gif)
17
+
18
+ <sub>`pagecite demo`: a fictional report and a sample summary bundled with pagecite (no API call),
19
+ with two claims deliberately wrong. The checks are the real ones.</sub>
20
+
21
+ ## Why
22
+
23
+ AI summaries read well and are hard to audit. The usual failure isn't a summary that's obviously
24
+ wrong. It's a plausible sentence with a number that drifted ("27%" where the report says 22%), or a
25
+ quote that's real but from a different section than the claim it supports. You only catch those
26
+ by rereading the document, which is what the summary was supposed to save you.
27
+
28
+ pagecite splits the work:
29
+
30
+ | | Who | What |
31
+ |---|---|---|
32
+ | **Writes** | Claude (`claude-opus-5-5`) | Reads the PDF page by page and returns a structured summary. Every argument and data point carries its page numbers and a verbatim quote. |
33
+ | **Checks** | Plain code, [`verify.py`](pagecite/verify.py) | Finds each quote on its cited page and each number in the data points on that page. No model, so no second opinion that can also be wrong. |
34
+ | **Decides** | You | Verified claims are marked ✓. Flagged ones stay in, marked ⚠ with the reason ("quote is on p. 7, not the cited p. 5", "27 not on the cited page"). |
35
+
36
+ ## What it does
37
+
38
+ - **Any PDF source:** a file, every PDF in a folder, or an `http(s)` URL.
39
+ - **Checked summary:** TL;DR, key arguments, data points, quotes worth keeping, open questions and
40
+ tags, each with page numbers. Quotes and figures are verified; open questions and the TL;DR show
41
+ their pages but have nothing quotable to check.
42
+ - **Obsidian notes:** `-o ~/Vault/Papers` writes each summary as a Markdown note with YAML
43
+ frontmatter (source, pages, model, verified/flagged counts, tags) and the flags inline.
44
+ - **A library:** every PDF you read is stored with its page text, keyed by its SHA-256. Summarising
45
+ the same file again (even under another name) costs nothing. `pagecite search` runs full-text
46
+ search over every page you've read.
47
+ - **Ask with citations:** `pagecite ask "what drives the cost gap?" --doc 3` answers from the
48
+ document with [citations](https://platform.claude.com/docs/en/build-with-claude/search-results)
49
+ returned by the API itself, so every sentence points to a page. For one document all its pages
50
+ are sent with a cache breakpoint, so follow-up questions read them from the prompt cache. Without
51
+ `--doc`, the best-matching pages across your library are sent.
52
+ - **MCP server:** Claude Desktop, Claude Code or any MCP client can summarise PDFs, search your
53
+ library, read pages and ask cited questions.
54
+
55
+ ## Quickstart
56
+
57
+ ```bash
58
+ pipx install pagecite
59
+ pagecite demo # a checked summary on a fictional report, no key needed
60
+ ```
61
+
62
+ With your own documents:
63
+
64
+ ```bash
65
+ mkdir -p ~/.pagecite && echo 'ANTHROPIC_API_KEY=sk-ant-...' >> ~/.pagecite/.env # or `ant auth login`
66
+
67
+ pagecite summarize paper.pdf
68
+ pagecite summarize ~/Downloads/reports -o ~/Obsidian/Papers # a whole folder, as notes
69
+ pagecite summarize https://arxiv.org/pdf/1706.03762
70
+ pagecite ask "what did they measure, and on what data?" --doc 1
71
+ ```
72
+
73
+ | Command | |
74
+ |---|---|
75
+ | `pagecite summarize SOURCE… [-o DIR] [--refresh]` | Summarise files, folders or URLs (alias `sum`) |
76
+ | `pagecite ask QUESTION [--doc ID]` | Answer from one document or the whole library, with page citations |
77
+ | `pagecite list` | The PDFs in your library (alias `ls`) |
78
+ | `pagecite show ID [--markdown]` | Print a stored summary, or its Obsidian note |
79
+ | `pagecite search QUERY [--doc ID]` | Full-text search over every page |
80
+ | `pagecite mcp` | Run the MCP server over stdio |
81
+ | `pagecite demo` | The demo above |
82
+
83
+ ## What counts as verified
84
+
85
+ [`verify.py`](pagecite/verify.py) is short and has no dependencies, so the rules are easy to check:
86
+
87
+ - **Quotes** must appear on the page(s) they cite. Matching ignores case, punctuation, spacing,
88
+ ligatures (`fi`) and words split across lines (`con-`/`straint`), but keeps decimal points, so
89
+ "4.2" never matches "42". An ellipsis splits a quote into parts that must appear in order.
90
+ Quotes under four words are flagged as too short to prove anything.
91
+ - **Numbers** in a data point's value must all appear on the cited page: "USD 115 per kWh, down
92
+ 14%" needs both 115 and 14 there. Thousands separators are normalised (`3,200` = `3200` =
93
+ `3 200`).
94
+ - **Pages** must exist in the document.
95
+ - When a quote is on a different page, the flag says where it really is. pagecite never moves
96
+ the citation for you.
97
+
98
+ What it can't check: whether a sentence in Claude's own words fairly represents its quote.
99
+ That's why each claim shows the quote right under it.
100
+
101
+ Scanned PDFs without a text layer are refused (OCR them first). Documents too long for one pass
102
+ are refused rather than silently truncated.
103
+
104
+ ### What leaves your machine
105
+
106
+ | | Sent to Anthropic |
107
+ |---|---|
108
+ | `summarize` | the extracted text of the whole PDF |
109
+ | `ask --doc ID` | every page of that document |
110
+ | `ask` | only the best-matching pages from your library |
111
+ | `list`, `show`, `search`, `demo` | nothing |
112
+
113
+ Your library is one SQLite file, `~/.pagecite/library.db`.
114
+
115
+ ## MCP
116
+
117
+ Add to Claude Desktop's `claude_desktop_config.json` (or `claude mcp add pagecite -- pagecite mcp`
118
+ in Claude Code):
119
+
120
+ ```json
121
+ {
122
+ "mcpServers": {
123
+ "pagecite": { "command": "pagecite", "args": ["mcp"] }
124
+ }
125
+ }
126
+ ```
127
+
128
+ Install with `pipx install 'pagecite[mcp]'`. Tools: `summarize_pdf` (returns each claim with its
129
+ check result), `ask_library`, `search`, `read` (page text) and `documents`. `search`, `read` and
130
+ `documents` need no API key.
131
+
132
+ ## Configuration
133
+
134
+ In `~/.pagecite/.env` or the environment (see [`.env.example`](.env.example)):
135
+
136
+ | Variable | Default | |
137
+ |---|---|---|
138
+ | `ANTHROPIC_API_KEY` | | Or log in once with `ant auth login` |
139
+ | `PAGECITE_NOTES_DIR` | | Always write notes here (e.g. a folder in your vault) |
140
+ | `PAGECITE_MODEL` | `claude-opus-5-5` | |
141
+ | `PAGECITE_DB` | `~/.pagecite/library.db` | |
142
+
143
+ ## How it works
144
+
145
+ ```mermaid
146
+ flowchart LR
147
+ In[file · folder · URL] --> PDF[pdf.py<br/>page texts + SHA-256]
148
+ PDF --> Lib[(library.db<br/>pages, FTS5)]
149
+ Lib -->|new file| Sum[summarize.py<br/>Claude: structured summary]
150
+ Sum --> Lib
151
+ Lib --> Verify[verify.py<br/>quotes + numbers vs page text]
152
+ Verify --> Out[terminal · Obsidian note · MCP]
153
+ Lib --> Ask[ask.py<br/>search-result blocks, cited answers]
154
+ ```
155
+
156
+ Verification runs every time a summary is shown, against the stored page text, so a stored
157
+ summary never carries a stale result.
158
+
159
+ ## Development
160
+
161
+ ```bash
162
+ git clone https://github.com/owen-alderson/pagecite && cd pagecite
163
+ python -m venv .venv && . .venv/bin/activate
164
+ pip install -e '.[dev]'
165
+ pytest # no network: Claude and HTTP are faked, test PDFs are generated
166
+ ```
167
+
168
+ Releases: push a `vX.Y.Z` tag and GitHub Actions publishes to PyPI. Re-record the demo with
169
+ `vhs docs/demo.tape`.
170
+
171
+ The original Streamlit app (pdf-research-summarizer) is kept at tag
172
+ [`v1-streamlit`](https://github.com/owen-alderson/pagecite/tree/v1-streamlit).
173
+
174
+ ## License
175
+
176
+ MIT
@@ -0,0 +1,23 @@
1
+ # Re-record the README demo: `vhs docs/demo.tape` from the repo root, with pagecite installed in .venv.
2
+ # It runs `pagecite demo`: a fictional report and a sample summary (no API call); the checks are real.
3
+ Output docs/demo.gif
4
+
5
+ Set Shell zsh
6
+ Set FontSize 13
7
+ Set Width 1180
8
+ Set Height 680
9
+ Set Padding 14
10
+ Set Framerate 15
11
+ Set TypingSpeed 55ms
12
+ Set Theme { "background": "#000000", "foreground": "#e0e0e0" }
13
+
14
+ Hide
15
+ Type "export PATH=$PWD/.venv/bin:$PATH PS1='$ ' && clear"
16
+ Enter
17
+ Sleep 1s
18
+ Show
19
+
20
+ Type "pagecite demo"
21
+ Sleep 600ms
22
+ Enter
23
+ Sleep 9s
@@ -0,0 +1,3 @@
1
+ """pagecite: summarise research PDFs where every claim cites its page and is checked against the text."""
2
+
3
+ __version__ = "2.0.0"