agentic-coding-harness 0.7.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.
@@ -0,0 +1,6 @@
1
+ dist/
2
+ .venv/
3
+ __pycache__/
4
+ *.pyc
5
+ .pytest_cache/
6
+ uv.lock
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.5
2
+ Name: agentic-coding-harness
3
+ Version: 0.7.1
4
+ Summary: Run, watch, and meter Claude Code, Codex CLI, Gemini CLI, OpenCode, and Kiro from one CLI — verified cost tracking, token usage, budget caps, OTel gen_ai spans, Langfuse traces, and a live dashboard + MCP server.
5
+ Project-URL: Homepage, https://github.com/sblattj/agentic-coding-harness
6
+ Project-URL: Repository, https://github.com/sblattj/agentic-coding-harness
7
+ Project-URL: Issues, https://github.com/sblattj/agentic-coding-harness/issues
8
+ Author: Stephen Blatt
9
+ License: MIT
10
+ Keywords: agent-observability,ai-agents,claude-code,cli,codex-cli,coding-agent,cost-tracking,gemini-cli,kiro,langfuse,llm,mcp-server,opencode,opentelemetry,token-usage
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Software Development
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.9
27
+ Description-Content-Type: text/markdown
28
+
29
+ # agentic-coding-harness (Python wrapper)
30
+
31
+ [![PyPI](https://img.shields.io/pypi/v/agentic-coding-harness)](https://pypi.org/project/agentic-coding-harness/)
32
+
33
+ Run, watch, and meter coding agents from the command line. This Python
34
+ package wraps the compiled `ach` CLI (vendored inside the wheel) and launches
35
+ it with whatever JavaScript runtime you have installed — Bun if available,
36
+ otherwise Node.js >= 18.19. No Python runtime dependencies; stdlib only.
37
+
38
+ ```sh
39
+ # run without installing (the alias name matters for uvx)
40
+ uvx agentic-coding-harness --help
41
+
42
+ # or install
43
+ uv tool install agentic-coding-harness
44
+ ach --help
45
+ ```
46
+
47
+ ## Requirements
48
+
49
+ - Python 3.9+
50
+ - Bun or Node.js >= 18.19 on your PATH (or in the usual install dirs), or set
51
+ `AGENTIC_CODING_HARNESS_RUNTIME=/path/to/runtime` to force one.
52
+
53
+ ## What it does
54
+
55
+ The console scripts `ach` and `agentic-coding-harness` both locate a JS
56
+ runtime, then `exec` the vendored `ach.mjs` bundle with full argument, stdio,
57
+ signal, and exit-code passthrough. If no runtime is found they print install
58
+ instructions and exit 127.
59
+
60
+ See the [project README](https://github.com/sblattj/agentic-coding-harness)
61
+ for the full `ach` CLI documentation.
@@ -0,0 +1,33 @@
1
+ # agentic-coding-harness (Python wrapper)
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/agentic-coding-harness)](https://pypi.org/project/agentic-coding-harness/)
4
+
5
+ Run, watch, and meter coding agents from the command line. This Python
6
+ package wraps the compiled `ach` CLI (vendored inside the wheel) and launches
7
+ it with whatever JavaScript runtime you have installed — Bun if available,
8
+ otherwise Node.js >= 18.19. No Python runtime dependencies; stdlib only.
9
+
10
+ ```sh
11
+ # run without installing (the alias name matters for uvx)
12
+ uvx agentic-coding-harness --help
13
+
14
+ # or install
15
+ uv tool install agentic-coding-harness
16
+ ach --help
17
+ ```
18
+
19
+ ## Requirements
20
+
21
+ - Python 3.9+
22
+ - Bun or Node.js >= 18.19 on your PATH (or in the usual install dirs), or set
23
+ `AGENTIC_CODING_HARNESS_RUNTIME=/path/to/runtime` to force one.
24
+
25
+ ## What it does
26
+
27
+ The console scripts `ach` and `agentic-coding-harness` both locate a JS
28
+ runtime, then `exec` the vendored `ach.mjs` bundle with full argument, stdio,
29
+ signal, and exit-code passthrough. If no runtime is found they print install
30
+ instructions and exit 127.
31
+
32
+ See the [project README](https://github.com/sblattj/agentic-coding-harness)
33
+ for the full `ach` CLI documentation.
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agentic-coding-harness"
7
+ version = "0.7.1"
8
+ description = "Run, watch, and meter Claude Code, Codex CLI, Gemini CLI, OpenCode, and Kiro from one CLI — verified cost tracking, token usage, budget caps, OTel gen_ai spans, Langfuse traces, and a live dashboard + MCP server."
9
+ keywords = ["claude-code", "codex-cli", "gemini-cli", "opencode", "kiro", "coding-agent", "agent-observability", "cost-tracking", "token-usage", "opentelemetry", "langfuse", "mcp-server", "llm", "ai-agents", "cli"]
10
+ authors = [{ name = "Stephen Blatt" }]
11
+ license = { text = "MIT" }
12
+ readme = "README.md"
13
+ requires-python = ">=3.9"
14
+ dependencies = []
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Operating System :: MacOS",
21
+ "Operating System :: POSIX :: Linux",
22
+ "Operating System :: Microsoft :: Windows",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
29
+ "Topic :: Software Development",
30
+ "Typing :: Typed",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/sblattj/agentic-coding-harness"
35
+ Repository = "https://github.com/sblattj/agentic-coding-harness"
36
+ Issues = "https://github.com/sblattj/agentic-coding-harness/issues"
37
+
38
+ [project.scripts]
39
+ ach = "agentic_coding_harness._cli:main"
40
+ agentic-coding-harness = "agentic_coding_harness._cli:main"
41
+
42
+ [tool.hatch.build.targets.wheel]
43
+ packages = ["src/agentic_coding_harness"]
44
+ artifacts = ["src/agentic_coding_harness/_vendor/ach.mjs"]
45
+
46
+ [tool.hatch.build.targets.sdist]
47
+ include = [
48
+ "src/agentic_coding_harness",
49
+ "tests",
50
+ "README.md",
51
+ "pyproject.toml",
52
+ ]
53
+ artifacts = ["src/agentic_coding_harness/_vendor/ach.mjs"]
@@ -0,0 +1,10 @@
1
+ """agentic-coding-harness: run/watch/meter coding agents.
2
+
3
+ Python wrapper that locates a JavaScript runtime (Bun preferred, then
4
+ Node.js >= 18.19) and execs the vendored ach.mjs CLI bundle with full
5
+ argument passthrough.
6
+ """
7
+
8
+ __version__ = "0.7.1"
9
+
10
+ __all__ = ["__version__"]
@@ -0,0 +1,126 @@
1
+ """Console-script entry point: locate a JS runtime and exec the vendored ach.mjs.
2
+
3
+ Stdlib only. Prefers Bun, then Node >= 18.19. The runtime may be forced via
4
+ the AGENTIC_CODING_HARNESS_RUNTIME environment variable. On POSIX we execv so
5
+ stdio, signals, and exit codes pass through untouched; on Windows we fall back
6
+ to subprocess.call.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import shutil
13
+ import subprocess
14
+ import sys
15
+
16
+ _PACKAGE_DIR = os.path.dirname(os.path.abspath(__file__))
17
+ _BUNDLE = os.path.join(_PACKAGE_DIR, "_vendor", "ach.mjs")
18
+ _RUNTIME_ENV = "AGENTIC_CODING_HARNESS_RUNTIME"
19
+
20
+ _COMMON_DIRS = (
21
+ "/opt/homebrew/bin",
22
+ "/usr/local/bin",
23
+ os.path.expanduser("~/.bun/bin"),
24
+ os.path.expanduser("~/.volta/bin"),
25
+ )
26
+
27
+ _MISSING_RUNTIME_MESSAGE = """ach: no JavaScript runtime found.
28
+
29
+ agentic-coding-harness needs Bun or Node.js (>= 18.19) to run.
30
+
31
+ Install one of:
32
+ curl -fsSL https://bun.sh/install | bash # Bun (recommended)
33
+ https://nodejs.org/en/download # Node.js >= 18.19
34
+
35
+ Or point {env} at an existing runtime binary, e.g.:
36
+ export {env}=/usr/local/bin/node
37
+ """.format(env=_RUNTIME_ENV)
38
+
39
+
40
+ def _candidate_paths(name: str):
41
+ found = shutil.which(name)
42
+ if found:
43
+ yield found
44
+ seen = {found} if found else set()
45
+ for directory in _COMMON_DIRS:
46
+ candidate = os.path.join(directory, name)
47
+ if candidate not in seen and os.path.isfile(candidate) and os.access(candidate, os.X_OK):
48
+ seen.add(candidate)
49
+ yield candidate
50
+
51
+
52
+ def _node_major_minor(path: str):
53
+ """Return (major, minor) for a node binary, or None if it can't be probed."""
54
+ try:
55
+ out = subprocess.run(
56
+ [path, "--version"],
57
+ capture_output=True,
58
+ text=True,
59
+ timeout=10,
60
+ check=False,
61
+ )
62
+ except (OSError, subprocess.SubprocessError):
63
+ return None
64
+ version = (out.stdout or "").strip().lstrip("v")
65
+ if not version:
66
+ return None
67
+ parts = version.split(".")
68
+ try:
69
+ return int(parts[0]), int(parts[1])
70
+ except (ValueError, IndexError):
71
+ return None
72
+
73
+
74
+ def find_runtime(env=None):
75
+ """Return the path to a usable JS runtime, or None.
76
+
77
+ Honors AGENTIC_CODING_HARNESS_RUNTIME when set.
78
+ """
79
+ environ = env if env is not None else os.environ
80
+ override = environ.get(_RUNTIME_ENV)
81
+ if override:
82
+ if os.path.isfile(override) and os.access(override, os.X_OK):
83
+ return override
84
+ resolved = shutil.which(override)
85
+ if resolved:
86
+ return resolved
87
+ return None
88
+
89
+ for bun in _candidate_paths("bun"):
90
+ return bun
91
+
92
+ for node in _candidate_paths("node"):
93
+ version = _node_major_minor(node)
94
+ if version is None:
95
+ # Unprobeable (e.g. broken install) - skip rather than fail hard.
96
+ continue
97
+ major, minor = version
98
+ if (major, minor) >= (18, 19):
99
+ return node
100
+
101
+ return None
102
+
103
+
104
+ def main(argv=None):
105
+ runtime = find_runtime()
106
+ if runtime is None:
107
+ sys.stderr.write(_MISSING_RUNTIME_MESSAGE)
108
+ return 127
109
+ if not os.path.isfile(_BUNDLE):
110
+ sys.stderr.write(
111
+ "ach: vendored bundle missing ({}). The install is broken; "
112
+ "reinstall agentic-coding-harness.\n".format(_BUNDLE)
113
+ )
114
+ return 127
115
+
116
+ args = list(sys.argv[1:] if argv is None else argv)
117
+
118
+ if os.name == "posix":
119
+ os.execv(runtime, [runtime, _BUNDLE] + args) # never returns
120
+ return 127 # pragma: no cover - execv failed to replace us
121
+
122
+ return subprocess.call([runtime, _BUNDLE] + args)
123
+
124
+
125
+ if __name__ == "__main__":
126
+ sys.exit(main())