hadara 0.2.0rc1__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.
- hadara-0.2.0rc1/.gitignore +37 -0
- hadara-0.2.0rc1/PKG-INFO +95 -0
- hadara-0.2.0rc1/README.md +76 -0
- hadara-0.2.0rc1/pyproject.toml +34 -0
- hadara-0.2.0rc1/src/hadara/__init__.py +11 -0
- hadara-0.2.0rc1/src/hadara/bridge.py +27 -0
- hadara-0.2.0rc1/src/hadara/cli.py +93 -0
- hadara-0.2.0rc1/src/hadara/version.py +7 -0
- hadara-0.2.0rc1/tests/test_bridge.py +11 -0
- hadara-0.2.0rc1/tests/test_cli.py +91 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
node_modules/
|
|
2
|
+
dist/
|
|
3
|
+
coverage/
|
|
4
|
+
*.log
|
|
5
|
+
dist-release/
|
|
6
|
+
|
|
7
|
+
# HADARA portable/local state
|
|
8
|
+
data/
|
|
9
|
+
.hadara/local/
|
|
10
|
+
.hadara/tmp/
|
|
11
|
+
.hadara/cache/
|
|
12
|
+
|
|
13
|
+
# OS/editor
|
|
14
|
+
.DS_Store
|
|
15
|
+
Thumbs.db
|
|
16
|
+
.vscode/*
|
|
17
|
+
!.vscode/extensions.json
|
|
18
|
+
|
|
19
|
+
# dev only
|
|
20
|
+
.env
|
|
21
|
+
__pycache__/
|
|
22
|
+
*.py[cod]
|
|
23
|
+
*.egg-info/
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.venv/
|
|
26
|
+
build/
|
|
27
|
+
docs/specs/
|
|
28
|
+
docs/design/mockups/*
|
|
29
|
+
!docs/design/mockups/HADARA_web_ui_v0.1_comfort_dark.html
|
|
30
|
+
.dockerignore
|
|
31
|
+
|
|
32
|
+
.mockup/
|
|
33
|
+
.agent_alpha_test/
|
|
34
|
+
.mcp.json
|
|
35
|
+
|
|
36
|
+
# Phase 5.6 dashboard visual baselines (generated)
|
|
37
|
+
.dashboard-visual/
|
hadara-0.2.0rc1/PKG-INFO
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hadara
|
|
3
|
+
Version: 0.2.0rc1
|
|
4
|
+
Summary: Python bridge package for HADARA. The current runtime requires Node.js.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ictseoyoungmin/HADARA-dev
|
|
6
|
+
Project-URL: Source, https://github.com/ictseoyoungmin/HADARA-dev
|
|
7
|
+
Project-URL: Issues, https://github.com/ictseoyoungmin/HADARA-dev/issues
|
|
8
|
+
Author-email: study Y <yeeca0401@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# HADARA for Python
|
|
21
|
+
|
|
22
|
+
This is a preview Python bridge package for HADARA.
|
|
23
|
+
|
|
24
|
+
The current implementation delegates to the official Node.js HADARA runtime. It
|
|
25
|
+
requires Node.js 22+ and `npx`.
|
|
26
|
+
|
|
27
|
+
If you want the primary runtime, use:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install -g hadara@0.2.0-rc.1
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then run:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
hadara doctor --json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install hadara
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The installed `hadara` command is a Python console-script wrapper. It checks
|
|
46
|
+
that Node.js 22+ and `npx` are available, then delegates to the pinned npm
|
|
47
|
+
runtime:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx -y hadara@0.2.0-rc.1 <args>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For example:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
hadara --help
|
|
57
|
+
hadara --version
|
|
58
|
+
hadara doctor --json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Missing Node.js
|
|
62
|
+
|
|
63
|
+
If Node.js or `npx` is missing, the wrapper exits with code `127` and prints a
|
|
64
|
+
clear setup message instead of failing with a Python traceback.
|
|
65
|
+
|
|
66
|
+
Recommended setup:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install -g hadara@0.2.0-rc.1
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Scope
|
|
73
|
+
|
|
74
|
+
This package is intentionally small:
|
|
75
|
+
|
|
76
|
+
- It is not a Python-native HADARA runtime.
|
|
77
|
+
- It does not publish npm packages, upload to PyPI, create releases, or run
|
|
78
|
+
installers.
|
|
79
|
+
- It is a bridge package so Python users can discover the official HADARA CLI
|
|
80
|
+
path and use a familiar `pip install hadara` entry point.
|
|
81
|
+
|
|
82
|
+
A Python-native runtime or SDK may be added later under modules such as
|
|
83
|
+
`hadara.protocol`, `hadara.evidence`, or `hadara.handoff`.
|
|
84
|
+
|
|
85
|
+
## Development
|
|
86
|
+
|
|
87
|
+
Run these commands from the `python/` directory:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
python -m pip install -U pip build twine pytest
|
|
91
|
+
python -m pip install -e .
|
|
92
|
+
python -m pytest
|
|
93
|
+
python -m build
|
|
94
|
+
python -m twine check dist/*
|
|
95
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# HADARA for Python
|
|
2
|
+
|
|
3
|
+
This is a preview Python bridge package for HADARA.
|
|
4
|
+
|
|
5
|
+
The current implementation delegates to the official Node.js HADARA runtime. It
|
|
6
|
+
requires Node.js 22+ and `npx`.
|
|
7
|
+
|
|
8
|
+
If you want the primary runtime, use:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g hadara@0.2.0-rc.1
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then run:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
hadara doctor --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install hadara
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The installed `hadara` command is a Python console-script wrapper. It checks
|
|
27
|
+
that Node.js 22+ and `npx` are available, then delegates to the pinned npm
|
|
28
|
+
runtime:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx -y hadara@0.2.0-rc.1 <args>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
For example:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
hadara --help
|
|
38
|
+
hadara --version
|
|
39
|
+
hadara doctor --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Missing Node.js
|
|
43
|
+
|
|
44
|
+
If Node.js or `npx` is missing, the wrapper exits with code `127` and prints a
|
|
45
|
+
clear setup message instead of failing with a Python traceback.
|
|
46
|
+
|
|
47
|
+
Recommended setup:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm install -g hadara@0.2.0-rc.1
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Scope
|
|
54
|
+
|
|
55
|
+
This package is intentionally small:
|
|
56
|
+
|
|
57
|
+
- It is not a Python-native HADARA runtime.
|
|
58
|
+
- It does not publish npm packages, upload to PyPI, create releases, or run
|
|
59
|
+
installers.
|
|
60
|
+
- It is a bridge package so Python users can discover the official HADARA CLI
|
|
61
|
+
path and use a familiar `pip install hadara` entry point.
|
|
62
|
+
|
|
63
|
+
A Python-native runtime or SDK may be added later under modules such as
|
|
64
|
+
`hadara.protocol`, `hadara.evidence`, or `hadara.handoff`.
|
|
65
|
+
|
|
66
|
+
## Development
|
|
67
|
+
|
|
68
|
+
Run these commands from the `python/` directory:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python -m pip install -U pip build twine pytest
|
|
72
|
+
python -m pip install -e .
|
|
73
|
+
python -m pytest
|
|
74
|
+
python -m build
|
|
75
|
+
python -m twine check dist/*
|
|
76
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "hadara"
|
|
7
|
+
version = "0.2.0rc1"
|
|
8
|
+
description = "Python bridge package for HADARA. The current runtime requires Node.js."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "study Y", email = "yeeca0401@gmail.com" }
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Topic :: Software Development :: Build Tools"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://github.com/ictseoyoungmin/HADARA-dev"
|
|
27
|
+
Source = "https://github.com/ictseoyoungmin/HADARA-dev"
|
|
28
|
+
Issues = "https://github.com/ictseoyoungmin/HADARA-dev/issues"
|
|
29
|
+
|
|
30
|
+
[project.scripts]
|
|
31
|
+
hadara = "hadara.cli:main"
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Preview Python bridge package for HADARA.
|
|
2
|
+
|
|
3
|
+
The package currently delegates command execution to the official Node.js
|
|
4
|
+
HADARA runtime. It exists so Python users have an official package name and a
|
|
5
|
+
clear path to the primary CLI while Python-native modules are still future
|
|
6
|
+
work.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .version import NPM_RUNTIME_SPEC, __version__
|
|
10
|
+
|
|
11
|
+
__all__ = ["NPM_RUNTIME_SPEC", "__version__"]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Helpers for bridging Python console entry points to the HADARA npm CLI.
|
|
2
|
+
|
|
3
|
+
The first PyPI preview intentionally avoids resolving a global ``hadara``
|
|
4
|
+
binary. A Python console-script named ``hadara`` may point back to this package,
|
|
5
|
+
so blindly executing ``shutil.which("hadara")`` can recurse into the wrapper.
|
|
6
|
+
The bridge therefore uses a pinned ``npx`` invocation until a later release can
|
|
7
|
+
implement and test safe self-wrapper exclusion.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from collections.abc import Sequence
|
|
13
|
+
|
|
14
|
+
from .version import NPM_RUNTIME_SPEC
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def build_npx_command(args: Sequence[str]) -> list[str]:
|
|
18
|
+
"""Return the subprocess command used to invoke the Node.js runtime.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
args: CLI arguments that should be forwarded to HADARA.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
A command list suitable for ``subprocess.call``.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
return ["npx", "-y", NPM_RUNTIME_SPEC, *args]
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""Console entry point for the HADARA Python bridge.
|
|
2
|
+
|
|
3
|
+
The ``hadara`` command installed by this package is a small, friendly wrapper
|
|
4
|
+
around the official Node.js runtime. It validates that Node.js 22+ and ``npx``
|
|
5
|
+
are available, emits a clear setup message when they are not, and otherwise
|
|
6
|
+
delegates all arguments to the pinned npm release.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
import shutil
|
|
13
|
+
import subprocess
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
from .bridge import build_npx_command
|
|
17
|
+
from .version import MINIMUM_NODE_MAJOR, MINIMUM_NODE_VERSION, NPM_RUNTIME_SPEC
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
MISSING_RUNTIME_MESSAGE = f"""HADARA Python package is currently a bridge to the official Node.js runtime.
|
|
21
|
+
|
|
22
|
+
Node.js {MINIMUM_NODE_VERSION}+ and npx are required for this preview release.
|
|
23
|
+
|
|
24
|
+
Recommended install:
|
|
25
|
+
npm install -g {NPM_RUNTIME_SPEC}
|
|
26
|
+
|
|
27
|
+
Then run:
|
|
28
|
+
hadara doctor --json
|
|
29
|
+
|
|
30
|
+
A Python-native runtime is planned.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _detect_node_major_version(node_path: str) -> int | None:
|
|
35
|
+
"""Return the Node.js major version for a resolved executable path.
|
|
36
|
+
|
|
37
|
+
The bridge intentionally keeps this probe small and side-effect-free:
|
|
38
|
+
``node --version`` should only print a version string such as ``v22.16.0``.
|
|
39
|
+
If the executable cannot run or prints an unexpected value, ``None`` is
|
|
40
|
+
returned so the caller can fail with the same friendly setup message.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
output = subprocess.check_output(
|
|
45
|
+
[node_path, "--version"],
|
|
46
|
+
stderr=subprocess.DEVNULL,
|
|
47
|
+
text=True,
|
|
48
|
+
timeout=2,
|
|
49
|
+
)
|
|
50
|
+
except (OSError, subprocess.SubprocessError):
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
version = output.strip()
|
|
54
|
+
if version.startswith("v"):
|
|
55
|
+
version = version[1:]
|
|
56
|
+
|
|
57
|
+
major_text = version.split(".", 1)[0]
|
|
58
|
+
if not major_text.isdigit():
|
|
59
|
+
return None
|
|
60
|
+
|
|
61
|
+
return int(major_text)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
65
|
+
"""Run HADARA through the official npm runtime.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
argv: Optional argument sequence. When omitted, ``sys.argv[1:]`` is
|
|
69
|
+
forwarded.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The subprocess exit code, or ``127`` when Node.js 22+/npx are
|
|
73
|
+
unavailable.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
forwarded_args = list(sys.argv[1:] if argv is None else argv)
|
|
77
|
+
node = shutil.which("node")
|
|
78
|
+
npx = shutil.which("npx")
|
|
79
|
+
|
|
80
|
+
if node is None or npx is None:
|
|
81
|
+
print(MISSING_RUNTIME_MESSAGE, file=sys.stderr, end="")
|
|
82
|
+
return 127
|
|
83
|
+
|
|
84
|
+
node_major_version = _detect_node_major_version(node)
|
|
85
|
+
if node_major_version is None or node_major_version < MINIMUM_NODE_MAJOR:
|
|
86
|
+
print(MISSING_RUNTIME_MESSAGE, file=sys.stderr, end="")
|
|
87
|
+
return 127
|
|
88
|
+
|
|
89
|
+
return subprocess.call(build_npx_command(forwarded_args))
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from hadara import __version__
|
|
8
|
+
from hadara import cli
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_version_is_python_bridge_preview() -> None:
|
|
12
|
+
assert __version__ == "0.2.0rc1"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_main_prints_friendly_message_when_node_is_missing(
|
|
16
|
+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
17
|
+
) -> None:
|
|
18
|
+
monkeypatch.setattr(cli.shutil, "which", lambda name: None)
|
|
19
|
+
|
|
20
|
+
result = cli.main(["doctor", "--json"])
|
|
21
|
+
|
|
22
|
+
captured = capsys.readouterr()
|
|
23
|
+
assert result == 127
|
|
24
|
+
assert captured.out == ""
|
|
25
|
+
assert "bridge to the official Node.js runtime" in captured.err
|
|
26
|
+
assert "Node.js 22+ and npx are required" in captured.err
|
|
27
|
+
assert "npm install -g hadara@0.2.0-rc.1" in captured.err
|
|
28
|
+
assert "A Python-native runtime is planned." in captured.err
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_main_prints_friendly_message_when_npx_is_missing(
|
|
32
|
+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
33
|
+
) -> None:
|
|
34
|
+
def fake_which(name: str) -> str | None:
|
|
35
|
+
return "/usr/bin/node" if name == "node" else None
|
|
36
|
+
|
|
37
|
+
monkeypatch.setattr(cli.shutil, "which", fake_which)
|
|
38
|
+
|
|
39
|
+
result = cli.main(["--help"])
|
|
40
|
+
|
|
41
|
+
captured = capsys.readouterr()
|
|
42
|
+
assert result == 127
|
|
43
|
+
assert "Node.js 22+ and npx are required" in captured.err
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_main_prints_friendly_message_when_node_is_too_old(
|
|
47
|
+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
|
|
48
|
+
) -> None:
|
|
49
|
+
def fake_which(name: str) -> str | None:
|
|
50
|
+
return f"/usr/bin/{name}" if name in {"node", "npx"} else None
|
|
51
|
+
|
|
52
|
+
monkeypatch.setattr(cli.shutil, "which", fake_which)
|
|
53
|
+
monkeypatch.setattr(cli, "_detect_node_major_version", lambda node_path: 20)
|
|
54
|
+
|
|
55
|
+
result = cli.main(["doctor", "--json"])
|
|
56
|
+
|
|
57
|
+
captured = capsys.readouterr()
|
|
58
|
+
assert result == 127
|
|
59
|
+
assert "Node.js 22+ and npx are required" in captured.err
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_main_delegates_to_pinned_npx_runtime(
|
|
63
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
64
|
+
) -> None:
|
|
65
|
+
calls: list[list[str]] = []
|
|
66
|
+
|
|
67
|
+
def fake_which(name: str) -> str | None:
|
|
68
|
+
return f"/usr/bin/{name}" if name in {"node", "npx"} else None
|
|
69
|
+
|
|
70
|
+
def fake_call(command: list[str]) -> int:
|
|
71
|
+
calls.append(command)
|
|
72
|
+
return 0
|
|
73
|
+
|
|
74
|
+
monkeypatch.setattr(cli.shutil, "which", fake_which)
|
|
75
|
+
monkeypatch.setattr(cli, "_detect_node_major_version", lambda node_path: 22)
|
|
76
|
+
monkeypatch.setattr(subprocess, "call", fake_call)
|
|
77
|
+
|
|
78
|
+
result = cli.main(["doctor", "--json"])
|
|
79
|
+
|
|
80
|
+
assert result == 0
|
|
81
|
+
assert calls == [["npx", "-y", "hadara@0.2.0-rc.1", "doctor", "--json"]]
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_main_propagates_subprocess_exit_code(
|
|
85
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
86
|
+
) -> None:
|
|
87
|
+
monkeypatch.setattr(cli.shutil, "which", lambda name: f"/usr/bin/{name}")
|
|
88
|
+
monkeypatch.setattr(cli, "_detect_node_major_version", lambda node_path: 22)
|
|
89
|
+
monkeypatch.setattr(subprocess, "call", lambda command: 6)
|
|
90
|
+
|
|
91
|
+
assert cli.main(["release", "gate", "--json"]) == 6
|