squawkbox 0.1.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.
- squawkbox-0.1.0/PKG-INFO +45 -0
- squawkbox-0.1.0/README.md +28 -0
- squawkbox-0.1.0/pyproject.toml +31 -0
- squawkbox-0.1.0/setup.cfg +4 -0
- squawkbox-0.1.0/src/squawkbox/__init__.py +5 -0
- squawkbox-0.1.0/src/squawkbox/__main__.py +4 -0
- squawkbox-0.1.0/src/squawkbox/cli.py +59 -0
- squawkbox-0.1.0/src/squawkbox.egg-info/PKG-INFO +45 -0
- squawkbox-0.1.0/src/squawkbox.egg-info/SOURCES.txt +11 -0
- squawkbox-0.1.0/src/squawkbox.egg-info/dependency_links.txt +1 -0
- squawkbox-0.1.0/src/squawkbox.egg-info/entry_points.txt +2 -0
- squawkbox-0.1.0/src/squawkbox.egg-info/top_level.txt +1 -0
- squawkbox-0.1.0/tests/test_cli.py +46 -0
squawkbox-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: squawkbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Thin PyPI wrapper for the squawkbox Node CLI — the intercom for your AI agents.
|
|
5
|
+
Author: Ben Wiseman
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# squawkbox (PyPI wrapper)
|
|
19
|
+
|
|
20
|
+
**The intercom for your AI agents** — `pip`/`uvx` access to
|
|
21
|
+
[squawkbox](https://github.com/BenWiseman/squawkbox), a local MCP message broker
|
|
22
|
+
that lets parallel AI coding agents (Claude Code, Codex, and concurrent
|
|
23
|
+
sessions) coordinate instead of colliding.
|
|
24
|
+
|
|
25
|
+
This package is a thin wrapper around the Node CLI: it runs a local build if one
|
|
26
|
+
is present, otherwise falls back to `npx -y squawkbox`. The implementation,
|
|
27
|
+
docs, and demo live in the main repo.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install squawkbox # or: uvx squawkbox
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Use
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
squawkbox shim --runtime claude # wire into your MCP client (see the repo)
|
|
39
|
+
squawkbox daemon # run the broker standalone
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Full docs, the 60-second quickstart, and MCP config snippets:
|
|
43
|
+
**https://github.com/BenWiseman/squawkbox**
|
|
44
|
+
|
|
45
|
+
MIT.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# squawkbox (PyPI wrapper)
|
|
2
|
+
|
|
3
|
+
**The intercom for your AI agents** — `pip`/`uvx` access to
|
|
4
|
+
[squawkbox](https://github.com/BenWiseman/squawkbox), a local MCP message broker
|
|
5
|
+
that lets parallel AI coding agents (Claude Code, Codex, and concurrent
|
|
6
|
+
sessions) coordinate instead of colliding.
|
|
7
|
+
|
|
8
|
+
This package is a thin wrapper around the Node CLI: it runs a local build if one
|
|
9
|
+
is present, otherwise falls back to `npx -y squawkbox`. The implementation,
|
|
10
|
+
docs, and demo live in the main repo.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install squawkbox # or: uvx squawkbox
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Use
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
squawkbox shim --runtime claude # wire into your MCP client (see the repo)
|
|
22
|
+
squawkbox daemon # run the broker standalone
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Full docs, the 60-second quickstart, and MCP config snippets:
|
|
26
|
+
**https://github.com/BenWiseman/squawkbox**
|
|
27
|
+
|
|
28
|
+
MIT.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "squawkbox"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Thin PyPI wrapper for the squawkbox Node CLI — the intercom for your AI agents."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Ben Wiseman" }]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Environment :: Console",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Topic :: Software Development :: Build Tools",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.scripts]
|
|
25
|
+
squawkbox = "squawkbox.cli:main"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools]
|
|
28
|
+
package-dir = { "" = "src" }
|
|
29
|
+
|
|
30
|
+
[tool.setuptools.packages.find]
|
|
31
|
+
where = ["src"]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Iterable, Sequence
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
PACKAGE_NAME = "squawkbox"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _candidate_roots(start: Path) -> Iterable[Path]:
|
|
14
|
+
current = start.resolve()
|
|
15
|
+
if current.is_file():
|
|
16
|
+
current = current.parent
|
|
17
|
+
yield current
|
|
18
|
+
yield from current.parents
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def find_local_cli(search_root: Path | None = None) -> Path | None:
|
|
22
|
+
start = search_root or Path(__file__)
|
|
23
|
+
for root in _candidate_roots(start):
|
|
24
|
+
cli_path = root / "dist" / "cli.js"
|
|
25
|
+
if (root / "package.json").is_file() and cli_path.is_file():
|
|
26
|
+
return cli_path
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def resolve_command(search_root: Path | None = None) -> list[str]:
|
|
31
|
+
cli_path = find_local_cli(search_root)
|
|
32
|
+
if cli_path is not None:
|
|
33
|
+
node = shutil.which("node")
|
|
34
|
+
if node is None:
|
|
35
|
+
raise RuntimeError("node is required to run the local squawkbox CLI")
|
|
36
|
+
return [node, str(cli_path)]
|
|
37
|
+
return ["npx", "-y", PACKAGE_NAME]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def run(argv: Sequence[str] | None = None) -> int:
|
|
41
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
42
|
+
command = resolve_command()
|
|
43
|
+
try:
|
|
44
|
+
completed = subprocess.run([*command, *args], check=False)
|
|
45
|
+
except FileNotFoundError as exc:
|
|
46
|
+
executable = exc.filename or command[0]
|
|
47
|
+
sys.stderr.write(
|
|
48
|
+
f"squawkbox: required executable not found: {executable}\n",
|
|
49
|
+
)
|
|
50
|
+
return 1
|
|
51
|
+
return int(completed.returncode)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def main() -> int:
|
|
55
|
+
try:
|
|
56
|
+
return run()
|
|
57
|
+
except RuntimeError as exc:
|
|
58
|
+
sys.stderr.write(f"squawkbox: {exc}\n")
|
|
59
|
+
return 1
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: squawkbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Thin PyPI wrapper for the squawkbox Node CLI — the intercom for your AI agents.
|
|
5
|
+
Author: Ben Wiseman
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# squawkbox (PyPI wrapper)
|
|
19
|
+
|
|
20
|
+
**The intercom for your AI agents** — `pip`/`uvx` access to
|
|
21
|
+
[squawkbox](https://github.com/BenWiseman/squawkbox), a local MCP message broker
|
|
22
|
+
that lets parallel AI coding agents (Claude Code, Codex, and concurrent
|
|
23
|
+
sessions) coordinate instead of colliding.
|
|
24
|
+
|
|
25
|
+
This package is a thin wrapper around the Node CLI: it runs a local build if one
|
|
26
|
+
is present, otherwise falls back to `npx -y squawkbox`. The implementation,
|
|
27
|
+
docs, and demo live in the main repo.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install squawkbox # or: uvx squawkbox
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Use
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
squawkbox shim --runtime claude # wire into your MCP client (see the repo)
|
|
39
|
+
squawkbox daemon # run the broker standalone
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Full docs, the 60-second quickstart, and MCP config snippets:
|
|
43
|
+
**https://github.com/BenWiseman/squawkbox**
|
|
44
|
+
|
|
45
|
+
MIT.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/squawkbox/__init__.py
|
|
4
|
+
src/squawkbox/__main__.py
|
|
5
|
+
src/squawkbox/cli.py
|
|
6
|
+
src/squawkbox.egg-info/PKG-INFO
|
|
7
|
+
src/squawkbox.egg-info/SOURCES.txt
|
|
8
|
+
src/squawkbox.egg-info/dependency_links.txt
|
|
9
|
+
src/squawkbox.egg-info/entry_points.txt
|
|
10
|
+
src/squawkbox.egg-info/top_level.txt
|
|
11
|
+
tests/test_cli.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
squawkbox
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
6
|
+
import tempfile
|
|
7
|
+
import unittest
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
12
|
+
PYTHON_SRC = REPO_ROOT / "python" / "src"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SquawkboxWrapperTests(unittest.TestCase):
|
|
16
|
+
def test_module_help_shells_out_to_local_node_cli(self) -> None:
|
|
17
|
+
env = os.environ.copy()
|
|
18
|
+
env["PYTHONPATH"] = str(PYTHON_SRC)
|
|
19
|
+
|
|
20
|
+
result = subprocess.run(
|
|
21
|
+
[sys.executable, "-m", "squawkbox", "--help"],
|
|
22
|
+
cwd=REPO_ROOT,
|
|
23
|
+
env=env,
|
|
24
|
+
capture_output=True,
|
|
25
|
+
text=True,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
29
|
+
self.assertIn("squawkbox — the intercom for your AI agents", result.stdout)
|
|
30
|
+
self.assertIn("squawkbox daemon", result.stdout)
|
|
31
|
+
|
|
32
|
+
def test_resolve_command_falls_back_to_npx_when_local_cli_is_missing(self) -> None:
|
|
33
|
+
sys.path.insert(0, str(PYTHON_SRC))
|
|
34
|
+
try:
|
|
35
|
+
from squawkbox.cli import resolve_command
|
|
36
|
+
finally:
|
|
37
|
+
sys.path.pop(0)
|
|
38
|
+
|
|
39
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
40
|
+
command = resolve_command(search_root=Path(tmp))
|
|
41
|
+
|
|
42
|
+
self.assertEqual(command, ["npx", "-y", "squawkbox"])
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == "__main__":
|
|
46
|
+
unittest.main()
|