corvee 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.
- corvee-0.1.0/.claude/CLAUDE.md +1 -0
- corvee-0.1.0/.github/dependabot.yml +10 -0
- corvee-0.1.0/.github/workflows/cicd.yaml +190 -0
- corvee-0.1.0/.github/workflows/dependabot_auto_merge.yaml +32 -0
- corvee-0.1.0/.gitignore +43 -0
- corvee-0.1.0/.pre-commit-config.yaml +61 -0
- corvee-0.1.0/AGENTS.md +146 -0
- corvee-0.1.0/CONTRIBUTING.md +33 -0
- corvee-0.1.0/LICENSE +201 -0
- corvee-0.1.0/PKG-INFO +107 -0
- corvee-0.1.0/README.md +93 -0
- corvee-0.1.0/docs/commands.md +44 -0
- corvee-0.1.0/docs/concurrency.md +57 -0
- corvee-0.1.0/docs/index.md +76 -0
- corvee-0.1.0/docs/mcp.md +297 -0
- corvee-0.1.0/docs/quickstart.md +195 -0
- corvee-0.1.0/docs/spec.md +2506 -0
- corvee-0.1.0/mkdocs.yml +44 -0
- corvee-0.1.0/pyproject.toml +163 -0
- corvee-0.1.0/src/corvee/__init__.py +11 -0
- corvee-0.1.0/src/corvee/__main__.py +10 -0
- corvee-0.1.0/src/corvee/actor.py +40 -0
- corvee-0.1.0/src/corvee/cli/__init__.py +9 -0
- corvee-0.1.0/src/corvee/cli/commands/__init__.py +5 -0
- corvee-0.1.0/src/corvee/cli/commands/brief.py +186 -0
- corvee-0.1.0/src/corvee/cli/commands/completion.py +47 -0
- corvee-0.1.0/src/corvee/cli/commands/doctor.py +141 -0
- corvee-0.1.0/src/corvee/cli/commands/explain.py +122 -0
- corvee-0.1.0/src/corvee/cli/commands/export.py +42 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/__init__.py +45 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/add.py +59 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/delete.py +35 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/list_.py +101 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/retract.py +39 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/revise.py +39 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/search.py +77 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/show.py +72 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/unverify.py +39 -0
- corvee-0.1.0/src/corvee/cli/commands/fact/verify.py +41 -0
- corvee-0.1.0/src/corvee/cli/commands/import_.py +47 -0
- corvee-0.1.0/src/corvee/cli/commands/init.py +82 -0
- corvee-0.1.0/src/corvee/cli/commands/mcp/__init__.py +22 -0
- corvee-0.1.0/src/corvee/cli/commands/mcp/serve.py +108 -0
- corvee-0.1.0/src/corvee/cli/commands/task/__init__.py +57 -0
- corvee-0.1.0/src/corvee/cli/commands/task/add.py +226 -0
- corvee-0.1.0/src/corvee/cli/commands/task/assign.py +48 -0
- corvee-0.1.0/src/corvee/cli/commands/task/claim.py +45 -0
- corvee-0.1.0/src/corvee/cli/commands/task/claims.py +39 -0
- corvee-0.1.0/src/corvee/cli/commands/task/comment.py +37 -0
- corvee-0.1.0/src/corvee/cli/commands/task/label.py +59 -0
- corvee-0.1.0/src/corvee/cli/commands/task/labels.py +32 -0
- corvee-0.1.0/src/corvee/cli/commands/task/link.py +53 -0
- corvee-0.1.0/src/corvee/cli/commands/task/list_.py +181 -0
- corvee-0.1.0/src/corvee/cli/commands/task/mine.py +63 -0
- corvee-0.1.0/src/corvee/cli/commands/task/purge.py +39 -0
- corvee-0.1.0/src/corvee/cli/commands/task/ready.py +68 -0
- corvee-0.1.0/src/corvee/cli/commands/task/search.py +81 -0
- corvee-0.1.0/src/corvee/cli/commands/task/show.py +95 -0
- corvee-0.1.0/src/corvee/cli/commands/task/start.py +49 -0
- corvee-0.1.0/src/corvee/cli/commands/task/tree.py +88 -0
- corvee-0.1.0/src/corvee/cli/commands/task/unassign.py +38 -0
- corvee-0.1.0/src/corvee/cli/commands/task/unclaim.py +43 -0
- corvee-0.1.0/src/corvee/cli/commands/task/unlink.py +47 -0
- corvee-0.1.0/src/corvee/cli/commands/task/update.py +77 -0
- corvee-0.1.0/src/corvee/cli/completion.py +78 -0
- corvee-0.1.0/src/corvee/cli/context.py +105 -0
- corvee-0.1.0/src/corvee/cli/main.py +114 -0
- corvee-0.1.0/src/corvee/cli/params.py +52 -0
- corvee-0.1.0/src/corvee/cli/scope.py +155 -0
- corvee-0.1.0/src/corvee/config.py +206 -0
- corvee-0.1.0/src/corvee/constants.py +115 -0
- corvee-0.1.0/src/corvee/db/__init__.py +5 -0
- corvee-0.1.0/src/corvee/db/connection.py +103 -0
- corvee-0.1.0/src/corvee/db/events.py +143 -0
- corvee-0.1.0/src/corvee/db/export_import.py +89 -0
- corvee-0.1.0/src/corvee/db/facts.py +310 -0
- corvee-0.1.0/src/corvee/db/labels.py +93 -0
- corvee-0.1.0/src/corvee/db/like.py +12 -0
- corvee-0.1.0/src/corvee/db/links.py +182 -0
- corvee-0.1.0/src/corvee/db/schema.py +132 -0
- corvee-0.1.0/src/corvee/db/stats.py +192 -0
- corvee-0.1.0/src/corvee/db/tasks.py +762 -0
- corvee-0.1.0/src/corvee/errors.py +58 -0
- corvee-0.1.0/src/corvee/guards/__init__.py +5 -0
- corvee-0.1.0/src/corvee/guards/ancestry.py +38 -0
- corvee-0.1.0/src/corvee/guards/fields.py +31 -0
- corvee-0.1.0/src/corvee/guards/labels.py +23 -0
- corvee-0.1.0/src/corvee/guards/parent_child.py +31 -0
- corvee-0.1.0/src/corvee/guards/scope.py +26 -0
- corvee-0.1.0/src/corvee/guards/transitions.py +27 -0
- corvee-0.1.0/src/corvee/mcp/__init__.py +5 -0
- corvee-0.1.0/src/corvee/mcp/dispatch.py +117 -0
- corvee-0.1.0/src/corvee/mcp/scope.py +81 -0
- corvee-0.1.0/src/corvee/mcp/server.py +160 -0
- corvee-0.1.0/src/corvee/mcp/tools_common.py +112 -0
- corvee-0.1.0/src/corvee/mcp/tools_fact.py +136 -0
- corvee-0.1.0/src/corvee/mcp/tools_read.py +228 -0
- corvee-0.1.0/src/corvee/mcp/tools_write.py +323 -0
- corvee-0.1.0/src/corvee/mcp/worker.py +50 -0
- corvee-0.1.0/src/corvee/models.py +224 -0
- corvee-0.1.0/src/corvee/output.py +227 -0
- corvee-0.1.0/src/corvee/references.py +81 -0
- corvee-0.1.0/src/corvee/timeutil.py +44 -0
- corvee-0.1.0/tests/acceptance/conftest.py +38 -0
- corvee-0.1.0/tests/acceptance/mcp_helpers.py +39 -0
- corvee-0.1.0/tests/acceptance/test_cli_actor_session_flags.py +91 -0
- corvee-0.1.0/tests/acceptance/test_cli_add_list_show.py +353 -0
- corvee-0.1.0/tests/acceptance/test_cli_brief.py +145 -0
- corvee-0.1.0/tests/acceptance/test_cli_claim_update.py +135 -0
- corvee-0.1.0/tests/acceptance/test_cli_claims.py +43 -0
- corvee-0.1.0/tests/acceptance/test_cli_completion.py +98 -0
- corvee-0.1.0/tests/acceptance/test_cli_completion_command.py +30 -0
- corvee-0.1.0/tests/acceptance/test_cli_context_overrides.py +103 -0
- corvee-0.1.0/tests/acceptance/test_cli_doctor.py +222 -0
- corvee-0.1.0/tests/acceptance/test_cli_duration_validation.py +49 -0
- corvee-0.1.0/tests/acceptance/test_cli_error_handling.py +104 -0
- corvee-0.1.0/tests/acceptance/test_cli_explain_and_epilogs.py +181 -0
- corvee-0.1.0/tests/acceptance/test_cli_export_import.py +132 -0
- corvee-0.1.0/tests/acceptance/test_cli_facts.py +389 -0
- corvee-0.1.0/tests/acceptance/test_cli_global_scope.py +289 -0
- corvee-0.1.0/tests/acceptance/test_cli_init.py +114 -0
- corvee-0.1.0/tests/acceptance/test_cli_labels.py +114 -0
- corvee-0.1.0/tests/acceptance/test_cli_limit_validation.py +67 -0
- corvee-0.1.0/tests/acceptance/test_cli_link.py +99 -0
- corvee-0.1.0/tests/acceptance/test_cli_mcp_serve.py +279 -0
- corvee-0.1.0/tests/acceptance/test_cli_no_project.py +85 -0
- corvee-0.1.0/tests/acceptance/test_cli_pagination.py +112 -0
- corvee-0.1.0/tests/acceptance/test_cli_params.py +39 -0
- corvee-0.1.0/tests/acceptance/test_cli_ready_search_mine_comment.py +170 -0
- corvee-0.1.0/tests/acceptance/test_cli_referenced.py +146 -0
- corvee-0.1.0/tests/acceptance/test_cli_scope.py +233 -0
- corvee-0.1.0/tests/acceptance/test_cli_task_add_from_file.py +178 -0
- corvee-0.1.0/tests/acceptance/test_cli_task_assign.py +123 -0
- corvee-0.1.0/tests/acceptance/test_cli_task_purge.py +81 -0
- corvee-0.1.0/tests/acceptance/test_cli_task_start.py +98 -0
- corvee-0.1.0/tests/acceptance/test_cli_tree.py +104 -0
- corvee-0.1.0/tests/acceptance/test_config.py +174 -0
- corvee-0.1.0/tests/acceptance/test_db_claims_and_update.py +361 -0
- corvee-0.1.0/tests/acceptance/test_db_connection.py +195 -0
- corvee-0.1.0/tests/acceptance/test_db_export_import.py +129 -0
- corvee-0.1.0/tests/acceptance/test_db_facts.py +347 -0
- corvee-0.1.0/tests/acceptance/test_db_labels.py +53 -0
- corvee-0.1.0/tests/acceptance/test_db_links.py +147 -0
- corvee-0.1.0/tests/acceptance/test_db_ready_search_mine_comment.py +290 -0
- corvee-0.1.0/tests/acceptance/test_db_stats.py +295 -0
- corvee-0.1.0/tests/acceptance/test_db_tasks.py +364 -0
- corvee-0.1.0/tests/acceptance/test_mcp_concurrency.py +73 -0
- corvee-0.1.0/tests/acceptance/test_mcp_create_and_find_tools.py +187 -0
- corvee-0.1.0/tests/acceptance/test_mcp_docs_tool_inventory.py +76 -0
- corvee-0.1.0/tests/acceptance/test_mcp_fact_tools.py +93 -0
- corvee-0.1.0/tests/acceptance/test_mcp_read_tools.py +237 -0
- corvee-0.1.0/tests/acceptance/test_mcp_scope.py +100 -0
- corvee-0.1.0/tests/acceptance/test_mcp_server_config.py +63 -0
- corvee-0.1.0/tests/acceptance/test_mcp_server_startup.py +94 -0
- corvee-0.1.0/tests/acceptance/test_mcp_stdout_purity.py +34 -0
- corvee-0.1.0/tests/acceptance/test_mcp_tool_descriptions.py +87 -0
- corvee-0.1.0/tests/acceptance/test_mcp_version_skew.py +60 -0
- corvee-0.1.0/tests/acceptance/test_mcp_write_tools.py +243 -0
- corvee-0.1.0/tests/conftest.py +94 -0
- corvee-0.1.0/tests/e2e/test_concurrency.py +104 -0
- corvee-0.1.0/tests/e2e/test_e2e.py +144 -0
- corvee-0.1.0/tests/e2e/test_mcp_protocol.py +65 -0
- corvee-0.1.0/tests/e2e/test_mcp_serve.py +51 -0
- corvee-0.1.0/tests/unit/test_actor.py +54 -0
- corvee-0.1.0/tests/unit/test_cicd_workflow.py +68 -0
- corvee-0.1.0/tests/unit/test_constants.py +125 -0
- corvee-0.1.0/tests/unit/test_guards.py +190 -0
- corvee-0.1.0/tests/unit/test_mcp_dispatch.py +145 -0
- corvee-0.1.0/tests/unit/test_mcp_dispatch_version_skew.py +117 -0
- corvee-0.1.0/tests/unit/test_mcp_session_id_resolution.py +37 -0
- corvee-0.1.0/tests/unit/test_mcp_worker.py +108 -0
- corvee-0.1.0/tests/unit/test_models.py +255 -0
- corvee-0.1.0/tests/unit/test_output.py +265 -0
- corvee-0.1.0/tests/unit/test_timeutil.py +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@../AGENTS.md
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
name: CI/CD
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
release:
|
|
7
|
+
types: [created]
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
pre-commit:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0 # hatch-vcs needs full history (and any tags) to derive a version
|
|
20
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.11"
|
|
23
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
24
|
+
- name: Install project (generates src/corvee/_version.py via the hatch-vcs build hook)
|
|
25
|
+
run: uv pip install --system -e .
|
|
26
|
+
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
|
|
27
|
+
|
|
28
|
+
test:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
strategy:
|
|
31
|
+
fail-fast: false
|
|
32
|
+
matrix:
|
|
33
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
36
|
+
with:
|
|
37
|
+
fetch-depth: 0
|
|
38
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
39
|
+
with:
|
|
40
|
+
python-version: ${{ matrix.python-version }}
|
|
41
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
42
|
+
- name: Install project and test dependencies
|
|
43
|
+
run: uv pip install --system -e '.[mcp]' pytest pytest-xdist
|
|
44
|
+
- name: Run tests
|
|
45
|
+
run: pytest -n auto
|
|
46
|
+
|
|
47
|
+
build:
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
needs: [pre-commit, test]
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
52
|
+
with:
|
|
53
|
+
fetch-depth: 0
|
|
54
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
55
|
+
with:
|
|
56
|
+
python-version: "3.11"
|
|
57
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
58
|
+
- name: Install hatch
|
|
59
|
+
run: uv tool install hatch
|
|
60
|
+
- name: Build
|
|
61
|
+
run: hatch build
|
|
62
|
+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
63
|
+
with:
|
|
64
|
+
name: dist
|
|
65
|
+
path: dist/
|
|
66
|
+
|
|
67
|
+
docs:
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
needs: [pre-commit, test]
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
72
|
+
with:
|
|
73
|
+
fetch-depth: 0
|
|
74
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
75
|
+
with:
|
|
76
|
+
python-version: "3.11"
|
|
77
|
+
- uses: astral-sh/setup-uv@bec219d24cd3e171d82865faccec33120bb574f4 # v10.1.0
|
|
78
|
+
- name: Install hatch
|
|
79
|
+
run: uv tool install hatch
|
|
80
|
+
- name: Build documentation
|
|
81
|
+
run: hatch run docs-build
|
|
82
|
+
- if: github.ref == 'refs/heads/master'
|
|
83
|
+
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
|
|
84
|
+
with:
|
|
85
|
+
path: site
|
|
86
|
+
|
|
87
|
+
deploy-docs:
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
needs: [docs]
|
|
90
|
+
if: github.ref == 'refs/heads/master'
|
|
91
|
+
permissions:
|
|
92
|
+
contents: read
|
|
93
|
+
pages: write
|
|
94
|
+
id-token: write
|
|
95
|
+
environment:
|
|
96
|
+
name: github-pages
|
|
97
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
|
|
100
|
+
- id: deployment
|
|
101
|
+
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
|
|
102
|
+
|
|
103
|
+
# Uploads the package to test.pypi.org on every push to master.
|
|
104
|
+
upload-test-pypi:
|
|
105
|
+
if: |
|
|
106
|
+
success()
|
|
107
|
+
&& github.ref == 'refs/heads/master'
|
|
108
|
+
&& github.actor == 'btschwertfeger'
|
|
109
|
+
&& github.event_name == 'push'
|
|
110
|
+
needs: [build]
|
|
111
|
+
name: Upload development version to Test PyPI
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
permissions:
|
|
114
|
+
contents: read
|
|
115
|
+
id-token: write # mandatory for OIDC Trusted Publishing
|
|
116
|
+
environment:
|
|
117
|
+
name: testpypi
|
|
118
|
+
url: https://test.pypi.org/p/corvee
|
|
119
|
+
steps:
|
|
120
|
+
- name: Harden Runner
|
|
121
|
+
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
|
122
|
+
with:
|
|
123
|
+
disable-sudo: true
|
|
124
|
+
egress-policy: block
|
|
125
|
+
allowed-endpoints: >
|
|
126
|
+
api.github.com:443
|
|
127
|
+
github.com:443
|
|
128
|
+
test.pypi.org
|
|
129
|
+
uploads.github.com:443
|
|
130
|
+
|
|
131
|
+
- name: Download the distributions
|
|
132
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
133
|
+
with:
|
|
134
|
+
name: dist
|
|
135
|
+
path: dist/
|
|
136
|
+
|
|
137
|
+
- name: Publish package distributions to Test PyPI
|
|
138
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
139
|
+
with:
|
|
140
|
+
repository-url: https://test.pypi.org/legacy/
|
|
141
|
+
|
|
142
|
+
# Uploads the package to PyPI when a release is created.
|
|
143
|
+
upload-pypi:
|
|
144
|
+
if: |
|
|
145
|
+
success()
|
|
146
|
+
&& github.actor == 'btschwertfeger'
|
|
147
|
+
&& github.event_name == 'release'
|
|
148
|
+
needs: [build]
|
|
149
|
+
name: Upload release to PyPI
|
|
150
|
+
runs-on: ubuntu-latest
|
|
151
|
+
permissions:
|
|
152
|
+
contents: read
|
|
153
|
+
id-token: write # mandatory for OIDC Trusted Publishing
|
|
154
|
+
attestations: write # write build-provenance attestations
|
|
155
|
+
environment:
|
|
156
|
+
name: pypi
|
|
157
|
+
url: https://pypi.org/p/corvee
|
|
158
|
+
steps:
|
|
159
|
+
- name: Harden Runner
|
|
160
|
+
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
|
161
|
+
with:
|
|
162
|
+
disable-sudo: true
|
|
163
|
+
egress-policy: block
|
|
164
|
+
allowed-endpoints: >
|
|
165
|
+
api.github.com:443
|
|
166
|
+
fulcio.sigstore.dev
|
|
167
|
+
github.com:443
|
|
168
|
+
pypi.org
|
|
169
|
+
rekor.sigstore.dev
|
|
170
|
+
timestamp.sigstore.dev
|
|
171
|
+
tuf-repo-cdn.sigstore.dev
|
|
172
|
+
upload.pypi.org
|
|
173
|
+
|
|
174
|
+
- name: Download the distributions
|
|
175
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
176
|
+
with:
|
|
177
|
+
name: dist
|
|
178
|
+
path: dist/
|
|
179
|
+
|
|
180
|
+
# SLSA build provenance for the wheel and sdist, written to GitHub's
|
|
181
|
+
# attestation store and verifiable with `gh attestation verify`.
|
|
182
|
+
- name: Attest build provenance
|
|
183
|
+
uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
|
|
184
|
+
with:
|
|
185
|
+
subject-path: "dist/*"
|
|
186
|
+
|
|
187
|
+
- name: Publish package distributions to PyPI
|
|
188
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
189
|
+
with:
|
|
190
|
+
repository-url: https://upload.pypi.org/legacy/
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Dependabot auto-merge
|
|
2
|
+
|
|
3
|
+
on: pull_request_target
|
|
4
|
+
|
|
5
|
+
permissions:
|
|
6
|
+
pull-requests: write
|
|
7
|
+
contents: write
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
dependabot:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
if: ${{ github.actor == 'dependabot[bot]' }}
|
|
13
|
+
steps:
|
|
14
|
+
- name: Dependabot metadata
|
|
15
|
+
id: dependabot-metadata
|
|
16
|
+
uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.0
|
|
17
|
+
with:
|
|
18
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
19
|
+
|
|
20
|
+
- name: Approve the PR
|
|
21
|
+
if: ${{ steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major' }}
|
|
22
|
+
run: gh pr review --approve "$PR_URL"
|
|
23
|
+
env:
|
|
24
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
25
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
+
|
|
27
|
+
- name: Enable auto-merge for patch/minor updates
|
|
28
|
+
if: ${{ steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major' }}
|
|
29
|
+
run: gh pr merge --auto --squash "$PR_URL"
|
|
30
|
+
env:
|
|
31
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
32
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
corvee-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Byte-compiled / optimized files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
.Python
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
*.egg
|
|
12
|
+
wheels/
|
|
13
|
+
*.whl
|
|
14
|
+
|
|
15
|
+
# Environments
|
|
16
|
+
.venv/
|
|
17
|
+
venv/
|
|
18
|
+
env/
|
|
19
|
+
.hatch/
|
|
20
|
+
|
|
21
|
+
# Testing / coverage / typing / linting caches
|
|
22
|
+
.cache/
|
|
23
|
+
.coverage
|
|
24
|
+
.coverage.*
|
|
25
|
+
coverage.xml
|
|
26
|
+
htmlcov/
|
|
27
|
+
.ruff_cache/
|
|
28
|
+
.pytest_cache/
|
|
29
|
+
.tox/
|
|
30
|
+
.nox/
|
|
31
|
+
mutants/
|
|
32
|
+
|
|
33
|
+
# Docs
|
|
34
|
+
site/
|
|
35
|
+
|
|
36
|
+
# Editors / OS
|
|
37
|
+
.vscode/
|
|
38
|
+
.idea/
|
|
39
|
+
*.swp
|
|
40
|
+
.DS_Store
|
|
41
|
+
|
|
42
|
+
# corvee project data (never committed)
|
|
43
|
+
.corvee/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.16.1
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff-check
|
|
6
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
7
|
+
- repo: https://github.com/psf/black
|
|
8
|
+
rev: 26.3.1
|
|
9
|
+
hooks:
|
|
10
|
+
- id: black
|
|
11
|
+
- repo: local
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ty
|
|
14
|
+
name: ty
|
|
15
|
+
entry: ty check
|
|
16
|
+
language: python
|
|
17
|
+
pass_filenames: false
|
|
18
|
+
additional_dependencies: ["ty==0.0.80", "click>=8.1", "pytest", "mcp>=2.2"]
|
|
19
|
+
args: [src, tests]
|
|
20
|
+
- repo: https://github.com/codespell-project/codespell
|
|
21
|
+
rev: v2.4.2
|
|
22
|
+
hooks:
|
|
23
|
+
- id: codespell
|
|
24
|
+
additional_dependencies: [tomli]
|
|
25
|
+
- repo: https://github.com/gitleaks/gitleaks
|
|
26
|
+
rev: v8.30.1
|
|
27
|
+
hooks:
|
|
28
|
+
- id: gitleaks
|
|
29
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
30
|
+
rev: v6.0.0
|
|
31
|
+
hooks:
|
|
32
|
+
- id: check-yaml
|
|
33
|
+
exclude: ^mkdocs\.yml$
|
|
34
|
+
- id: check-yaml
|
|
35
|
+
name: check-yaml (mkdocs.yml, unsafe for the mermaid !!python/name tag)
|
|
36
|
+
files: ^mkdocs\.yml$
|
|
37
|
+
args: [--unsafe]
|
|
38
|
+
- id: check-toml
|
|
39
|
+
- id: check-json
|
|
40
|
+
- id: check-ast
|
|
41
|
+
- id: check-docstring-first
|
|
42
|
+
- id: check-case-conflict
|
|
43
|
+
- id: check-merge-conflict
|
|
44
|
+
- id: check-added-large-files
|
|
45
|
+
args: [--maxkb=500]
|
|
46
|
+
- id: check-executables-have-shebangs
|
|
47
|
+
- id: trailing-whitespace
|
|
48
|
+
- id: fix-byte-order-marker
|
|
49
|
+
- id: mixed-line-ending
|
|
50
|
+
- id: end-of-file-fixer
|
|
51
|
+
- id: detect-private-key
|
|
52
|
+
- repo: https://github.com/pre-commit/pygrep-hooks
|
|
53
|
+
rev: v1.10.0
|
|
54
|
+
hooks:
|
|
55
|
+
- id: python-use-type-annotations
|
|
56
|
+
- id: python-check-blanket-noqa
|
|
57
|
+
- id: python-check-blanket-type-ignore
|
|
58
|
+
- id: python-check-mock-methods
|
|
59
|
+
- id: python-no-eval
|
|
60
|
+
- id: python-no-log-warn
|
|
61
|
+
- id: text-unicode-replacement-char
|
corvee-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidance for coding agents working on the corvee codebase itself, not the
|
|
4
|
+
pointer block `corvee init` prints for other projects to paste into their
|
|
5
|
+
own AGENTS.md.
|
|
6
|
+
|
|
7
|
+
## Source of truth
|
|
8
|
+
|
|
9
|
+
- `docs/spec.md` is the technical specification: schema, CLI contract, exit
|
|
10
|
+
codes, concurrency model. Implementation must match it. If the two
|
|
11
|
+
disagree, update `docs/spec.md` rather than letting it drift. Any new
|
|
12
|
+
feature bumps the spec's own version and extends `docs/spec.md` first,
|
|
13
|
+
independent of when it gets implemented. The spec documents intended
|
|
14
|
+
design, not just shipped behavior.
|
|
15
|
+
- `pyproject.toml`'s `[tool.hatch.envs.default.scripts]` is the source of
|
|
16
|
+
truth for available dev commands. The list below covers the ones used
|
|
17
|
+
constantly. Run `hatch env show` for the full, current set.
|
|
18
|
+
|
|
19
|
+
## Stack
|
|
20
|
+
|
|
21
|
+
Python 3.11+, managed with Hatch (`uv` as the installer underneath). `src`
|
|
22
|
+
layout: the package lives at `src/corvee/`, tests at `tests/`. click for the
|
|
23
|
+
CLI, stdlib `sqlite3` for storage, no ORM. Every tool (pytest, ty, ruff,
|
|
24
|
+
black, coverage) is configured in `pyproject.toml`, not in separate config
|
|
25
|
+
files.
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
hatch run test # pytest, parallel via pytest-xdist
|
|
29
|
+
hatch run check # every prek hook + test.
|
|
30
|
+
# Run this before considering a change done
|
|
31
|
+
hatch run lint # ruff check, via prek
|
|
32
|
+
hatch run format # black, via prek
|
|
33
|
+
hatch run typecheck # ty, via prek
|
|
34
|
+
hatch run +py=3.12 test:test # run the suite against one Python version
|
|
35
|
+
# from the test matrix (3.11-3.14)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`lint`/`format`/`typecheck` all delegate to `prek run <hook-id>` rather than
|
|
39
|
+
invoking ruff/black/ty directly, so hatch and CI can never drift apart on
|
|
40
|
+
what each one actually runs. `hatch run check` (or `prek run --all-files`
|
|
41
|
+
directly) is the mandatory quality gate before a change is considered
|
|
42
|
+
finished.
|
|
43
|
+
|
|
44
|
+
## Principles
|
|
45
|
+
|
|
46
|
+
KISS, YAGNI, DRY. A change should be minimal and focused on what was asked.
|
|
47
|
+
Do not use a bug fix or small feature as an excuse for a wider rework, a new
|
|
48
|
+
abstraction, or unrelated cleanup. Three similar lines beat a premature
|
|
49
|
+
abstraction.
|
|
50
|
+
|
|
51
|
+
## Architecture
|
|
52
|
+
|
|
53
|
+
Every CLI invocation flows through the same layers, in this order:
|
|
54
|
+
|
|
55
|
+
1. **`cli/main.py`**: the click group. `CorveeGroup.main()` is overridden so
|
|
56
|
+
every failure, including click's own usage errors, is caught and
|
|
57
|
+
re-emitted through one path: a `{"error": {...}}` JSON object on stderr
|
|
58
|
+
plus the documented exit code (`errors.py`). This is what makes
|
|
59
|
+
`CliRunner`-based tests exercise the exact same error path a real
|
|
60
|
+
subprocess would.
|
|
61
|
+
2. **`cli/commands/{task,fact}/*.py`**: one thin click command per verb. The
|
|
62
|
+
pattern is always: parse id(s) with `models.parse_task_refs`/
|
|
63
|
+
`parse_fact_refs` (which also determines local vs global scope from the
|
|
64
|
+
`TASK-GLOBAL-<n>`/`FACT-GLOBAL-<n>` prefix), open `corvee_context(...)`,
|
|
65
|
+
call exactly one `db/*.py` function to do the actual mutation/query, then
|
|
66
|
+
`output.emit_tasks`/`emit_facts` to print. Command files contain no SQL
|
|
67
|
+
and no business logic themselves.
|
|
68
|
+
3. **`cli/context.py`** (`corvee_context`): resolves which SQLite file to
|
|
69
|
+
open (local project via `config.resolve_project()`, or the global
|
|
70
|
+
`~/.corvee/corvee.db` for `scope="global"`), opens it via
|
|
71
|
+
`db/connection.open_connection` (which also bootstraps/migrates the
|
|
72
|
+
schema), and wraps the command body in one transaction: `BEGIN IMMEDIATE`
|
|
73
|
+
for writes, plain `BEGIN` for reads, commit on success, rollback on any
|
|
74
|
+
exception. This is what gives multi-id commands like `task update 4 7 9`
|
|
75
|
+
their all-or-nothing property for free.
|
|
76
|
+
4. **`db/*.py`**: raw `sqlite3` against the schema in `db/schema.py` (no
|
|
77
|
+
ORM). Each module owns one area: `tasks.py`, `facts.py`, `labels.py`,
|
|
78
|
+
`links.py`, `events.py`, `export_import.py`, `stats.py`. Mutating
|
|
79
|
+
functions here call into `guards/*.py` before writing (transition table,
|
|
80
|
+
parent/child cycle checks, claim conflicts, label patterns) and write the
|
|
81
|
+
corresponding `task_events`/`fact_events` row in the same call, so the
|
|
82
|
+
audit trail is not a separate step a caller can forget.
|
|
83
|
+
5. **`guards/*.py`**: pure validation functions that raise
|
|
84
|
+
`errors.GuardViolationError`/`ClaimConflictError`/etc. Consult
|
|
85
|
+
`constants.py` for the data-driven rules (e.g. `TRANSITIONS`, a
|
|
86
|
+
`dict[State, frozenset[State]]`) rather than branching in code, so policy
|
|
87
|
+
changes are edits to one table.
|
|
88
|
+
6. **`output.py`**: JSON array (or single object for `doctor`/`export`) vs.
|
|
89
|
+
fixed-width table rendering, `--fields` projection (`filter_fields`),
|
|
90
|
+
shared by every command group.
|
|
91
|
+
|
|
92
|
+
Cross-cutting modules: `actor.py` resolves `$CORVEE_ACTOR`/
|
|
93
|
+
`$CORVEE_SESSION_ID`. `config.py` walks up from cwd to find
|
|
94
|
+
`.corvee/config.toml` (git-style) and resolves `db_path`. `timeutil.py` is
|
|
95
|
+
the one place that formats the fixed-width UTC-with-milliseconds timestamps
|
|
96
|
+
used everywhere on disk.
|
|
97
|
+
|
|
98
|
+
**Scope.** Every task/fact lives in exactly one of two independent SQLite
|
|
99
|
+
databases: the local project one (`.corvee/corvee.db`, pointed to by
|
|
100
|
+
`.corvee/config.toml`) or one global database shared across the machine
|
|
101
|
+
(`~/.corvee/corvee.db`, created lazily on first `--global` write). Scope is
|
|
102
|
+
fixed at creation and encoded in the id itself (`TASK-14` vs
|
|
103
|
+
`TASK-GLOBAL-14`), never passed as a separate flag on mutating commands. A
|
|
104
|
+
merged read (`--scope all`, the default for listing) opens and closes one
|
|
105
|
+
ordinary connection per database in turn, never a cross-database
|
|
106
|
+
transaction.
|
|
107
|
+
|
|
108
|
+
**Concurrency.** No daemon. Every invocation opens, does its transaction, and
|
|
109
|
+
closes. WAL mode + `busy_timeout=5000` handle contention. Claims are a single
|
|
110
|
+
conditional `UPDATE` checked by rows-affected. Full reasoning in
|
|
111
|
+
`docs/concurrency.md` and spec §3.2/§3.3. Read that before touching
|
|
112
|
+
`cli/context.py` or `db/connection.py`.
|
|
113
|
+
|
|
114
|
+
**Exit codes.** `errors.py` defines one exception subclass per documented
|
|
115
|
+
exit code (0 success, 1 internal, 2 usage, 3 not found, 4 claim conflict, 5
|
|
116
|
+
guard violation, 6 project/config problem). Raise the matching subclass
|
|
117
|
+
rather than a bare exception. `CorveeGroup.main()` is what turns it into the
|
|
118
|
+
JSON-on-stderr shape and the process exit code.
|
|
119
|
+
|
|
120
|
+
## Working here
|
|
121
|
+
|
|
122
|
+
- TDD: write the failing test before the code that makes it pass.
|
|
123
|
+
- No mocking SQLite. Tests run against a real database in `tmp_path`.
|
|
124
|
+
- Every CLI command needs a `--help` epilog with at least three runnable
|
|
125
|
+
examples (enforced by a test).
|
|
126
|
+
- Full type hints throughout. `ty` has zero tolerance for untyped public
|
|
127
|
+
signatures or unjustified `Any`.
|
|
128
|
+
- Tests are classified by directory, not per-test decorators: `tests/unit`
|
|
129
|
+
(pure functions, no filesystem/db), `tests/acceptance` (through the CLI or
|
|
130
|
+
db layer against a real `tmp_path` SQLite database), `tests/e2e` (a real
|
|
131
|
+
`python -m corvee` subprocess). `conftest.py` applies the
|
|
132
|
+
`unit`/`acceptance`/`e2e` pytest marker automatically from
|
|
133
|
+
`item.path.parts`. Key shared fixtures: `project` (initialized project, cwd
|
|
134
|
+
inside it, `CORVEE_ACTOR` set), `runner` (`CliRunner`), `conn` (direct
|
|
135
|
+
connection to the project db), `add_task`/`add_fact` (create via CLI,
|
|
136
|
+
return the id).
|
|
137
|
+
- Never run `corvee ... --global` directly in a shell against this
|
|
138
|
+
machine's real `~/.corvee/corvee.db` while manually poking at --global
|
|
139
|
+
behavior. Set `CORVEE_GLOBAL_DB=/some/scratch/path` first. The pytest
|
|
140
|
+
suite already isolates `$HOME` for you. This is only for ad hoc shell
|
|
141
|
+
commands outside it.
|
|
142
|
+
- Commit one completed corvee task per commit, not a batch of several
|
|
143
|
+
tasks squashed into one. Finish the task (code, tests, docs, `hatch run
|
|
144
|
+
check` green, `corvee task comment`/`update --state done`), then commit
|
|
145
|
+
before starting the next one, so each commit maps onto one reviewable
|
|
146
|
+
unit of work and one task's audit trail.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Requires Python 3.11+ and [Hatch](https://hatch.pypa.io/) (`uv` is used
|
|
4
|
+
underneath as the installer).
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
hatch run test # run the test suite (parallel via pytest-xdist)
|
|
8
|
+
hatch run cov # run the test suite with coverage
|
|
9
|
+
hatch run lint # ruff check, via prek
|
|
10
|
+
hatch run format # black, via prek
|
|
11
|
+
hatch run typecheck # ty, via prek
|
|
12
|
+
hatch run check # every prek hook + test
|
|
13
|
+
hatch run mutate # mutation testing against db/ and guards/,
|
|
14
|
+
# opt-in, not part of check/CI
|
|
15
|
+
hatch run +py=3.12 test:test # run the suite against one Python version
|
|
16
|
+
# from the test matrix (3.11-3.14)
|
|
17
|
+
hatch run docs-serve # serve the documentation locally
|
|
18
|
+
hatch build # build sdist + wheel
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`hatch run check` (or `prek run --all-files` directly) is the quality gate
|
|
22
|
+
for any change. Run it before considering a change done.
|
|
23
|
+
|
|
24
|
+
See [AGENTS.md](AGENTS.md) for the architecture, testing conventions, and
|
|
25
|
+
the `corvee` task-tracking workflow this project uses on itself.
|
|
26
|
+
|
|
27
|
+
## Before you open a PR
|
|
28
|
+
|
|
29
|
+
Open an issue first and wait for a maintainer to approve it before starting
|
|
30
|
+
a pull request. This applies to features and non-trivial fixes. A typo or
|
|
31
|
+
other trivial fix can go straight to a PR. Approval keeps effort from being
|
|
32
|
+
spent on work that doesn't fit the project's direction. PRs opened without an
|
|
33
|
+
approved issue may be closed and asked to go through this process first.
|