thrdi 0.0.1a0__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 (65) hide show
  1. thrdi-0.0.1a0/.github/workflows/release.yml +113 -0
  2. thrdi-0.0.1a0/.github/workflows/test.yml +52 -0
  3. thrdi-0.0.1a0/.gitignore +232 -0
  4. thrdi-0.0.1a0/.pre-commit-config.yaml +20 -0
  5. thrdi-0.0.1a0/LICENSE +21 -0
  6. thrdi-0.0.1a0/PKG-INFO +68 -0
  7. thrdi-0.0.1a0/README.md +34 -0
  8. thrdi-0.0.1a0/RELEASING.md +73 -0
  9. thrdi-0.0.1a0/codecov.yml +21 -0
  10. thrdi-0.0.1a0/pyproject.toml +104 -0
  11. thrdi-0.0.1a0/setup.cfg +4 -0
  12. thrdi-0.0.1a0/src/thirdeye/__init__.py +4 -0
  13. thrdi-0.0.1a0/src/thirdeye/__main__.py +4 -0
  14. thrdi-0.0.1a0/src/thirdeye/_version.py +24 -0
  15. thrdi-0.0.1a0/src/thirdeye/cli.py +25 -0
  16. thrdi-0.0.1a0/src/thirdeye/codec.py +19 -0
  17. thrdi-0.0.1a0/src/thirdeye/commands/__init__.py +0 -0
  18. thrdi-0.0.1a0/src/thirdeye/commands/add.py +25 -0
  19. thrdi-0.0.1a0/src/thirdeye/commands/ingest.py +33 -0
  20. thrdi-0.0.1a0/src/thirdeye/commands/reads.py +112 -0
  21. thrdi-0.0.1a0/src/thirdeye/config.py +33 -0
  22. thrdi-0.0.1a0/src/thirdeye/ids.py +29 -0
  23. thrdi-0.0.1a0/src/thirdeye/index.py +86 -0
  24. thrdi-0.0.1a0/src/thirdeye/meta.py +45 -0
  25. thrdi-0.0.1a0/src/thirdeye/paths.py +25 -0
  26. thrdi-0.0.1a0/src/thirdeye/platforms/__init__.py +0 -0
  27. thrdi-0.0.1a0/src/thirdeye/platforms/base.py +14 -0
  28. thrdi-0.0.1a0/src/thirdeye/platforms/claude/__init__.py +0 -0
  29. thrdi-0.0.1a0/src/thirdeye/platforms/claude/constants.py +20 -0
  30. thrdi-0.0.1a0/src/thirdeye/platforms/claude/hooks.py +85 -0
  31. thrdi-0.0.1a0/src/thirdeye/platforms/claude/install.py +77 -0
  32. thrdi-0.0.1a0/src/thirdeye/reader.py +58 -0
  33. thrdi-0.0.1a0/src/thirdeye/render.py +61 -0
  34. thrdi-0.0.1a0/src/thirdeye/search.py +54 -0
  35. thrdi-0.0.1a0/src/thirdeye/store.py +148 -0
  36. thrdi-0.0.1a0/src/thirdeye/writer.py +113 -0
  37. thrdi-0.0.1a0/src/thrdi.egg-info/PKG-INFO +68 -0
  38. thrdi-0.0.1a0/src/thrdi.egg-info/SOURCES.txt +63 -0
  39. thrdi-0.0.1a0/src/thrdi.egg-info/dependency_links.txt +1 -0
  40. thrdi-0.0.1a0/src/thrdi.egg-info/entry_points.txt +13 -0
  41. thrdi-0.0.1a0/src/thrdi.egg-info/requires.txt +11 -0
  42. thrdi-0.0.1a0/src/thrdi.egg-info/top_level.txt +1 -0
  43. thrdi-0.0.1a0/tests/__init__.py +0 -0
  44. thrdi-0.0.1a0/tests/conftest.py +22 -0
  45. thrdi-0.0.1a0/tests/test_add_command.py +285 -0
  46. thrdi-0.0.1a0/tests/test_claude_constants.py +47 -0
  47. thrdi-0.0.1a0/tests/test_claude_hooks.py +492 -0
  48. thrdi-0.0.1a0/tests/test_claude_install.py +432 -0
  49. thrdi-0.0.1a0/tests/test_cli.py +1022 -0
  50. thrdi-0.0.1a0/tests/test_codec.py +150 -0
  51. thrdi-0.0.1a0/tests/test_e2e.py +221 -0
  52. thrdi-0.0.1a0/tests/test_e2e_claude.py +479 -0
  53. thrdi-0.0.1a0/tests/test_ids.py +41 -0
  54. thrdi-0.0.1a0/tests/test_index.py +193 -0
  55. thrdi-0.0.1a0/tests/test_meta.py +277 -0
  56. thrdi-0.0.1a0/tests/test_paths.py +72 -0
  57. thrdi-0.0.1a0/tests/test_platforms_base.py +77 -0
  58. thrdi-0.0.1a0/tests/test_project_setup.py +148 -0
  59. thrdi-0.0.1a0/tests/test_pyproject_scripts.py +150 -0
  60. thrdi-0.0.1a0/tests/test_reader.py +321 -0
  61. thrdi-0.0.1a0/tests/test_render.py +297 -0
  62. thrdi-0.0.1a0/tests/test_search.py +256 -0
  63. thrdi-0.0.1a0/tests/test_store.py +526 -0
  64. thrdi-0.0.1a0/tests/test_writer.py +589 -0
  65. thrdi-0.0.1a0/uv.lock +715 -0
@@ -0,0 +1,113 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write # needed by github-release job
10
+ id-token: write # needed by publish-pypi job (OIDC)
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ with:
18
+ fetch-depth: 0 # setuptools-scm needs full history
19
+
20
+ - uses: actions/setup-python@v6
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install dependencies
25
+ run: pip install -e ".[dev]"
26
+
27
+ - name: Run tests
28
+ run: pytest tests/ -v
29
+
30
+ build:
31
+ needs: test
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v5
35
+ with:
36
+ fetch-depth: 0 # full history for setuptools-scm
37
+
38
+ - uses: actions/setup-python@v6
39
+ with:
40
+ python-version: "3.12"
41
+
42
+ - name: Install build tools
43
+ run: pip install build
44
+
45
+ - name: Build package
46
+ run: python -m build
47
+
48
+ - name: Upload artifacts
49
+ uses: actions/upload-artifact@v4
50
+ with:
51
+ name: dist
52
+ path: dist/
53
+
54
+ publish-pypi:
55
+ needs: build
56
+ runs-on: ubuntu-latest
57
+ environment: "pypi"
58
+ steps:
59
+ - name: Download artifacts
60
+ uses: actions/download-artifact@v4
61
+ with:
62
+ name: dist
63
+ path: dist/
64
+
65
+ - name: Publish to PyPI
66
+ uses: pypa/gh-action-pypi-publish@release/v1
67
+
68
+ github-release:
69
+ needs: build
70
+ runs-on: ubuntu-latest
71
+ steps:
72
+ - uses: actions/checkout@v5
73
+ with:
74
+ fetch-depth: 0
75
+
76
+ - name: Download artifacts
77
+ uses: actions/download-artifact@v4
78
+ with:
79
+ name: dist
80
+ path: dist/
81
+
82
+ - name: Generate changelog
83
+ id: changelog
84
+ run: |
85
+ NEW_TAG="${GITHUB_REF#refs/tags/}"
86
+ PREV_TAG=$(git tag --sort=-v:refname | grep -v "^${NEW_TAG}$" | head -1)
87
+ if [ -z "$PREV_TAG" ]; then
88
+ CHANGELOG=$(git log --oneline --no-decorate)
89
+ else
90
+ CHANGELOG=$(git log --oneline --no-decorate "${PREV_TAG}..HEAD")
91
+ fi
92
+ {
93
+ echo "changelog<<EOF"
94
+ echo "$CHANGELOG"
95
+ echo "EOF"
96
+ } >> "$GITHUB_OUTPUT"
97
+
98
+ - name: Create GitHub Release
99
+ uses: softprops/action-gh-release@v2
100
+ with:
101
+ body: |
102
+ ## Changes
103
+
104
+ ${{ steps.changelog.outputs.changelog }}
105
+
106
+ ## Install
107
+
108
+ ```bash
109
+ pipx install thrdi
110
+ # or: uv tool install thrdi
111
+ ```
112
+ files: dist/*
113
+ generate_release_notes: false
@@ -0,0 +1,52 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v5
14
+
15
+ - uses: actions/setup-python@v6
16
+ with:
17
+ python-version: "3.12"
18
+
19
+ - name: Install pre-commit
20
+ run: pip install pre-commit
21
+
22
+ - name: Run pre-commit hooks
23
+ run: pre-commit run --all-files
24
+
25
+ test:
26
+ runs-on: ubuntu-latest
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
31
+
32
+ steps:
33
+ - uses: actions/checkout@v5
34
+ with:
35
+ fetch-depth: 0 # full history for setuptools-scm
36
+
37
+ - uses: actions/setup-python@v6
38
+ with:
39
+ python-version: ${{ matrix.python-version }}
40
+ allow-prereleases: true
41
+
42
+ - name: Install dependencies
43
+ run: pip install -e ".[dev]"
44
+
45
+ - name: Run tests with coverage
46
+ run: pytest tests/ -v --cov-report=xml
47
+
48
+ - name: Upload coverage reports to Codecov
49
+ if: matrix.python-version == '3.12'
50
+ uses: codecov/codecov-action@v5
51
+ with:
52
+ token: ${{ secrets.CODECOV_TOKEN }}
@@ -0,0 +1,232 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # Coverage
30
+ .coverage
31
+ .coverage.*
32
+ htmlcov/
33
+ coverage.xml
34
+
35
+ # setuptools-scm generated
36
+ src/thirdeye/_version.py
37
+
38
+ # PyInstaller
39
+ # Usually these files are written by a python script from a template
40
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
41
+ *.manifest
42
+ *.spec
43
+
44
+ # Installer logs
45
+ pip-log.txt
46
+ pip-delete-this-directory.txt
47
+
48
+ # Unit test / coverage reports
49
+ htmlcov/
50
+ .tox/
51
+ .nox/
52
+ .coverage
53
+ .coverage.*
54
+ .cache
55
+ nosetests.xml
56
+ coverage.xml
57
+ *.cover
58
+ *.py.cover
59
+ .hypothesis/
60
+ .pytest_cache/
61
+ cover/
62
+
63
+ # Translations
64
+ *.mo
65
+ *.pot
66
+
67
+ # Django stuff:
68
+ *.log
69
+ local_settings.py
70
+ db.sqlite3
71
+ db.sqlite3-journal
72
+
73
+ # Flask stuff:
74
+ instance/
75
+ .webassets-cache
76
+
77
+ # Scrapy stuff:
78
+ .scrapy
79
+
80
+ # Sphinx documentation
81
+ docs/_build/
82
+
83
+ # PyBuilder
84
+ .pybuilder/
85
+ target/
86
+
87
+ # Jupyter Notebook
88
+ .ipynb_checkpoints
89
+
90
+ # IPython
91
+ profile_default/
92
+ ipython_config.py
93
+
94
+ # pyenv
95
+ # For a library or package, you might want to ignore these files since the code is
96
+ # intended to run in multiple environments; otherwise, check them in:
97
+ # .python-version
98
+
99
+ # pipenv
100
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
101
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
102
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
103
+ # install all needed dependencies.
104
+ # Pipfile.lock
105
+
106
+ # UV
107
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
108
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
109
+ # commonly ignored for libraries.
110
+ # uv.lock
111
+
112
+ # poetry
113
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
114
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
115
+ # commonly ignored for libraries.
116
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
117
+ # poetry.lock
118
+ # poetry.toml
119
+
120
+ # pdm
121
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
122
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
123
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
124
+ # pdm.lock
125
+ # pdm.toml
126
+ .pdm-python
127
+ .pdm-build/
128
+
129
+ # pixi
130
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
131
+ # pixi.lock
132
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
133
+ # in the .venv directory. It is recommended not to include this directory in version control.
134
+ .pixi
135
+
136
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
137
+ __pypackages__/
138
+
139
+ # Celery stuff
140
+ celerybeat-schedule
141
+ celerybeat.pid
142
+
143
+ # Redis
144
+ *.rdb
145
+ *.aof
146
+ *.pid
147
+
148
+ # RabbitMQ
149
+ mnesia/
150
+ rabbitmq/
151
+ rabbitmq-data/
152
+
153
+ # ActiveMQ
154
+ activemq-data/
155
+
156
+ # SageMath parsed files
157
+ *.sage.py
158
+
159
+ # Environments
160
+ .env
161
+ .envrc
162
+ .venv
163
+ env/
164
+ venv/
165
+ ENV/
166
+ env.bak/
167
+ venv.bak/
168
+
169
+ # Spyder project settings
170
+ .spyderproject
171
+ .spyproject
172
+
173
+ # Rope project settings
174
+ .ropeproject
175
+
176
+ # mkdocs documentation
177
+ /site
178
+
179
+ # mypy
180
+ .mypy_cache/
181
+ .dmypy.json
182
+ dmypy.json
183
+
184
+ # Pyre type checker
185
+ .pyre/
186
+
187
+ # pytype static type analyzer
188
+ .pytype/
189
+
190
+ # Cython debug symbols
191
+ cython_debug/
192
+
193
+ # PyCharm
194
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
195
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
196
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
197
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
198
+ # .idea/
199
+
200
+ # Abstra
201
+ # Abstra is an AI-powered process automation framework.
202
+ # Ignore directories containing user credentials, local state, and settings.
203
+ # Learn more at https://abstra.io/docs
204
+ .abstra/
205
+
206
+ # Visual Studio Code
207
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
208
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
209
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
210
+ # you could uncomment the following to ignore the entire vscode folder
211
+ # .vscode/
212
+ # Temporary file for partial code execution
213
+ tempCodeRunnerFile.py
214
+
215
+ # Ruff stuff:
216
+ .ruff_cache/
217
+
218
+ # PyPI configuration file
219
+ .pypirc
220
+
221
+ # Marimo
222
+ marimo/_static/
223
+ marimo/_lsp/
224
+ __marimo__/
225
+
226
+ # Streamlit
227
+ .streamlit/secrets.toml
228
+
229
+ #agents
230
+ .claude/
231
+ .agents/
232
+ .workbench/
@@ -0,0 +1,20 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.6.0
4
+ hooks:
5
+ - id: check-yaml
6
+ - id: check-toml
7
+ - id: check-merge-conflict
8
+ - id: check-added-large-files
9
+ args: [--maxkb=500]
10
+ - id: end-of-file-fixer
11
+ - id: trailing-whitespace
12
+ - id: mixed-line-ending
13
+ args: [--fix=lf]
14
+
15
+ - repo: https://github.com/astral-sh/ruff-pre-commit
16
+ rev: v0.7.4
17
+ hooks:
18
+ - id: ruff
19
+ args: [--fix]
20
+ - id: ruff-format
thrdi-0.0.1a0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Duncan McKinnon
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.
thrdi-0.0.1a0/PKG-INFO ADDED
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.4
2
+ Name: thrdi
3
+ Version: 0.0.1a0
4
+ Summary: Trace any agentic CLI to a unified local store, queryable from the CLI.
5
+ Author: Duncan McKinnon
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/duncankmckinnon/thirdeye
8
+ Project-URL: Issues, https://github.com/duncankmckinnon/thirdeye/issues
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Operating System :: POSIX
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Topic :: Software Development
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: click>=8.1
24
+ Requires-Dist: msgpack>=1.0
25
+ Requires-Dist: zstandard>=0.22
26
+ Requires-Dist: pyaml>=23.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=8.0; extra == "dev"
29
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
30
+ Requires-Dist: pre-commit>=3.7; extra == "dev"
31
+ Requires-Dist: ruff>=0.7; extra == "dev"
32
+ Requires-Dist: build>=1.2; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # thirdeye
36
+
37
+ Trace every agent session on your machine — Claude Code, Cursor, Codex, Gemini, Copilot — into one history you and your agents can search.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ pipx install thrdi # or: uv tool install thrdi
43
+ ```
44
+
45
+ ## Enable tracing
46
+
47
+ ```bash
48
+ thirdeye add --claude # also: --cursor, --codex, --gemini, --copilot
49
+ ```
50
+
51
+ To detach: `thirdeye add --claude --remove`.
52
+
53
+ ## Read your history
54
+
55
+ ```bash
56
+ thirdeye list # every session, every platform
57
+ thirdeye events <id> # one session, terse
58
+ thirdeye tail <id> -n 5 # last few events
59
+ thirdeye event <id> <seq> # one event, fully expanded
60
+ thirdeye search "migration" # substring across all sessions
61
+ thirdeye stats # totals
62
+ ```
63
+
64
+ Add `--json` for parseable JSONL, `--tree` for human-readable, `--platform` / `--cwd` to filter. Session IDs accept any unique prefix. Run `thirdeye --help` for the full reference.
65
+
66
+ ## License
67
+
68
+ MIT.
@@ -0,0 +1,34 @@
1
+ # thirdeye
2
+
3
+ Trace every agent session on your machine — Claude Code, Cursor, Codex, Gemini, Copilot — into one history you and your agents can search.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pipx install thrdi # or: uv tool install thrdi
9
+ ```
10
+
11
+ ## Enable tracing
12
+
13
+ ```bash
14
+ thirdeye add --claude # also: --cursor, --codex, --gemini, --copilot
15
+ ```
16
+
17
+ To detach: `thirdeye add --claude --remove`.
18
+
19
+ ## Read your history
20
+
21
+ ```bash
22
+ thirdeye list # every session, every platform
23
+ thirdeye events <id> # one session, terse
24
+ thirdeye tail <id> -n 5 # last few events
25
+ thirdeye event <id> <seq> # one event, fully expanded
26
+ thirdeye search "migration" # substring across all sessions
27
+ thirdeye stats # totals
28
+ ```
29
+
30
+ Add `--json` for parseable JSONL, `--tree` for human-readable, `--platform` / `--cwd` to filter. Session IDs accept any unique prefix. Run `thirdeye --help` for the full reference.
31
+
32
+ ## License
33
+
34
+ MIT.
@@ -0,0 +1,73 @@
1
+ # Releasing thirdeye
2
+
3
+ The PyPI distribution is published as **`thrdi`**, while the import name and CLI command are **`thirdeye`**. Users do `pipx install thrdi` and then run `thirdeye ...` from any shell.
4
+
5
+ Versions are derived from git tags via `setuptools-scm`. Tagging a commit triggers a CI build and a PyPI publish via OIDC trusted publishing.
6
+
7
+ ## One-time setup
8
+
9
+ These must be done once before the first release.
10
+
11
+ 1. **Reserve the distribution name on PyPI.** Sign in at https://pypi.org and confirm `thrdi` is available at https://pypi.org/project/thrdi/. If taken, change `name` in `pyproject.toml` to a free alternative (the import name and CLI script stay `thirdeye`).
12
+ 2. **Configure trusted publishing on PyPI.** Go to https://pypi.org/manage/account/publishing/ → "Add a new pending publisher" with:
13
+ - PyPI Project Name: `thrdi`
14
+ - Owner: `duncankmckinnon`
15
+ - Repository: `thirdeye`
16
+ - Workflow filename: `release.yml`
17
+ - Environment name: `pypi`
18
+ 3. **Create the `pypi` environment in GitHub.** Repo settings → Environments → New environment named `pypi`. Optionally add a required reviewer for an extra confirmation gate before publish.
19
+ 4. **(Optional) Add a Codecov token.** For private repos or higher rate limits, add `CODECOV_TOKEN` as a repository secret.
20
+
21
+ ## Cutting a release
22
+
23
+ ```bash
24
+ # Make sure main is green
25
+ git checkout main && git pull
26
+ pytest tests/ -v
27
+
28
+ # Tag and push
29
+ git tag v0.1.0
30
+ git push origin v0.1.0
31
+ ```
32
+
33
+ GitHub Actions runs the `release` workflow:
34
+ 1. Runs the test suite
35
+ 2. Builds sdist + wheel using the tag as the version
36
+ 3. Publishes to PyPI via OIDC
37
+ 4. Creates a GitHub Release with auto-generated changelog
38
+
39
+ After ~2 minutes the release is live. `pipx install thrdi` (or `uv tool install thrdi`) installs it; the `thirdeye` command becomes available on PATH.
40
+
41
+ ## Pre-releases
42
+
43
+ Use PEP 440-style suffixed tags:
44
+
45
+ - `v0.2.0a1` — alpha
46
+ - `v0.2.0b1` — beta
47
+ - `v0.2.0rc1` — release candidate
48
+
49
+ PyPI accepts these. `pipx install --pip-args '--pre' thrdi` will pick them up; otherwise stable releases are preferred.
50
+
51
+ ## Local development version
52
+
53
+ Without any tag the package version resolves to `0.1.0.dev0` (set as `fallback_version`). Once the first `v*` tag is pushed, `setuptools-scm` produces dev versions like `0.1.1.dev3+gabc1234` for commits between tags.
54
+
55
+ ## Manual build (no publish)
56
+
57
+ ```bash
58
+ python -m build # produces dist/thrdi-*.tar.gz and dist/thrdi-*.whl
59
+ ```
60
+
61
+ This runs locally for inspection without going to PyPI.
62
+
63
+ ## Pre-commit hooks
64
+
65
+ Install local hooks once after cloning:
66
+
67
+ ```bash
68
+ pre-commit install
69
+ ```
70
+
71
+ Run on demand: `pre-commit run --all-files`.
72
+
73
+ CI runs the same hooks on every PR via the `lint` job in `.github/workflows/test.yml`.
@@ -0,0 +1,21 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: auto
6
+ threshold: 2%
7
+ informational: false
8
+ patch:
9
+ default:
10
+ target: 80%
11
+ threshold: 5%
12
+
13
+ ignore:
14
+ - "tests/**"
15
+ - "src/thirdeye/_version.py"
16
+ - ".workbench/**"
17
+
18
+ comment:
19
+ layout: "header, diff, files"
20
+ behavior: default
21
+ require_changes: false