thrdi 0.0.1__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 (89) hide show
  1. thrdi-0.0.1/.github/actions/update-homebrew-tap/action.yml +85 -0
  2. thrdi-0.0.1/.github/workflows/release.yml +130 -0
  3. thrdi-0.0.1/.github/workflows/test.yml +52 -0
  4. thrdi-0.0.1/.github/workflows/update-homebrew-tap.yml +24 -0
  5. thrdi-0.0.1/.gitignore +233 -0
  6. thrdi-0.0.1/.pre-commit-config.yaml +20 -0
  7. thrdi-0.0.1/Formula/thirdeye.rb +46 -0
  8. thrdi-0.0.1/LICENSE +21 -0
  9. thrdi-0.0.1/PKG-INFO +68 -0
  10. thrdi-0.0.1/README.md +34 -0
  11. thrdi-0.0.1/codecov.yml +21 -0
  12. thrdi-0.0.1/pyproject.toml +113 -0
  13. thrdi-0.0.1/setup.cfg +4 -0
  14. thrdi-0.0.1/src/thirdeye/__init__.py +4 -0
  15. thrdi-0.0.1/src/thirdeye/__main__.py +4 -0
  16. thrdi-0.0.1/src/thirdeye/_version.py +24 -0
  17. thrdi-0.0.1/src/thirdeye/cli.py +29 -0
  18. thrdi-0.0.1/src/thirdeye/codec.py +19 -0
  19. thrdi-0.0.1/src/thirdeye/commands/__init__.py +0 -0
  20. thrdi-0.0.1/src/thirdeye/commands/add.py +43 -0
  21. thrdi-0.0.1/src/thirdeye/commands/ingest.py +33 -0
  22. thrdi-0.0.1/src/thirdeye/commands/reads.py +175 -0
  23. thrdi-0.0.1/src/thirdeye/commands/tags.py +112 -0
  24. thrdi-0.0.1/src/thirdeye/config.py +33 -0
  25. thrdi-0.0.1/src/thirdeye/ids.py +29 -0
  26. thrdi-0.0.1/src/thirdeye/index.py +86 -0
  27. thrdi-0.0.1/src/thirdeye/meta.py +47 -0
  28. thrdi-0.0.1/src/thirdeye/paths.py +29 -0
  29. thrdi-0.0.1/src/thirdeye/platforms/__init__.py +0 -0
  30. thrdi-0.0.1/src/thirdeye/platforms/base.py +14 -0
  31. thrdi-0.0.1/src/thirdeye/platforms/claude/__init__.py +0 -0
  32. thrdi-0.0.1/src/thirdeye/platforms/claude/constants.py +20 -0
  33. thrdi-0.0.1/src/thirdeye/platforms/claude/hooks.py +122 -0
  34. thrdi-0.0.1/src/thirdeye/platforms/claude/install.py +77 -0
  35. thrdi-0.0.1/src/thirdeye/platforms/codex/__init__.py +0 -0
  36. thrdi-0.0.1/src/thirdeye/platforms/codex/constants.py +9 -0
  37. thrdi-0.0.1/src/thirdeye/platforms/codex/hooks.py +72 -0
  38. thrdi-0.0.1/src/thirdeye/platforms/codex/install.py +101 -0
  39. thrdi-0.0.1/src/thirdeye/platforms/gemini/__init__.py +0 -0
  40. thrdi-0.0.1/src/thirdeye/platforms/gemini/constants.py +30 -0
  41. thrdi-0.0.1/src/thirdeye/platforms/gemini/hooks.py +174 -0
  42. thrdi-0.0.1/src/thirdeye/platforms/gemini/install.py +101 -0
  43. thrdi-0.0.1/src/thirdeye/reader.py +58 -0
  44. thrdi-0.0.1/src/thirdeye/render.py +61 -0
  45. thrdi-0.0.1/src/thirdeye/search.py +76 -0
  46. thrdi-0.0.1/src/thirdeye/store.py +176 -0
  47. thrdi-0.0.1/src/thirdeye/tags.py +140 -0
  48. thrdi-0.0.1/src/thirdeye/timeparse.py +61 -0
  49. thrdi-0.0.1/src/thirdeye/writer.py +113 -0
  50. thrdi-0.0.1/src/thrdi.egg-info/PKG-INFO +68 -0
  51. thrdi-0.0.1/src/thrdi.egg-info/SOURCES.txt +87 -0
  52. thrdi-0.0.1/src/thrdi.egg-info/dependency_links.txt +1 -0
  53. thrdi-0.0.1/src/thrdi.egg-info/entry_points.txt +22 -0
  54. thrdi-0.0.1/src/thrdi.egg-info/requires.txt +12 -0
  55. thrdi-0.0.1/src/thrdi.egg-info/top_level.txt +1 -0
  56. thrdi-0.0.1/tests/__init__.py +0 -0
  57. thrdi-0.0.1/tests/conftest.py +22 -0
  58. thrdi-0.0.1/tests/test_add_command.py +508 -0
  59. thrdi-0.0.1/tests/test_claude_constants.py +47 -0
  60. thrdi-0.0.1/tests/test_claude_hooks.py +606 -0
  61. thrdi-0.0.1/tests/test_claude_install.py +432 -0
  62. thrdi-0.0.1/tests/test_cli.py +1022 -0
  63. thrdi-0.0.1/tests/test_codec.py +150 -0
  64. thrdi-0.0.1/tests/test_codex_constants.py +31 -0
  65. thrdi-0.0.1/tests/test_codex_hooks.py +350 -0
  66. thrdi-0.0.1/tests/test_codex_install.py +601 -0
  67. thrdi-0.0.1/tests/test_e2e.py +221 -0
  68. thrdi-0.0.1/tests/test_e2e_claude.py +479 -0
  69. thrdi-0.0.1/tests/test_e2e_codex.py +285 -0
  70. thrdi-0.0.1/tests/test_e2e_gemini.py +298 -0
  71. thrdi-0.0.1/tests/test_gemini_constants.py +64 -0
  72. thrdi-0.0.1/tests/test_gemini_hooks.py +768 -0
  73. thrdi-0.0.1/tests/test_gemini_install.py +511 -0
  74. thrdi-0.0.1/tests/test_ids.py +41 -0
  75. thrdi-0.0.1/tests/test_index.py +193 -0
  76. thrdi-0.0.1/tests/test_meta.py +358 -0
  77. thrdi-0.0.1/tests/test_paths.py +72 -0
  78. thrdi-0.0.1/tests/test_platforms_base.py +77 -0
  79. thrdi-0.0.1/tests/test_project_setup.py +148 -0
  80. thrdi-0.0.1/tests/test_reader.py +321 -0
  81. thrdi-0.0.1/tests/test_reads_cli.py +267 -0
  82. thrdi-0.0.1/tests/test_render.py +297 -0
  83. thrdi-0.0.1/tests/test_search.py +454 -0
  84. thrdi-0.0.1/tests/test_store.py +737 -0
  85. thrdi-0.0.1/tests/test_tag_commands.py +202 -0
  86. thrdi-0.0.1/tests/test_tags.py +259 -0
  87. thrdi-0.0.1/tests/test_timeparse.py +125 -0
  88. thrdi-0.0.1/tests/test_writer.py +589 -0
  89. thrdi-0.0.1/uv.lock +623 -0
@@ -0,0 +1,85 @@
1
+ name: Update Homebrew Tap
2
+ description: Updates the Homebrew formula in a tap repo with a new PyPI release version and SHA256.
3
+
4
+ inputs:
5
+ version:
6
+ description: Package version (without leading v)
7
+ required: true
8
+ tap-repo:
9
+ description: GitHub tap repository (owner/repo)
10
+ default: duncankmckinnon/homebrew-tap
11
+ formula-name:
12
+ description: Formula file name (without .rb)
13
+ default: thirdeye
14
+ pypi-package:
15
+ description: PyPI package name
16
+ default: thrdi
17
+ tap-token:
18
+ description: GitHub PAT with contents:write on the tap repository
19
+ required: true
20
+
21
+ runs:
22
+ using: composite
23
+ steps:
24
+ - name: Wait for PyPI availability
25
+ shell: bash
26
+ env:
27
+ VERSION: ${{ inputs.version }}
28
+ PYPI_PACKAGE: ${{ inputs.pypi-package }}
29
+ run: |
30
+ URL="https://files.pythonhosted.org/packages/source/${PYPI_PACKAGE:0:1}/${PYPI_PACKAGE}/${PYPI_PACKAGE}-${VERSION}.tar.gz"
31
+ echo "Waiting for ${URL} ..."
32
+ for i in $(seq 1 30); do
33
+ if curl -sfI "${URL}" >/dev/null 2>&1; then
34
+ echo "Found on PyPI."
35
+ exit 0
36
+ fi
37
+ echo " attempt ${i}/30 — retrying in 10s"
38
+ sleep 10
39
+ done
40
+ echo "::error::${PYPI_PACKAGE} ${VERSION} not found on PyPI after 5 minutes"
41
+ exit 1
42
+
43
+ - name: Compute SHA256
44
+ id: sha
45
+ shell: bash
46
+ env:
47
+ VERSION: ${{ inputs.version }}
48
+ PYPI_PACKAGE: ${{ inputs.pypi-package }}
49
+ run: |
50
+ URL="https://files.pythonhosted.org/packages/source/${PYPI_PACKAGE:0:1}/${PYPI_PACKAGE}/${PYPI_PACKAGE}-${VERSION}.tar.gz"
51
+ SHA=$(curl -sL "${URL}" | shasum -a 256 | cut -d' ' -f1)
52
+ echo "sha256=${SHA}" >> "$GITHUB_OUTPUT"
53
+ echo "url=${URL}" >> "$GITHUB_OUTPUT"
54
+ echo "SHA256: ${SHA}"
55
+
56
+ - name: Clone tap and update formula
57
+ shell: bash
58
+ env:
59
+ TAP_REPO: ${{ inputs.tap-repo }}
60
+ TAP_TOKEN: ${{ inputs.tap-token }}
61
+ FORMULA: ${{ inputs.formula-name }}
62
+ SHA256: ${{ steps.sha.outputs.sha256 }}
63
+ TARBALL_URL: ${{ steps.sha.outputs.url }}
64
+ VERSION: ${{ inputs.version }}
65
+ run: |
66
+ WORKDIR=$(mktemp -d)
67
+ git clone "https://x-access-token:${TAP_TOKEN}@github.com/${TAP_REPO}.git" "${WORKDIR}/tap"
68
+
69
+ # Copy formula from this repo, patch in version + sha.
70
+ # Anchor to 2-space class-level indent so resource blocks (4-space) are not rewritten.
71
+ DEST="${WORKDIR}/tap/Formula/${FORMULA}.rb"
72
+ mkdir -p "${WORKDIR}/tap/Formula"
73
+ cp "${GITHUB_WORKSPACE}/Formula/${FORMULA}.rb" "${DEST}"
74
+ sed -i "s|^ url \".*\"| url \"${TARBALL_URL}\"|" "${DEST}"
75
+ sed -i "s|^ sha256 \".*\"| sha256 \"${SHA256}\"|" "${DEST}"
76
+
77
+ cd "${WORKDIR}/tap"
78
+ git config user.name "github-actions[bot]"
79
+ git config user.email "github-actions[bot]@users.noreply.github.com"
80
+ git add "Formula/${FORMULA}.rb"
81
+ git commit -m "${FORMULA} ${VERSION}"
82
+ git push origin main
83
+
84
+ rm -rf "${WORKDIR}"
85
+ echo "Tap updated to ${VERSION}"
@@ -0,0 +1,130 @@
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
+ # or: brew install duncankmckinnon/tap/thirdeye
112
+ ```
113
+ files: dist/*
114
+ generate_release_notes: false
115
+
116
+ update-homebrew-tap:
117
+ needs: publish-pypi
118
+ runs-on: ubuntu-latest
119
+ steps:
120
+ - uses: actions/checkout@v5
121
+
122
+ - name: Extract version from tag
123
+ id: version
124
+ run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
125
+
126
+ - name: Update Homebrew tap
127
+ uses: ./.github/actions/update-homebrew-tap
128
+ with:
129
+ version: ${{ steps.version.outputs.version }}
130
+ tap-token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
@@ -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.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,24 @@
1
+ name: Update Homebrew Tap (Manual)
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ version:
7
+ description: "Package version to publish to the tap (without leading v, e.g. 0.0.1)"
8
+ required: true
9
+ type: string
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ update-tap:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v5
19
+
20
+ - name: Update Homebrew tap
21
+ uses: ./.github/actions/update-homebrew-tap
22
+ with:
23
+ version: ${{ inputs.version }}
24
+ tap-token: ${{ secrets.HOMEBREW_TAP_TOKEN }}
thrdi-0.0.1/.gitignore ADDED
@@ -0,0 +1,233 @@
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/
233
+ *docs/superpowers/*
@@ -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
@@ -0,0 +1,46 @@
1
+ class Thirdeye < Formula
2
+ include Language::Python::Virtualenv
3
+
4
+ desc "Trace any agentic CLI to a unified local store, queryable from the CLI"
5
+ homepage "https://github.com/duncankmckinnon/thirdeye"
6
+ url "https://files.pythonhosted.org/packages/source/t/thrdi/thrdi-0.0.1.tar.gz"
7
+ sha256 "PLACEHOLDER"
8
+ license "MIT"
9
+
10
+ depends_on "libyaml"
11
+ depends_on "python@3.12"
12
+
13
+ resource "click" do
14
+ url "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz"
15
+ sha256 "398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2"
16
+ end
17
+
18
+ resource "msgpack" do
19
+ url "https://files.pythonhosted.org/packages/4d/f2/bfb55a6236ed8725a96b0aa3acbd0ec17588e6a2c3b62a93eb513ed8783f/msgpack-1.1.2.tar.gz"
20
+ sha256 "3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e"
21
+ end
22
+
23
+ resource "zstandard" do
24
+ url "https://files.pythonhosted.org/packages/fd/aa/3e0508d5a5dd96529cdc5a97011299056e14c6505b678fd58938792794b1/zstandard-0.25.0.tar.gz"
25
+ sha256 "7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b"
26
+ end
27
+
28
+ resource "pyaml" do
29
+ url "https://files.pythonhosted.org/packages/38/fb/2b9590512a9d7763620d87171c7531d5295678ce96e57393614b91da8998/pyaml-26.2.1.tar.gz"
30
+ sha256 "489dd82997235d4cfcf76a6287fce2f075487d77a6567c271e8d790583690c68"
31
+ end
32
+
33
+ resource "pyyaml" do
34
+ url "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz"
35
+ sha256 "d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"
36
+ end
37
+
38
+ def install
39
+ virtualenv_install_with_resources
40
+ end
41
+
42
+ test do
43
+ assert_match "Usage", shell_output("#{bin}/thirdeye --help")
44
+ assert_match "Usage", shell_output("#{bin}/thrdi --help")
45
+ end
46
+ end
thrdi-0.0.1/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.1/PKG-INFO ADDED
@@ -0,0 +1,68 @@
1
+ Metadata-Version: 2.4
2
+ Name: thrdi
3
+ Version: 0.0.1
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.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Operating System :: POSIX
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Topic :: Software Development
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: click>=8.1
23
+ Requires-Dist: msgpack>=1.0
24
+ Requires-Dist: zstandard>=0.22
25
+ Requires-Dist: pyaml>=23.0
26
+ Requires-Dist: tomli>=2.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 remove --claude`.
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.