zotero 0.1.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 (98) hide show
  1. zotero-0.1.0/.github/workflows/ci.yml +68 -0
  2. zotero-0.1.0/.github/workflows/release.yml +60 -0
  3. zotero-0.1.0/.gitignore +27 -0
  4. zotero-0.1.0/.python-version +1 -0
  5. zotero-0.1.0/CLAUDE.md +65 -0
  6. zotero-0.1.0/CODE_OF_CONDUCT.md +23 -0
  7. zotero-0.1.0/CONTRIBUTING.md +39 -0
  8. zotero-0.1.0/DEVELOPMENT.md +679 -0
  9. zotero-0.1.0/LICENSE +21 -0
  10. zotero-0.1.0/PKG-INFO +158 -0
  11. zotero-0.1.0/README.md +95 -0
  12. zotero-0.1.0/SECURITY.md +24 -0
  13. zotero-0.1.0/docs/superpowers/plans/2026-06-07-phase-1-infrastructure.md +2488 -0
  14. zotero-0.1.0/docs/superpowers/plans/2026-06-07-phase-2-config.md +1471 -0
  15. zotero-0.1.0/docs/superpowers/plans/2026-06-07-phase-3-zotero-api.md +1212 -0
  16. zotero-0.1.0/docs/superpowers/plans/2026-06-07-phase-4-attachments.md +3659 -0
  17. zotero-0.1.0/docs/superpowers/plans/2026-06-07-phase-5-rss.md +1073 -0
  18. zotero-0.1.0/docs/superpowers/plans/2026-06-07-phase-6-wrap-up.md +868 -0
  19. zotero-0.1.0/docs/superpowers/plans/2026-06-08-phase5-review-fixes.md +951 -0
  20. zotero-0.1.0/docs/superpowers/specs/2026-06-07-zotero-cli-design.md +1432 -0
  21. zotero-0.1.0/docs/superpowers/specs/spikes/phase4-open-issues.md +353 -0
  22. zotero-0.1.0/pyproject.toml +96 -0
  23. zotero-0.1.0/src/zotero_cli/__init__.py +1 -0
  24. zotero-0.1.0/src/zotero_cli/__main__.py +9 -0
  25. zotero-0.1.0/src/zotero_cli/adapters/__init__.py +0 -0
  26. zotero-0.1.0/src/zotero_cli/adapters/config_store.py +73 -0
  27. zotero-0.1.0/src/zotero_cli/adapters/sqlite_reader.py +181 -0
  28. zotero-0.1.0/src/zotero_cli/adapters/webdav_client.py +341 -0
  29. zotero-0.1.0/src/zotero_cli/adapters/zotero_api.py +423 -0
  30. zotero-0.1.0/src/zotero_cli/cli.py +43 -0
  31. zotero-0.1.0/src/zotero_cli/commands/__init__.py +0 -0
  32. zotero-0.1.0/src/zotero_cli/commands/_runner.py +145 -0
  33. zotero-0.1.0/src/zotero_cli/commands/collections.py +220 -0
  34. zotero-0.1.0/src/zotero_cli/commands/config.py +246 -0
  35. zotero-0.1.0/src/zotero_cli/commands/feeds.py +112 -0
  36. zotero-0.1.0/src/zotero_cli/commands/items.py +515 -0
  37. zotero-0.1.0/src/zotero_cli/commands/schema.py +157 -0
  38. zotero-0.1.0/src/zotero_cli/commands/tags.py +195 -0
  39. zotero-0.1.0/src/zotero_cli/constants.py +8 -0
  40. zotero-0.1.0/src/zotero_cli/models/__init__.py +0 -0
  41. zotero-0.1.0/src/zotero_cli/models/attachment.py +44 -0
  42. zotero-0.1.0/src/zotero_cli/models/config.py +125 -0
  43. zotero-0.1.0/src/zotero_cli/models/envelope.py +95 -0
  44. zotero-0.1.0/src/zotero_cli/models/errors.py +252 -0
  45. zotero-0.1.0/src/zotero_cli/models/feed.py +67 -0
  46. zotero-0.1.0/src/zotero_cli/models/results.py +114 -0
  47. zotero-0.1.0/src/zotero_cli/services/__init__.py +0 -0
  48. zotero-0.1.0/src/zotero_cli/services/attachment_service.py +295 -0
  49. zotero-0.1.0/src/zotero_cli/services/collection_service.py +105 -0
  50. zotero-0.1.0/src/zotero_cli/services/config_service.py +142 -0
  51. zotero-0.1.0/src/zotero_cli/services/export_service.py +33 -0
  52. zotero-0.1.0/src/zotero_cli/services/feed_service.py +69 -0
  53. zotero-0.1.0/src/zotero_cli/services/item_service.py +167 -0
  54. zotero-0.1.0/src/zotero_cli/services/tag_service.py +109 -0
  55. zotero-0.1.0/src/zotero_cli/utils/__init__.py +0 -0
  56. zotero-0.1.0/src/zotero_cli/utils/audit_log.py +120 -0
  57. zotero-0.1.0/src/zotero_cli/utils/date_parser.py +114 -0
  58. zotero-0.1.0/src/zotero_cli/utils/exit_codes.py +18 -0
  59. zotero-0.1.0/src/zotero_cli/utils/output.py +328 -0
  60. zotero-0.1.0/tests/__init__.py +0 -0
  61. zotero-0.1.0/tests/conftest.py +11 -0
  62. zotero-0.1.0/tests/fixtures/__init__.py +0 -0
  63. zotero-0.1.0/tests/fixtures/build_sqlite.py +183 -0
  64. zotero-0.1.0/tests/fixtures/sample_pdf.pdf +14 -0
  65. zotero-0.1.0/tests/fixtures/zotero_test.sqlite +0 -0
  66. zotero-0.1.0/tests/integration/__init__.py +0 -0
  67. zotero-0.1.0/tests/integration/test_collections_commands.py +149 -0
  68. zotero-0.1.0/tests/integration/test_feed_perf.py +41 -0
  69. zotero-0.1.0/tests/integration/test_feed_queries.py +88 -0
  70. zotero-0.1.0/tests/integration/test_items_commands.py +416 -0
  71. zotero-0.1.0/tests/integration/test_tags_commands.py +146 -0
  72. zotero-0.1.0/tests/unit/__init__.py +0 -0
  73. zotero-0.1.0/tests/unit/test_affected_keys.py +82 -0
  74. zotero-0.1.0/tests/unit/test_attachment_service.py +344 -0
  75. zotero-0.1.0/tests/unit/test_audit_log.py +217 -0
  76. zotero-0.1.0/tests/unit/test_collection_service.py +61 -0
  77. zotero-0.1.0/tests/unit/test_command_mutex.py +51 -0
  78. zotero-0.1.0/tests/unit/test_command_runner.py +99 -0
  79. zotero-0.1.0/tests/unit/test_config_commands.py +331 -0
  80. zotero-0.1.0/tests/unit/test_config_models.py +183 -0
  81. zotero-0.1.0/tests/unit/test_config_service.py +130 -0
  82. zotero-0.1.0/tests/unit/test_config_store.py +78 -0
  83. zotero-0.1.0/tests/unit/test_date_parser.py +170 -0
  84. zotero-0.1.0/tests/unit/test_dry_run.py +173 -0
  85. zotero-0.1.0/tests/unit/test_envelope.py +151 -0
  86. zotero-0.1.0/tests/unit/test_errors.py +185 -0
  87. zotero-0.1.0/tests/unit/test_exit_codes.py +29 -0
  88. zotero-0.1.0/tests/unit/test_export_service.py +30 -0
  89. zotero-0.1.0/tests/unit/test_feed_commands.py +201 -0
  90. zotero-0.1.0/tests/unit/test_item_service.py +168 -0
  91. zotero-0.1.0/tests/unit/test_output.py +473 -0
  92. zotero-0.1.0/tests/unit/test_results_models.py +67 -0
  93. zotero-0.1.0/tests/unit/test_schema_command.py +107 -0
  94. zotero-0.1.0/tests/unit/test_sqlite_reader.py +56 -0
  95. zotero-0.1.0/tests/unit/test_tag_service.py +87 -0
  96. zotero-0.1.0/tests/unit/test_webdav_client.py +448 -0
  97. zotero-0.1.0/tests/unit/test_zotero_api.py +692 -0
  98. zotero-0.1.0/uv.lock +1310 -0
@@ -0,0 +1,68 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ quality:
14
+ name: Quality checks (${{ matrix.python-version }})
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version: ["3.11", "3.12", "3.13"]
20
+
21
+ steps:
22
+ - name: Check out repository
23
+ uses: actions/checkout@v4
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@v5
27
+ with:
28
+ enable-cache: true
29
+ cache-dependency-glob: uv.lock
30
+
31
+ - name: Set up Python
32
+ uses: actions/setup-python@v5
33
+ with:
34
+ python-version: ${{ matrix.python-version }}
35
+
36
+ - name: Install dependencies
37
+ run: uv sync --extra dev --locked
38
+
39
+ - name: Lint
40
+ run: uv run ruff check src tests
41
+
42
+ - name: Type check
43
+ run: uv run mypy src
44
+
45
+ - name: Test
46
+ run: uv run pytest --cov=src/zotero_cli --cov-report=term-missing
47
+
48
+ build:
49
+ name: Build package
50
+ runs-on: ubuntu-latest
51
+
52
+ steps:
53
+ - name: Check out repository
54
+ uses: actions/checkout@v4
55
+
56
+ - name: Install uv
57
+ uses: astral-sh/setup-uv@v5
58
+ with:
59
+ enable-cache: true
60
+ cache-dependency-glob: uv.lock
61
+
62
+ - name: Set up Python
63
+ uses: actions/setup-python@v5
64
+ with:
65
+ python-version: "3.11"
66
+
67
+ - name: Build distributions
68
+ run: uv build
@@ -0,0 +1,60 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: ["published"]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ name: Build distributions
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Check out repository
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v5
22
+ with:
23
+ enable-cache: true
24
+ cache-dependency-glob: uv.lock
25
+
26
+ - name: Set up Python
27
+ uses: actions/setup-python@v5
28
+ with:
29
+ python-version: "3.11"
30
+
31
+ - name: Build distributions
32
+ run: uv build
33
+
34
+ - name: Upload distributions
35
+ uses: actions/upload-artifact@v4
36
+ with:
37
+ name: python-distributions
38
+ path: dist/
39
+ if-no-files-found: error
40
+
41
+ publish:
42
+ name: Publish to PyPI
43
+ needs: build
44
+ runs-on: ubuntu-latest
45
+ environment:
46
+ name: pypi
47
+ url: https://pypi.org/p/zotero
48
+ permissions:
49
+ contents: read
50
+ id-token: write
51
+
52
+ steps:
53
+ - name: Download distributions
54
+ uses: actions/download-artifact@v4
55
+ with:
56
+ name: python-distributions
57
+ path: dist/
58
+
59
+ - name: Publish distributions
60
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,27 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ dist/
7
+ build/
8
+
9
+ # Caches
10
+ .ruff_cache/
11
+ .mypy_cache/
12
+ .pytest_cache/
13
+ .coverage
14
+ htmlcov/
15
+
16
+ # Project artifacts (DEVELOPMENT.md §10.5)
17
+ *.pdf
18
+ !tests/fixtures/sample_pdf.pdf
19
+ *.sqlite
20
+ !tests/fixtures/zotero_test.sqlite
21
+ *.sqlite-journal
22
+ audit.log*
23
+
24
+ # IDE
25
+ .idea/
26
+ .vscode/
27
+ *.swp
@@ -0,0 +1 @@
1
+ 3.11
zotero-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1,65 @@
1
+ # CLAUDE.md
2
+
3
+ Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
4
+
5
+ **Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
6
+
7
+ ## 1. Think Before Coding
8
+
9
+ **Don't assume. Don't hide confusion. Surface tradeoffs.**
10
+
11
+ Before implementing:
12
+ - State your assumptions explicitly. If uncertain, ask.
13
+ - If multiple interpretations exist, present them - don't pick silently.
14
+ - If a simpler approach exists, say so. Push back when warranted.
15
+ - If something is unclear, stop. Name what's confusing. Ask.
16
+
17
+ ## 2. Simplicity First
18
+
19
+ **Minimum code that solves the problem. Nothing speculative.**
20
+
21
+ - No features beyond what was asked.
22
+ - No abstractions for single-use code.
23
+ - No "flexibility" or "configurability" that wasn't requested.
24
+ - No error handling for impossible scenarios.
25
+ - If you write 200 lines and it could be 50, rewrite it.
26
+
27
+ Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
28
+
29
+ ## 3. Surgical Changes
30
+
31
+ **Touch only what you must. Clean up only your own mess.**
32
+
33
+ When editing existing code:
34
+ - Don't "improve" adjacent code, comments, or formatting.
35
+ - Don't refactor things that aren't broken.
36
+ - Match existing style, even if you'd do it differently.
37
+ - If you notice unrelated dead code, mention it - don't delete it.
38
+
39
+ When your changes create orphans:
40
+ - Remove imports/variables/functions that YOUR changes made unused.
41
+ - Don't remove pre-existing dead code unless asked.
42
+
43
+ The test: Every changed line should trace directly to the user's request.
44
+
45
+ ## 4. Goal-Driven Execution
46
+
47
+ **Define success criteria. Loop until verified.**
48
+
49
+ Transform tasks into verifiable goals:
50
+ - "Add validation" → "Write tests for invalid inputs, then make them pass"
51
+ - "Fix the bug" → "Write a test that reproduces it, then make it pass"
52
+ - "Refactor X" → "Ensure tests pass before and after"
53
+
54
+ For multi-step tasks, state a brief plan:
55
+ ```
56
+ 1. [Step] → verify: [check]
57
+ 2. [Step] → verify: [check]
58
+ 3. [Step] → verify: [check]
59
+ ```
60
+
61
+ Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
62
+
63
+ ---
64
+
65
+ **These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
@@ -0,0 +1,23 @@
1
+ # Code of Conduct
2
+
3
+ This project expects respectful, constructive collaboration.
4
+
5
+ ## Expected Behavior
6
+
7
+ - Be direct and professional.
8
+ - Assume good intent, but be clear when something is wrong or risky.
9
+ - Keep discussion focused on the project and the technical issue being solved.
10
+ - Respect privacy. Do not post credentials, private Zotero data, or private documents.
11
+
12
+ ## Unacceptable Behavior
13
+
14
+ - Harassment, personal attacks, discriminatory language, or repeated hostile comments.
15
+ - Publishing private information without permission.
16
+ - Ignoring maintainer requests to stop disruptive behavior.
17
+
18
+ ## Enforcement
19
+
20
+ Maintainers may edit or remove comments, close issues, reject contributions, or block participants
21
+ who violate this code of conduct. To report a concern, use the repository's private reporting
22
+ channels when available, or open an issue asking for a private contact path without posting
23
+ sensitive details.
@@ -0,0 +1,39 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in zotero-cli. Keep changes focused, tested, and easy to review.
4
+
5
+ ## Development Setup
6
+
7
+ Use `uv` for all dependency and command execution:
8
+
9
+ ```bash
10
+ uv sync --extra dev
11
+ uv run ruff check src tests
12
+ uv run mypy src
13
+ uv run pytest --cov=src
14
+ uv build
15
+ ```
16
+
17
+ Do not use `pip`, Poetry, or Pipenv in this repository. They can drift from `uv.lock`.
18
+
19
+ ## Pull Requests
20
+
21
+ - Keep each PR scoped to one behavior, fix, or infrastructure change.
22
+ - Add or update tests for behavior changes.
23
+ - Update README or development docs when user-facing commands, setup, or release behavior changes.
24
+ - Run the full local check set before opening a PR.
25
+ - Do not commit real Zotero API keys, WebDAV credentials, personal Zotero databases, or real paper PDFs.
26
+
27
+ ## Test Fixtures
28
+
29
+ Fixtures under `tests/fixtures/` must be synthetic. `zotero_test.sqlite` is generated by
30
+ `tests/fixtures/build_sqlite.py`; regenerate it with:
31
+
32
+ ```bash
33
+ uv run python tests/fixtures/build_sqlite.py
34
+ ```
35
+
36
+ ## Releases
37
+
38
+ Maintainers publish releases from GitHub Releases. The release workflow builds distributions and
39
+ publishes to PyPI using trusted publishing, so no PyPI token should be committed to the repository.