bibcite-cli 0.5.4__tar.gz → 0.6.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.
Files changed (32) hide show
  1. bibcite_cli-0.6.0/.github/workflows/ci.yml +64 -0
  2. bibcite_cli-0.6.0/.github/workflows/publish.yml +74 -0
  3. bibcite_cli-0.6.0/PKG-INFO +213 -0
  4. bibcite_cli-0.6.0/Readme.md +200 -0
  5. bibcite_cli-0.6.0/assets/bibcite.svg +21 -0
  6. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/pyproject.toml +2 -1
  7. bibcite_cli-0.6.0/skills/bibcite/SKILL.md +80 -0
  8. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/__init__.py +1 -1
  9. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/bibfile.py +4 -1
  10. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/cli.py +26 -8
  11. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/resolve.py +20 -9
  12. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/sources.py +23 -6
  13. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_bibfile.py +10 -0
  14. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_bugfixes.py +13 -0
  15. bibcite_cli-0.6.0/tests/test_cli_status.py +124 -0
  16. bibcite_cli-0.6.0/tests/test_source_retries.py +143 -0
  17. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/uv.lock +31 -2
  18. bibcite_cli-0.5.4/PKG-INFO +0 -98
  19. bibcite_cli-0.5.4/Readme.md +0 -85
  20. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/.gitignore +0 -0
  21. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/LICENSE +0 -0
  22. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/cache.py +0 -0
  23. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/data/strings.bib +0 -0
  24. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/normalize.py +0 -0
  25. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/src/bibcite/venues.py +0 -0
  26. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_entry_types.py +0 -0
  27. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_normalize.py +0 -0
  28. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_round2.py +0 -0
  29. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_round3.py +0 -0
  30. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_status_semantics.py +0 -0
  31. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_strings_override.py +0 -0
  32. {bibcite_cli-0.5.4 → bibcite_cli-0.6.0}/tests/test_venues.py +0 -0
@@ -0,0 +1,64 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ test:
14
+ name: Test on Python ${{ matrix.python-version }}
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version:
20
+ - "3.10"
21
+ - "3.11"
22
+ - "3.12"
23
+ - "3.13"
24
+ - "3.14"
25
+ steps:
26
+ - name: Check out the repository
27
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
28
+
29
+ - name: Install uv and Python
30
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+ enable-cache: true
34
+
35
+ - name: Install dependencies
36
+ run: uv sync --frozen --all-groups
37
+
38
+ - name: Run tests
39
+ run: uv run --frozen pytest -q
40
+
41
+ quality:
42
+ name: Lint and build
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - name: Check out the repository
46
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
47
+
48
+ - name: Install uv and Python
49
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
50
+ with:
51
+ python-version: "3.13"
52
+ enable-cache: true
53
+
54
+ - name: Install dependencies
55
+ run: uv sync --frozen --all-groups
56
+
57
+ - name: Run Ruff
58
+ run: uv run --frozen ruff check .
59
+
60
+ - name: Build distributions
61
+ run: uv build
62
+
63
+ - name: Smoke-test the wheel
64
+ run: uvx --from dist/*.whl bibcite --help
@@ -0,0 +1,74 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - published
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ name: Build and verify distributions
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Check out the release
17
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
18
+ with:
19
+ ref: ${{ github.event.release.tag_name }}
20
+
21
+ - name: Install uv and Python
22
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
23
+ with:
24
+ python-version: "3.13"
25
+
26
+ - name: Verify the release tag matches the package version
27
+ run: |
28
+ package_version="$(uv version --short)"
29
+ if [ "${GITHUB_REF_NAME}" != "v${package_version}" ]; then
30
+ echo "Release tag ${GITHUB_REF_NAME} does not match package version ${package_version}."
31
+ exit 1
32
+ fi
33
+
34
+ - name: Install dependencies
35
+ run: uv sync --frozen --all-groups
36
+
37
+ - name: Run tests
38
+ run: uv run --frozen pytest -q
39
+
40
+ - name: Run Ruff
41
+ run: uv run --frozen ruff check .
42
+
43
+ - name: Build distributions
44
+ run: uv build
45
+
46
+ - name: Smoke-test the wheel
47
+ run: uvx --from dist/*.whl bibcite --help
48
+
49
+ - name: Upload distributions
50
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
51
+ with:
52
+ name: python-package-distributions
53
+ path: dist/
54
+ if-no-files-found: error
55
+
56
+ publish:
57
+ name: Upload release to PyPI
58
+ needs: build
59
+ runs-on: ubuntu-latest
60
+ environment:
61
+ name: pypi
62
+ url: https://pypi.org/p/bibcite-cli
63
+ permissions:
64
+ contents: read
65
+ id-token: write
66
+ steps:
67
+ - name: Download distributions
68
+ uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
69
+ with:
70
+ name: python-package-distributions
71
+ path: dist/
72
+
73
+ - name: Publish distributions to PyPI
74
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: bibcite-cli
3
+ Version: 0.6.0
4
+ Summary: Resolve papers (arXiv id / DOI / title) to canonical, normalized BibTeX for agents and humans
5
+ Project-URL: Repository, https://github.com/leo1oel/bibcite
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: arxiv,bibliography,bibtex,citations,dblp
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: bibtexparser<2,>=1.4
11
+ Requires-Dist: httpx>=0.27
12
+ Description-Content-Type: text/markdown
13
+
14
+ <p align="center">
15
+ <img src="assets/bibcite.svg" width="128" alt="bibcite logo">
16
+ </p>
17
+
18
+ <h1 align="center">bibcite</h1>
19
+
20
+ <p align="center">
21
+ Turn an arXiv ID, DOI, or paper title into clean BibTeX, then keep the whole bibliography normalized and deduplicated.
22
+ </p>
23
+
24
+ <p align="center">
25
+ <a href="https://pypi.org/project/bibcite-cli/"><img alt="PyPI" src="https://img.shields.io/pypi/v/bibcite-cli?color=6366f1"></a>
26
+ <a href="https://pypi.org/project/bibcite-cli/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/bibcite-cli"></a>
27
+ <a href="LICENSE"><img alt="License" src="https://img.shields.io/github/license/leo1oel/bibcite"></a>
28
+ </p>
29
+
30
+ `bibcite` resolves a paper to its published record when one exists, preserves arXiv links, canonicalizes venue names, and writes the result into a `.bib` file without breaking existing citation keys.
31
+ It is built for both terminal use and coding agents that need a dependable alternative to editing BibTeX by hand.
32
+
33
+ ## Quick start with an agent
34
+
35
+ Install the bundled skill so your coding agent knows how to manage citations with `bibcite`:
36
+
37
+ ```bash
38
+ npx -y skills add leo1oel/bibcite --skill bibcite --global --yes
39
+ ```
40
+
41
+ Install the CLI once as well, or let the agent install it on the first bibliography task:
42
+
43
+ ```bash
44
+ uv tool install bibcite-cli
45
+ ```
46
+
47
+ You can then ask your agent to handle the bibliography in plain language:
48
+
49
+ ```text
50
+ Add arXiv:1706.03762 to references.bib and cite it in main.tex.
51
+ Upgrade the arXiv entries in references.bib to their published versions.
52
+ Check and fix references.bib before submission.
53
+ ```
54
+
55
+ The skill tells the agent to call `bibcite` for every `.bib` change, read the citation key from its JSON output, and use that exact key in `\cite{...}`.
56
+ The agent never needs to guess a key or edit a BibTeX entry by hand.
57
+
58
+ ## Use the CLI directly
59
+
60
+ Install the command from PyPI if you have not already done so:
61
+
62
+ ```bash
63
+ uv tool install bibcite-cli
64
+ ```
65
+
66
+ Resolve a paper and add it to your bibliography:
67
+
68
+ ```bash
69
+ bibcite add references.bib 1706.03762
70
+ ```
71
+
72
+ The command prints a machine-readable result, including the stable citation key:
73
+
74
+ ```json
75
+ {
76
+ "query": "1706.03762",
77
+ "action": "added",
78
+ "key": "vaswani2017attention",
79
+ "title": "Attention is All you Need",
80
+ "venue": "Advances in Neural Information Processing Systems (NIPS)",
81
+ "published": true,
82
+ "source": "semanticscholar",
83
+ "file": "references.bib",
84
+ "tidied": true
85
+ }
86
+ ```
87
+
88
+ You can now cite it as `\cite{vaswani2017attention}`.
89
+ Running the same command again is safe: `bibcite` detects the existing entry and does not add a duplicate.
90
+
91
+ When `add` writes a new entry, it runs [bibtex-tidy](https://github.com/FlamingTempura/bibtex-tidy) automatically unless you pass `--no-tidy`.
92
+ It uses a globally installed `bibtex-tidy` command when available and otherwise runs it through `npx --yes bibtex-tidy`.
93
+ `npx` downloads the formatter automatically on first use, so the agent-first setup does not require a separate `bibtex-tidy` installation.
94
+ The JSON result reports `"tidied": true` when formatting succeeds.
95
+
96
+ If neither `bibtex-tidy` nor `npx` is available, or if the formatter fails, the entry remains written but the command exits with code `1` and reports `"tidied": false`.
97
+ An `"action": "exists"` result also reports `"tidied": false` because no file change occurred, so `add` skips the formatting pass.
98
+ Run `bibcite tidy references.bib` or `bibcite fix references.bib` when you want to format an existing file.
99
+
100
+ You can also try a one-off command without installing `bibcite`:
101
+
102
+ ```bash
103
+ uvx --from bibcite-cli bibcite get "Attention is all you need"
104
+ ```
105
+
106
+ ## What it handles
107
+
108
+ - It accepts arXiv IDs and URLs, arXiv DOIs such as `10.48550/arXiv.1706.03762`, standard DOIs, and paper titles.
109
+ - It searches for a published version before falling back to an arXiv preprint, and it reports when source outages make that check incomplete.
110
+ - It canonicalizes journal, conference, and workshop names against the bundled venue table, including year-sensitive names such as NIPS and NeurIPS.
111
+ - It assigns the correct BibTeX entry type and field, such as `@inproceedings` with `booktitle` or `@article` with `journal`.
112
+ - It deduplicates by arXiv ID, DOI, exact title, and similar titles from the same first author.
113
+ - It upgrades preprints in place while preserving citation keys already used by your LaTeX source.
114
+
115
+ ## Commands
116
+
117
+ | Command | Purpose |
118
+ | --- | --- |
119
+ | `bibcite get <query>` | Preview resolved BibTeX without writing a file. |
120
+ | `bibcite add <file> <query>` | Resolve, deduplicate, add, and tidy an entry. |
121
+ | `bibcite add <file> --bibtex "..."` | Normalize and add a raw BibTeX entry. |
122
+ | `bibcite add <file> --from ids.txt` | Add one query per line and tidy once at the end. |
123
+ | `bibcite upgrade <file>` | Replace arXiv entries with published records when available. |
124
+ | `bibcite check <file>` | Find missing fields, duplicates, preprints, and all-caps author names without changing the file. |
125
+ | `bibcite tidy <file>` | Apply the canonical `bibtex-tidy` formatting rules. |
126
+ | `bibcite fix <file>` | Upgrade preprints, tidy the file, and run the checks in one command. |
127
+ | `bibcite remove <file> <key>` | Remove an entry by citation key. |
128
+
129
+ ### Common workflows
130
+
131
+ Preview a result as BibTeX or JSON:
132
+
133
+ ```bash
134
+ bibcite get 1706.03762
135
+ bibcite get 10.1109/CVPR52688.2022.01167 --json
136
+ ```
137
+
138
+ Add raw BibTeX from the clipboard:
139
+
140
+ ```bash
141
+ pbpaste | bibcite add references.bib --bibtex -
142
+ ```
143
+
144
+ Replace a bad entry while keeping its current key:
145
+
146
+ ```bash
147
+ bibcite add references.bib "correct paper title" --key existingKey
148
+ ```
149
+
150
+ Check what would be upgraded without writing the file:
151
+
152
+ ```bash
153
+ bibcite upgrade references.bib --dry-run
154
+ ```
155
+
156
+ Mark a confirmed preprint-only entry with `pubstate = {preprint}` if you want `check` and `upgrade` to leave it alone.
157
+
158
+ ## How resolution works
159
+
160
+ For arXiv IDs and titles, `bibcite` collects paper metadata and checks publication sources in a cascade derived from [PaperMemory](https://github.com/vict0rsch/PaperMemory): DBLP, Semantic Scholar, Google Scholar, Crossref, Unpaywall, and OpenAlex.
161
+ A published match must have the same normalized title or pass a guarded title-drift check, have a plausible publication year, and name a non-preprint venue.
162
+
163
+ Successful published matches are cached at `~/.cache/bibcite/published.json`.
164
+ Preprint-only results are never cached because a paper may be published later.
165
+ Use `--no-cache` or set `BIBCITE_NO_CACHE=1` to bypass the cache.
166
+
167
+ ## Configuration
168
+
169
+ Set `BIBCITE_STRINGS=/path/to/strings.bib` to use your own venue table, or place one at `~/.config/bibcite/strings.bib`.
170
+
171
+ These optional environment variables improve source reliability:
172
+
173
+ | Variable | Effect |
174
+ | --- | --- |
175
+ | `OPENALEX_API_KEY` | Uses your OpenAlex quota instead of the anonymous shared pool. |
176
+ | `S2_API_KEY` | Uses a private Semantic Scholar quota. |
177
+ | `BIBCITE_MAILTO` | Sends your contact email to the Crossref, OpenAlex, and Unpaywall polite pools. |
178
+ | `BIBCITE_CORE_SOURCES` | Overrides the sources required for a trustworthy publication check. |
179
+ | `BIBCITE_NO_CACHE=1` | Disables the local publication cache. |
180
+
181
+ ## Exit codes and agent use
182
+
183
+ `add`, `remove`, `upgrade`, `check`, and `fix` print JSON on standard output and send diagnostics to standard error.
184
+ This keeps their output easy to parse from scripts and agents.
185
+
186
+ | Code | Meaning |
187
+ | --- | --- |
188
+ | `0` | The command completed successfully. |
189
+ | `1` | A file, lint, or formatting problem remains. |
190
+ | `2` | The paper or requested entry could not be found. |
191
+ | `3` | Publication sources or an internal tool failed. |
192
+
193
+ Agents should call `bibcite add <file> <query>` and use the returned `key` in `\cite{...}`.
194
+ They should never modify `.bib` entries directly because doing so bypasses deduplication, venue normalization, and stable-key handling.
195
+
196
+ ## Development
197
+
198
+ ```bash
199
+ git clone https://github.com/leo1oel/bibcite.git
200
+ cd bibcite
201
+ uv sync --all-groups
202
+ uv run pytest
203
+ ```
204
+
205
+ Install the checkout as an editable command while developing:
206
+
207
+ ```bash
208
+ uv tool install --editable .
209
+ ```
210
+
211
+ ## License
212
+
213
+ `bibcite` is available under the [MIT License](LICENSE).
@@ -0,0 +1,200 @@
1
+ <p align="center">
2
+ <img src="assets/bibcite.svg" width="128" alt="bibcite logo">
3
+ </p>
4
+
5
+ <h1 align="center">bibcite</h1>
6
+
7
+ <p align="center">
8
+ Turn an arXiv ID, DOI, or paper title into clean BibTeX, then keep the whole bibliography normalized and deduplicated.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://pypi.org/project/bibcite-cli/"><img alt="PyPI" src="https://img.shields.io/pypi/v/bibcite-cli?color=6366f1"></a>
13
+ <a href="https://pypi.org/project/bibcite-cli/"><img alt="Python" src="https://img.shields.io/pypi/pyversions/bibcite-cli"></a>
14
+ <a href="LICENSE"><img alt="License" src="https://img.shields.io/github/license/leo1oel/bibcite"></a>
15
+ </p>
16
+
17
+ `bibcite` resolves a paper to its published record when one exists, preserves arXiv links, canonicalizes venue names, and writes the result into a `.bib` file without breaking existing citation keys.
18
+ It is built for both terminal use and coding agents that need a dependable alternative to editing BibTeX by hand.
19
+
20
+ ## Quick start with an agent
21
+
22
+ Install the bundled skill so your coding agent knows how to manage citations with `bibcite`:
23
+
24
+ ```bash
25
+ npx -y skills add leo1oel/bibcite --skill bibcite --global --yes
26
+ ```
27
+
28
+ Install the CLI once as well, or let the agent install it on the first bibliography task:
29
+
30
+ ```bash
31
+ uv tool install bibcite-cli
32
+ ```
33
+
34
+ You can then ask your agent to handle the bibliography in plain language:
35
+
36
+ ```text
37
+ Add arXiv:1706.03762 to references.bib and cite it in main.tex.
38
+ Upgrade the arXiv entries in references.bib to their published versions.
39
+ Check and fix references.bib before submission.
40
+ ```
41
+
42
+ The skill tells the agent to call `bibcite` for every `.bib` change, read the citation key from its JSON output, and use that exact key in `\cite{...}`.
43
+ The agent never needs to guess a key or edit a BibTeX entry by hand.
44
+
45
+ ## Use the CLI directly
46
+
47
+ Install the command from PyPI if you have not already done so:
48
+
49
+ ```bash
50
+ uv tool install bibcite-cli
51
+ ```
52
+
53
+ Resolve a paper and add it to your bibliography:
54
+
55
+ ```bash
56
+ bibcite add references.bib 1706.03762
57
+ ```
58
+
59
+ The command prints a machine-readable result, including the stable citation key:
60
+
61
+ ```json
62
+ {
63
+ "query": "1706.03762",
64
+ "action": "added",
65
+ "key": "vaswani2017attention",
66
+ "title": "Attention is All you Need",
67
+ "venue": "Advances in Neural Information Processing Systems (NIPS)",
68
+ "published": true,
69
+ "source": "semanticscholar",
70
+ "file": "references.bib",
71
+ "tidied": true
72
+ }
73
+ ```
74
+
75
+ You can now cite it as `\cite{vaswani2017attention}`.
76
+ Running the same command again is safe: `bibcite` detects the existing entry and does not add a duplicate.
77
+
78
+ When `add` writes a new entry, it runs [bibtex-tidy](https://github.com/FlamingTempura/bibtex-tidy) automatically unless you pass `--no-tidy`.
79
+ It uses a globally installed `bibtex-tidy` command when available and otherwise runs it through `npx --yes bibtex-tidy`.
80
+ `npx` downloads the formatter automatically on first use, so the agent-first setup does not require a separate `bibtex-tidy` installation.
81
+ The JSON result reports `"tidied": true` when formatting succeeds.
82
+
83
+ If neither `bibtex-tidy` nor `npx` is available, or if the formatter fails, the entry remains written but the command exits with code `1` and reports `"tidied": false`.
84
+ An `"action": "exists"` result also reports `"tidied": false` because no file change occurred, so `add` skips the formatting pass.
85
+ Run `bibcite tidy references.bib` or `bibcite fix references.bib` when you want to format an existing file.
86
+
87
+ You can also try a one-off command without installing `bibcite`:
88
+
89
+ ```bash
90
+ uvx --from bibcite-cli bibcite get "Attention is all you need"
91
+ ```
92
+
93
+ ## What it handles
94
+
95
+ - It accepts arXiv IDs and URLs, arXiv DOIs such as `10.48550/arXiv.1706.03762`, standard DOIs, and paper titles.
96
+ - It searches for a published version before falling back to an arXiv preprint, and it reports when source outages make that check incomplete.
97
+ - It canonicalizes journal, conference, and workshop names against the bundled venue table, including year-sensitive names such as NIPS and NeurIPS.
98
+ - It assigns the correct BibTeX entry type and field, such as `@inproceedings` with `booktitle` or `@article` with `journal`.
99
+ - It deduplicates by arXiv ID, DOI, exact title, and similar titles from the same first author.
100
+ - It upgrades preprints in place while preserving citation keys already used by your LaTeX source.
101
+
102
+ ## Commands
103
+
104
+ | Command | Purpose |
105
+ | --- | --- |
106
+ | `bibcite get <query>` | Preview resolved BibTeX without writing a file. |
107
+ | `bibcite add <file> <query>` | Resolve, deduplicate, add, and tidy an entry. |
108
+ | `bibcite add <file> --bibtex "..."` | Normalize and add a raw BibTeX entry. |
109
+ | `bibcite add <file> --from ids.txt` | Add one query per line and tidy once at the end. |
110
+ | `bibcite upgrade <file>` | Replace arXiv entries with published records when available. |
111
+ | `bibcite check <file>` | Find missing fields, duplicates, preprints, and all-caps author names without changing the file. |
112
+ | `bibcite tidy <file>` | Apply the canonical `bibtex-tidy` formatting rules. |
113
+ | `bibcite fix <file>` | Upgrade preprints, tidy the file, and run the checks in one command. |
114
+ | `bibcite remove <file> <key>` | Remove an entry by citation key. |
115
+
116
+ ### Common workflows
117
+
118
+ Preview a result as BibTeX or JSON:
119
+
120
+ ```bash
121
+ bibcite get 1706.03762
122
+ bibcite get 10.1109/CVPR52688.2022.01167 --json
123
+ ```
124
+
125
+ Add raw BibTeX from the clipboard:
126
+
127
+ ```bash
128
+ pbpaste | bibcite add references.bib --bibtex -
129
+ ```
130
+
131
+ Replace a bad entry while keeping its current key:
132
+
133
+ ```bash
134
+ bibcite add references.bib "correct paper title" --key existingKey
135
+ ```
136
+
137
+ Check what would be upgraded without writing the file:
138
+
139
+ ```bash
140
+ bibcite upgrade references.bib --dry-run
141
+ ```
142
+
143
+ Mark a confirmed preprint-only entry with `pubstate = {preprint}` if you want `check` and `upgrade` to leave it alone.
144
+
145
+ ## How resolution works
146
+
147
+ For arXiv IDs and titles, `bibcite` collects paper metadata and checks publication sources in a cascade derived from [PaperMemory](https://github.com/vict0rsch/PaperMemory): DBLP, Semantic Scholar, Google Scholar, Crossref, Unpaywall, and OpenAlex.
148
+ A published match must have the same normalized title or pass a guarded title-drift check, have a plausible publication year, and name a non-preprint venue.
149
+
150
+ Successful published matches are cached at `~/.cache/bibcite/published.json`.
151
+ Preprint-only results are never cached because a paper may be published later.
152
+ Use `--no-cache` or set `BIBCITE_NO_CACHE=1` to bypass the cache.
153
+
154
+ ## Configuration
155
+
156
+ Set `BIBCITE_STRINGS=/path/to/strings.bib` to use your own venue table, or place one at `~/.config/bibcite/strings.bib`.
157
+
158
+ These optional environment variables improve source reliability:
159
+
160
+ | Variable | Effect |
161
+ | --- | --- |
162
+ | `OPENALEX_API_KEY` | Uses your OpenAlex quota instead of the anonymous shared pool. |
163
+ | `S2_API_KEY` | Uses a private Semantic Scholar quota. |
164
+ | `BIBCITE_MAILTO` | Sends your contact email to the Crossref, OpenAlex, and Unpaywall polite pools. |
165
+ | `BIBCITE_CORE_SOURCES` | Overrides the sources required for a trustworthy publication check. |
166
+ | `BIBCITE_NO_CACHE=1` | Disables the local publication cache. |
167
+
168
+ ## Exit codes and agent use
169
+
170
+ `add`, `remove`, `upgrade`, `check`, and `fix` print JSON on standard output and send diagnostics to standard error.
171
+ This keeps their output easy to parse from scripts and agents.
172
+
173
+ | Code | Meaning |
174
+ | --- | --- |
175
+ | `0` | The command completed successfully. |
176
+ | `1` | A file, lint, or formatting problem remains. |
177
+ | `2` | The paper or requested entry could not be found. |
178
+ | `3` | Publication sources or an internal tool failed. |
179
+
180
+ Agents should call `bibcite add <file> <query>` and use the returned `key` in `\cite{...}`.
181
+ They should never modify `.bib` entries directly because doing so bypasses deduplication, venue normalization, and stable-key handling.
182
+
183
+ ## Development
184
+
185
+ ```bash
186
+ git clone https://github.com/leo1oel/bibcite.git
187
+ cd bibcite
188
+ uv sync --all-groups
189
+ uv run pytest
190
+ ```
191
+
192
+ Install the checkout as an editable command while developing:
193
+
194
+ ```bash
195
+ uv tool install --editable .
196
+ ```
197
+
198
+ ## License
199
+
200
+ `bibcite` is available under the [MIT License](LICENSE).
@@ -0,0 +1,21 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" role="img" aria-labelledby="title description">
2
+ <title id="title">bibcite logo</title>
3
+ <desc id="description">A paper with citation marks and a verification check.</desc>
4
+ <defs>
5
+ <linearGradient id="background" x1="32" y1="24" x2="224" y2="232" gradientUnits="userSpaceOnUse">
6
+ <stop stop-color="#6366F1"/>
7
+ <stop offset="1" stop-color="#7C3AED"/>
8
+ </linearGradient>
9
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="150%">
10
+ <feDropShadow dx="0" dy="8" stdDeviation="8" flood-color="#312E81" flood-opacity="0.28"/>
11
+ </filter>
12
+ </defs>
13
+ <rect width="256" height="256" rx="56" fill="url(#background)"/>
14
+ <path d="M67 48h89l37 37v116c0 9.4-7.6 17-17 17H67c-9.4 0-17-7.6-17-17V65c0-9.4 7.6-17 17-17Z" fill="#FFFFFF" filter="url(#shadow)"/>
15
+ <path d="M156 48v28c0 9.4 7.6 17 17 17h20" fill="#E0E7FF"/>
16
+ <path d="m156 48 37 37h-28c-5 0-9-4-9-9V48Z" fill="#C7D2FE"/>
17
+ <path d="M81 112c-8 4-12 11-12 22v18h22v-20H80c0-5 3-9 9-12l-8-8Zm40 0c-8 4-12 11-12 22v18h22v-20h-11c0-5 3-9 9-12l-8-8Z" fill="#6366F1"/>
18
+ <rect x="70" y="172" width="69" height="10" rx="5" fill="#CBD5E1"/>
19
+ <circle cx="181" cy="184" r="35" fill="#14B8A6" stroke="#FFFFFF" stroke-width="8"/>
20
+ <path d="m165 184 11 11 22-25" fill="none" stroke="#FFFFFF" stroke-width="9" stroke-linecap="round" stroke-linejoin="round"/>
21
+ </svg>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bibcite-cli"
3
- version = "0.5.4"
3
+ version = "0.6.0"
4
4
  description = "Resolve papers (arXiv id / DOI / title) to canonical, normalized BibTeX for agents and humans"
5
5
  readme = "Readme.md"
6
6
  license = "MIT"
@@ -20,6 +20,7 @@ bibcite = "bibcite.cli:main"
20
20
  [dependency-groups]
21
21
  dev = [
22
22
  "pytest>=8",
23
+ "ruff>=0.15,<0.16",
23
24
  ]
24
25
 
25
26
  [build-system]
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: bibcite
3
+ description: Manage paper citations and .bib files through the bibcite CLI instead of hand-editing them. Use whenever a task involves adding a paper reference or \cite, resolving an arXiv ID, arXiv DOI, DOI, or title to BibTeX, cleaning or checking a bibliography, deduplicating entries, or upgrading arXiv preprints to published records.
4
+ compatibility: Requires bibcite or uv, network access for paper resolution, and Node.js with npx for automatic formatting.
5
+ ---
6
+
7
+ # bibcite
8
+
9
+ Route every `.bib` change through `bibcite` because the CLI resolves metadata, canonicalizes venues, deduplicates entries, preserves existing citation keys, and formats the file.
10
+ Never add, replace, or delete a `.bib` entry by editing the file directly.
11
+
12
+ If `bibcite` is not on `PATH`, install it with `uv tool install bibcite-cli`, then use the commands below.
13
+
14
+ ## Choose the command
15
+
16
+ ```bash
17
+ bibcite add refs.bib <arXiv ID | arXiv URL | arXiv DOI | DOI | title>
18
+ bibcite add refs.bib --bibtex '<complete BibTeX entry>'
19
+ bibcite add refs.bib --from queries.txt
20
+ bibcite add refs.bib <query> --replace
21
+ bibcite add refs.bib <query> --key existingKey
22
+ bibcite remove refs.bib <key>
23
+ bibcite get <query> [--json]
24
+ bibcite upgrade refs.bib [--dry-run]
25
+ bibcite check refs.bib
26
+ bibcite tidy refs.bib
27
+ bibcite fix refs.bib
28
+ ```
29
+
30
+ Use `get` only to preview a paper without changing a bibliography.
31
+ Use `add` for one paper, and pass an arXiv ID, an arXiv DOI such as `10.48550/arXiv.1706.03762`, a standard DOI, or an exact title.
32
+ Use `--from` for multiple papers because one process shares source throttling state and tidies the file once.
33
+ Use `--replace` only when the resolved paper should overwrite an automatically matched entry.
34
+ Use `--key` when title drift prevents automatic matching and a specific existing citation key must be replaced.
35
+ Use `upgrade --dry-run` before upgrading a large bibliography.
36
+ Use `fix` when the user asks to clean up a bibliography end to end.
37
+
38
+ ## Use the returned citation key
39
+
40
+ File-changing commands print a JSON result on standard output and diagnostics on standard error.
41
+ Read the `key` from JSON after `add` and use that exact value in `\cite{...}` instead of guessing or reconstructing it.
42
+ After a write, confirm that `tidied` is `true` before reporting that formatting completed.
43
+ An `exists` result may have `tidied` set to `false` because the file was unchanged, so `add` skipped the formatting pass.
44
+ For any other `tidied: false` result, expect exit code `1` and retry once with `bibcite tidy <file>`.
45
+ `bibcite` downloads `bibtex-tidy` through `npx`, so do not install it separately.
46
+ If Node.js or `npx` is missing, ask before installing it and never format the file by hand.
47
+
48
+ Treat these `action` values as successful outcomes:
49
+
50
+ - `added` means a new entry was written.
51
+ - `exists` means the paper was already present and no duplicate was added.
52
+ - `upgraded` means a preprint was replaced by its published record while keeping the existing key.
53
+ - `replaced` means an explicitly targeted entry was overwritten while keeping its existing key.
54
+
55
+ For batch commands, inspect every item in `results` because one failed query does not invalidate successful entries.
56
+
57
+ ## Handle publication uncertainty
58
+
59
+ An unmatched upgrade reports either `no_published_version` or `sources_unavailable`.
60
+ Treat `no_published_version` as a trustworthy miss.
61
+ Treat `sources_unavailable` as temporary because rate limits or outages prevented a complete check, so retry later without writing a replacement by hand.
62
+
63
+ A preprint result may include `published_check`.
64
+ Treat `complete` as a trustworthy publication check and `incomplete` as a reason to retry later.
65
+
66
+ An entry that is intentionally preprint-only can use `pubstate = {preprint}` to mute future `check` and `upgrade` warnings.
67
+ Submit the complete updated entry through `--bibtex` and target its existing key rather than editing the file directly.
68
+
69
+ ## Handle exit codes
70
+
71
+ - Exit code `0` means the command completed successfully.
72
+ - Exit code `1` means a file, lint, or formatting problem remains.
73
+ Inspect `problems`, `remaining_problems`, and `tidied` before deciding what to do next.
74
+ - Exit code `2` means the paper or requested entry was not found.
75
+ Ask for a stronger identifier, preferably an arXiv ID or DOI, instead of fabricating an entry.
76
+ - Exit code `3` means publication sources or an internal tool failed.
77
+ Retry later and never fall back to hand-editing the bibliography.
78
+
79
+ `check` is read-only, but it returns exit code `1` when it finds problems.
80
+ `fix` also returns exit code `1` when unresolved lint issues remain or formatting fails.
@@ -1,3 +1,3 @@
1
1
  """bibcite: canonical BibTeX resolution for papers (arXiv id / DOI / title)."""
2
2
 
3
- __version__ = "0.5.4"
3
+ __version__ = "0.6.0"