harness-detect 0.2.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.
- harness_detect-0.2.0/.gitignore +287 -0
- harness_detect-0.2.0/AGENTS.md +113 -0
- harness_detect-0.2.0/CHANGELOG.md +8 -0
- harness_detect-0.2.0/PKG-INFO +66 -0
- harness_detect-0.2.0/README.md +50 -0
- harness_detect-0.2.0/pyproject.toml +37 -0
- harness_detect-0.2.0/scripts/parity_snapshot.py +299 -0
- harness_detect-0.2.0/scripts/perf_smoke.py +98 -0
- harness_detect-0.2.0/src/harness_detect/__init__.py +680 -0
- harness_detect-0.2.0/src/harness_detect/data/harnesses.json +13219 -0
- harness_detect-0.2.0/tests/test_behavior.py +689 -0
- harness_detect-0.2.0/uv.lock +185 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# BEGIN genignore
|
|
2
|
+
# Generated by genignore. Do not edit between these markers.
|
|
3
|
+
# Providers: macos,python
|
|
4
|
+
# Provenance: github/gitignore@3780fff86c705155792fb3e1787cebd6281ba8cf [macos,python]
|
|
5
|
+
# General
|
|
6
|
+
.DS_Store
|
|
7
|
+
.localized
|
|
8
|
+
__MACOSX/
|
|
9
|
+
.AppleDouble
|
|
10
|
+
.LSOverride
|
|
11
|
+
Icon[
|
|
12
|
+
|
|
13
|
+
# Resource forks
|
|
14
|
+
._*
|
|
15
|
+
|
|
16
|
+
# Files and directories that might appear in the root of a volume
|
|
17
|
+
.DocumentRevisions-V100
|
|
18
|
+
.fseventsd
|
|
19
|
+
.Spotlight-V100
|
|
20
|
+
.TemporaryItems
|
|
21
|
+
.Trashes
|
|
22
|
+
.VolumeIcon.icns
|
|
23
|
+
.com.apple.timemachine.donotpresent
|
|
24
|
+
.com.apple.timemachine.supported
|
|
25
|
+
.PKInstallSandboxManager
|
|
26
|
+
.PKInstallSandboxManager-SystemSoftware
|
|
27
|
+
.hotfiles.btree
|
|
28
|
+
.vol
|
|
29
|
+
.file
|
|
30
|
+
.disk_label*
|
|
31
|
+
lost+found
|
|
32
|
+
.HFS+ Private Directory Data[
|
|
33
|
+
|
|
34
|
+
# Directories potentially created on remote AFP share
|
|
35
|
+
.AppleDB
|
|
36
|
+
.AppleDesktop
|
|
37
|
+
Network Trash Folder
|
|
38
|
+
Temporary Items
|
|
39
|
+
.apdisk
|
|
40
|
+
|
|
41
|
+
# Mac OS 6 to 9
|
|
42
|
+
Desktop DB
|
|
43
|
+
Desktop DF
|
|
44
|
+
TheFindByContentFolder
|
|
45
|
+
TheVolumeSettingsFolder
|
|
46
|
+
.FBCIndex
|
|
47
|
+
.FBCSemaphoreFile
|
|
48
|
+
.FBCLockFolder
|
|
49
|
+
|
|
50
|
+
# Quota system
|
|
51
|
+
.quota.group
|
|
52
|
+
.quota.user
|
|
53
|
+
.quota.ops.group
|
|
54
|
+
.quota.ops.user
|
|
55
|
+
|
|
56
|
+
# TimeMachine
|
|
57
|
+
Backups.backupdb
|
|
58
|
+
.MobileBackups
|
|
59
|
+
.MobileBackups.trash
|
|
60
|
+
MobileBackups.trash
|
|
61
|
+
tmbootpicker.efi
|
|
62
|
+
|
|
63
|
+
# Byte-compiled / optimized / DLL files
|
|
64
|
+
__pycache__/
|
|
65
|
+
*.py[codz]
|
|
66
|
+
*$py.class
|
|
67
|
+
|
|
68
|
+
# C extensions
|
|
69
|
+
*.so
|
|
70
|
+
|
|
71
|
+
# Distribution / packaging
|
|
72
|
+
.Python
|
|
73
|
+
build/
|
|
74
|
+
develop-eggs/
|
|
75
|
+
dist/
|
|
76
|
+
downloads/
|
|
77
|
+
eggs/
|
|
78
|
+
.eggs/
|
|
79
|
+
lib/
|
|
80
|
+
lib64/
|
|
81
|
+
parts/
|
|
82
|
+
sdist/
|
|
83
|
+
var/
|
|
84
|
+
wheels/
|
|
85
|
+
share/python-wheels/
|
|
86
|
+
*.egg-info/
|
|
87
|
+
.installed.cfg
|
|
88
|
+
*.egg
|
|
89
|
+
MANIFEST
|
|
90
|
+
|
|
91
|
+
# PyInstaller
|
|
92
|
+
# Usually these files are written by a python script from a template
|
|
93
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
94
|
+
*.manifest
|
|
95
|
+
*.spec
|
|
96
|
+
|
|
97
|
+
# Installer logs
|
|
98
|
+
pip-log.txt
|
|
99
|
+
pip-delete-this-directory.txt
|
|
100
|
+
|
|
101
|
+
# Unit test / coverage reports
|
|
102
|
+
htmlcov/
|
|
103
|
+
.tox/
|
|
104
|
+
.nox/
|
|
105
|
+
.coverage
|
|
106
|
+
.coverage.*
|
|
107
|
+
.cache
|
|
108
|
+
nosetests.xml
|
|
109
|
+
coverage.xml
|
|
110
|
+
*.cover
|
|
111
|
+
*.py.cover
|
|
112
|
+
*.lcov
|
|
113
|
+
.hypothesis/
|
|
114
|
+
.pytest_cache/
|
|
115
|
+
cover/
|
|
116
|
+
|
|
117
|
+
# Translations
|
|
118
|
+
*.mo
|
|
119
|
+
*.pot
|
|
120
|
+
|
|
121
|
+
# Django stuff:
|
|
122
|
+
*.log
|
|
123
|
+
local_settings.py
|
|
124
|
+
db.sqlite3
|
|
125
|
+
db.sqlite3-journal
|
|
126
|
+
|
|
127
|
+
# Flask stuff:
|
|
128
|
+
instance/
|
|
129
|
+
.webassets-cache
|
|
130
|
+
|
|
131
|
+
# Scrapy stuff:
|
|
132
|
+
.scrapy
|
|
133
|
+
|
|
134
|
+
# Sphinx documentation
|
|
135
|
+
docs/_build/
|
|
136
|
+
|
|
137
|
+
# PyBuilder
|
|
138
|
+
.pybuilder/
|
|
139
|
+
target/
|
|
140
|
+
|
|
141
|
+
# Jupyter Notebook
|
|
142
|
+
.ipynb_checkpoints
|
|
143
|
+
|
|
144
|
+
# IPython
|
|
145
|
+
profile_default/
|
|
146
|
+
ipython_config.py
|
|
147
|
+
|
|
148
|
+
# pyenv
|
|
149
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
150
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
151
|
+
# .python-version
|
|
152
|
+
|
|
153
|
+
# pipenv
|
|
154
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
155
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
156
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
157
|
+
# install all needed dependencies.
|
|
158
|
+
# Pipfile.lock
|
|
159
|
+
|
|
160
|
+
# UV
|
|
161
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
162
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
163
|
+
# commonly ignored for libraries.
|
|
164
|
+
# uv.lock
|
|
165
|
+
|
|
166
|
+
# poetry
|
|
167
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
168
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
169
|
+
# commonly ignored for libraries.
|
|
170
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
171
|
+
# poetry.lock
|
|
172
|
+
# poetry.toml
|
|
173
|
+
|
|
174
|
+
# pdm
|
|
175
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
176
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
177
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
178
|
+
# pdm.lock
|
|
179
|
+
# pdm.toml
|
|
180
|
+
.pdm-python
|
|
181
|
+
.pdm-build/
|
|
182
|
+
|
|
183
|
+
# pixi
|
|
184
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
185
|
+
# pixi.lock
|
|
186
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
187
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
188
|
+
.pixi/*
|
|
189
|
+
!.pixi/config.toml
|
|
190
|
+
|
|
191
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
192
|
+
__pypackages__/
|
|
193
|
+
|
|
194
|
+
# Celery stuff
|
|
195
|
+
celerybeat-schedule*
|
|
196
|
+
celerybeat.pid
|
|
197
|
+
|
|
198
|
+
# Redis
|
|
199
|
+
*.rdb
|
|
200
|
+
*.aof
|
|
201
|
+
*.pid
|
|
202
|
+
|
|
203
|
+
# RabbitMQ
|
|
204
|
+
mnesia/
|
|
205
|
+
rabbitmq/
|
|
206
|
+
rabbitmq-data/
|
|
207
|
+
|
|
208
|
+
# ActiveMQ
|
|
209
|
+
activemq-data/
|
|
210
|
+
|
|
211
|
+
# SageMath parsed files
|
|
212
|
+
*.sage.py
|
|
213
|
+
|
|
214
|
+
# Environments
|
|
215
|
+
.venv
|
|
216
|
+
env/
|
|
217
|
+
venv/
|
|
218
|
+
ENV/
|
|
219
|
+
env.bak/
|
|
220
|
+
venv.bak/
|
|
221
|
+
|
|
222
|
+
# Spyder project settings
|
|
223
|
+
.spyderproject
|
|
224
|
+
.spyproject
|
|
225
|
+
|
|
226
|
+
# Rope project settings
|
|
227
|
+
.ropeproject
|
|
228
|
+
|
|
229
|
+
# mkdocs documentation
|
|
230
|
+
/site
|
|
231
|
+
|
|
232
|
+
# mypy
|
|
233
|
+
.mypy_cache/
|
|
234
|
+
.dmypy.json
|
|
235
|
+
dmypy.json
|
|
236
|
+
|
|
237
|
+
# Pyre type checker
|
|
238
|
+
.pyre/
|
|
239
|
+
|
|
240
|
+
# pytype static type analyzer
|
|
241
|
+
.pytype/
|
|
242
|
+
|
|
243
|
+
# Cython debug symbols
|
|
244
|
+
cython_debug/
|
|
245
|
+
|
|
246
|
+
# PyCharm
|
|
247
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
248
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
249
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
250
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
251
|
+
# .idea/
|
|
252
|
+
|
|
253
|
+
# Abstra
|
|
254
|
+
# Abstra is an AI-powered process automation framework.
|
|
255
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
256
|
+
# Learn more at https://abstra.io/docs
|
|
257
|
+
.abstra/
|
|
258
|
+
|
|
259
|
+
# Visual Studio Code
|
|
260
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
261
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
262
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
263
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
264
|
+
# .vscode/
|
|
265
|
+
# Temporary file for partial code execution
|
|
266
|
+
tempCodeRunnerFile.py
|
|
267
|
+
|
|
268
|
+
# Ruff stuff:
|
|
269
|
+
.ruff_cache/
|
|
270
|
+
|
|
271
|
+
# PyPI configuration file
|
|
272
|
+
.pypirc
|
|
273
|
+
|
|
274
|
+
# Marimo
|
|
275
|
+
marimo/_static/
|
|
276
|
+
marimo/_lsp/
|
|
277
|
+
__marimo__/
|
|
278
|
+
|
|
279
|
+
# Streamlit
|
|
280
|
+
.streamlit/secrets.toml
|
|
281
|
+
|
|
282
|
+
.env
|
|
283
|
+
.env.*
|
|
284
|
+
!.env.example
|
|
285
|
+
!.env.ci
|
|
286
|
+
.envrc
|
|
287
|
+
# END genignore
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
`harness-detect` is a Python port of the `@auron-labs/harness-detect` Node package,
|
|
6
|
+
the Go package at `github.com/auron/harness-detect/packages/golang/harnessdetect`, and the
|
|
7
|
+
`harness-detect` Rust crate. It detects installed LLM harnesses and resolves
|
|
8
|
+
their config/state paths from a bundled JSON registry.
|
|
9
|
+
|
|
10
|
+
- Package entrypoint: `src/harness_detect/__init__.py`
|
|
11
|
+
- Canonical registry: `packages/data/harnesses.json`
|
|
12
|
+
- Bundled registry copy: `src/harness_detect/data/harnesses.json`
|
|
13
|
+
- Tests: `tests/test_behavior.py`
|
|
14
|
+
- Package metadata: `pyproject.toml`
|
|
15
|
+
|
|
16
|
+
## Source-Of-Truth Files
|
|
17
|
+
|
|
18
|
+
- Package code and exported API: `src/harness_detect/__init__.py`
|
|
19
|
+
- Canonical harness matrix data: `packages/data/harnesses.json`
|
|
20
|
+
- Bundled harness matrix copy: `src/harness_detect/data/harnesses.json`
|
|
21
|
+
- TypeScript harness matrix copy: `packages/typescript/data/harnesses.json`
|
|
22
|
+
- Go embedded harness matrix copy: `packages/golang/harnessdetect/data/harnesses.json`
|
|
23
|
+
- Rust embedded harness matrix copy: `packages/rust/data/harnesses.json`
|
|
24
|
+
- Behavior checks: `tests/test_behavior.py`
|
|
25
|
+
- Package metadata: `pyproject.toml`
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
See [../../docs/maintainers.md](../../docs/maintainers.md) for the full
|
|
30
|
+
command reference, the registry editing procedure, and change-aware
|
|
31
|
+
validation. Package-specific commands (run from `packages/python`):
|
|
32
|
+
|
|
33
|
+
| Purpose | Command |
|
|
34
|
+
|---|---|
|
|
35
|
+
| Install dev deps | `uv sync --dev` |
|
|
36
|
+
| Run tests | `uv run pytest` |
|
|
37
|
+
| Lint | `uv run ruff check .` |
|
|
38
|
+
| Format check | `uv run ruff format --check .` |
|
|
39
|
+
| Format apply | `uv run ruff format .` |
|
|
40
|
+
| Build wheel | `uv build` |
|
|
41
|
+
|
|
42
|
+
There is no root `pyproject.toml`; always `cd` into `packages/python` first.
|
|
43
|
+
|
|
44
|
+
## Working Rules
|
|
45
|
+
|
|
46
|
+
- Keep the package dependency-free at runtime. The only runtime dependency is
|
|
47
|
+
the Python standard library (`json`, `os`, `pathlib`, `re`, `importlib`).
|
|
48
|
+
Do not add runtime dependencies without a clear reason.
|
|
49
|
+
- Prefer editing `packages/data/harnesses.json` over adding harness-specific
|
|
50
|
+
code paths in `__init__.py`.
|
|
51
|
+
- `__init__.py` should stay generic: compute effective roots, expand
|
|
52
|
+
templates, check executables, return results. No `if key == "codex"`
|
|
53
|
+
branches.
|
|
54
|
+
- Preserve the current API unless the user asks for a breaking change:
|
|
55
|
+
- `get_raw_harness_data()`
|
|
56
|
+
- `get_harness_matrix()`
|
|
57
|
+
- `list_harnesses()`
|
|
58
|
+
- `get_harness_support(input)`
|
|
59
|
+
- `list_harness_support()`
|
|
60
|
+
- `check_harness(input, options=None)`
|
|
61
|
+
- `detect_harnesses(options=None)`
|
|
62
|
+
- `detect_installed_harnesses(options=None)`
|
|
63
|
+
- Raw-registry APIs, `list_harnesses()`, and detection results that embed a
|
|
64
|
+
full harness definition now expose required `support` metadata wherever they
|
|
65
|
+
expose registry harness entries.
|
|
66
|
+
- `support` is descriptive only. Detection still depends on executable matches
|
|
67
|
+
and existing resolved `paths[]` entries.
|
|
68
|
+
- The repo is still unpublished, so prefer a clean aligned API/schema over
|
|
69
|
+
compatibility-only layers. Keep registry `version: 1` unless internal
|
|
70
|
+
tooling truly requires a bump.
|
|
71
|
+
|
|
72
|
+
## Matrix Editing
|
|
73
|
+
|
|
74
|
+
See [../../docs/maintainers.md](../../docs/maintainers.md) for the
|
|
75
|
+
registry editing rules and post-edit verification. Package-specific
|
|
76
|
+
notes:
|
|
77
|
+
|
|
78
|
+
- `paths[].template` supports `${...}` placeholders resolved by
|
|
79
|
+
`_with_defaults()` + `_resolve_harness_roots()` in `__init__.py`.
|
|
80
|
+
- Use derived roots like `${CODEX_ROOT}` or `${GEMINI_ROOT}` when overrides
|
|
81
|
+
affect default locations; avoid hardcoding `${HOME}/...` when the harness
|
|
82
|
+
has a documented root override.
|
|
83
|
+
- After editing the canonical registry, run `mise run registry:sync`, then
|
|
84
|
+
`mise run registry:check`. Do not hand-edit or manually copy derived package
|
|
85
|
+
registries.
|
|
86
|
+
|
|
87
|
+
## Testing
|
|
88
|
+
|
|
89
|
+
- The tests in `tests/test_behavior.py` mirror the TypeScript, Go, and Rust
|
|
90
|
+
suites: matrix readability, byte-for-byte sync with the canonical registry,
|
|
91
|
+
alias lookup, env overrides, derived roots, project (`${CWD}`) resolution,
|
|
92
|
+
executable detection (including Windows `PATHEXT`), unresolved-placeholder
|
|
93
|
+
semantics, platform gating, and basic registry schema validation.
|
|
94
|
+
- Registry sync changes should also be validated with `bun test` in
|
|
95
|
+
`packages/typescript`, `go test ./...` in `packages/golang`, and
|
|
96
|
+
`cargo test` in `packages/rust` because all package copies must stay
|
|
97
|
+
aligned with `packages/data/harnesses.json`.
|
|
98
|
+
|
|
99
|
+
## Known Pitfalls
|
|
100
|
+
|
|
101
|
+
- `packages/data/harnesses.json` is the canonical registry, but the Python
|
|
102
|
+
package bundles `src/harness_detect/data/harnesses.json` and reads it at
|
|
103
|
+
load time via `importlib.resources`; keep that copy, plus the TypeScript,
|
|
104
|
+
Go, and Rust copies, byte-for-byte aligned after registry edits. The
|
|
105
|
+
`test_bundled_data_matches_shared_file` test asserts this.
|
|
106
|
+
- The registry uses Node.js platform names (`darwin`, `linux`, `win32`).
|
|
107
|
+
`_current_platform()` in `__init__.py` maps `sys.platform` to this
|
|
108
|
+
convention.
|
|
109
|
+
- The package uses `importlib.resources` to locate the bundled JSON, so the
|
|
110
|
+
`data/harnesses.json` file must be included in the wheel build (handled by
|
|
111
|
+
the `force-include` config in `pyproject.toml`).
|
|
112
|
+
- Detection is intentionally evidence-based: a harness can count as installed
|
|
113
|
+
from either an executable match or existing config/state paths.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: harness-detect
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Detect installed LLM harnesses and resolve their config/state paths from a JSON registry.
|
|
5
|
+
Project-URL: Repository, https://github.com/auron/harness-detect
|
|
6
|
+
Project-URL: Issues, https://github.com/auron/harness-detect/issues
|
|
7
|
+
Author: Auron
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: claude,codex,detect,gemini,harness,llm
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: System :: Filesystems
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# harness-detect (Python)
|
|
18
|
+
|
|
19
|
+
Detect installed LLM harnesses (Codex, Claude Code, Gemini CLI, Cursor, and many
|
|
20
|
+
others) and resolve their config/state/install paths from a shared JSON
|
|
21
|
+
registry.
|
|
22
|
+
|
|
23
|
+
This is the Python port of `@auron-labs/harness-detect`. It shares the same harness
|
|
24
|
+
registry as the TypeScript, Go, and Rust packages and exposes the same API
|
|
25
|
+
surface, adapted to idiomatic Python naming.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
pip install harness-detect
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Supported distribution targets are npm (`@auron-labs/harness-detect`), Go modules (`github.com/auron/harness-detect/packages/golang/harnessdetect`, released by `packages/golang/vX.Y.Z` tags), crates.io (`harness-detect`), and PyPI (`harness-detect`). Before the first public release for an ecosystem, these install commands are the intended consumer coordinates and may not resolve yet.
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from harness_detect import detect_installed_harnesses, CheckOptions
|
|
39
|
+
|
|
40
|
+
for r in detect_installed_harnesses(CheckOptions()):
|
|
41
|
+
print(r.key, r.reasons)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Support metadata is also available:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from harness_detect import get_harness_support, list_harness_support
|
|
48
|
+
|
|
49
|
+
codex = get_harness_support("codex")
|
|
50
|
+
print(codex.support.config.global_.status)
|
|
51
|
+
print(len(list_harness_support()))
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Exported API
|
|
55
|
+
|
|
56
|
+
- `get_raw_harness_data()` returns the full registry object.
|
|
57
|
+
- `get_harness_matrix()` returns the full registry object.
|
|
58
|
+
- `list_harnesses()` returns the registry's harness definitions.
|
|
59
|
+
- `get_harness_support(input)` returns support metadata for one harness key or alias.
|
|
60
|
+
- `list_harness_support()` returns support metadata for every harness.
|
|
61
|
+
- `check_harness(input, options=None)` checks one harness key or alias.
|
|
62
|
+
- `detect_harnesses(options=None)` checks every registry entry.
|
|
63
|
+
- `detect_installed_harnesses(options=None)` returns only installed harnesses.
|
|
64
|
+
|
|
65
|
+
See the [package docs](https://github.com/auron/harness-detect) for the full
|
|
66
|
+
API reference.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# harness-detect (Python)
|
|
2
|
+
|
|
3
|
+
Detect installed LLM harnesses (Codex, Claude Code, Gemini CLI, Cursor, and many
|
|
4
|
+
others) and resolve their config/state/install paths from a shared JSON
|
|
5
|
+
registry.
|
|
6
|
+
|
|
7
|
+
This is the Python port of `@auron-labs/harness-detect`. It shares the same harness
|
|
8
|
+
registry as the TypeScript, Go, and Rust packages and exposes the same API
|
|
9
|
+
surface, adapted to idiomatic Python naming.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pip install harness-detect
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Supported distribution targets are npm (`@auron-labs/harness-detect`), Go modules (`github.com/auron/harness-detect/packages/golang/harnessdetect`, released by `packages/golang/vX.Y.Z` tags), crates.io (`harness-detect`), and PyPI (`harness-detect`). Before the first public release for an ecosystem, these install commands are the intended consumer coordinates and may not resolve yet.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from harness_detect import detect_installed_harnesses, CheckOptions
|
|
23
|
+
|
|
24
|
+
for r in detect_installed_harnesses(CheckOptions()):
|
|
25
|
+
print(r.key, r.reasons)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Support metadata is also available:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from harness_detect import get_harness_support, list_harness_support
|
|
32
|
+
|
|
33
|
+
codex = get_harness_support("codex")
|
|
34
|
+
print(codex.support.config.global_.status)
|
|
35
|
+
print(len(list_harness_support()))
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Exported API
|
|
39
|
+
|
|
40
|
+
- `get_raw_harness_data()` returns the full registry object.
|
|
41
|
+
- `get_harness_matrix()` returns the full registry object.
|
|
42
|
+
- `list_harnesses()` returns the registry's harness definitions.
|
|
43
|
+
- `get_harness_support(input)` returns support metadata for one harness key or alias.
|
|
44
|
+
- `list_harness_support()` returns support metadata for every harness.
|
|
45
|
+
- `check_harness(input, options=None)` checks one harness key or alias.
|
|
46
|
+
- `detect_harnesses(options=None)` checks every registry entry.
|
|
47
|
+
- `detect_installed_harnesses(options=None)` returns only installed harnesses.
|
|
48
|
+
|
|
49
|
+
See the [package docs](https://github.com/auron/harness-detect) for the full
|
|
50
|
+
API reference.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "harness-detect"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Detect installed LLM harnesses and resolve their config/state paths from a JSON registry."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Auron" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["llm", "harness", "detect", "codex", "claude", "gemini"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Topic :: System :: Filesystems",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Repository = "https://github.com/auron/harness-detect"
|
|
25
|
+
Issues = "https://github.com/auron/harness-detect/issues"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.build.targets.wheel]
|
|
28
|
+
packages = ["src/harness_detect"]
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
31
|
+
"src/harness_detect/data/harnesses.json" = "harness_detect/data/harnesses.json"
|
|
32
|
+
|
|
33
|
+
[dependency-groups]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=8.0",
|
|
36
|
+
"ruff>=0.6",
|
|
37
|
+
]
|