Added executable root launcher for audita

This commit is contained in:
2026-04-21 10:19:39 -05:00
parent e10349302f
commit 8f6c721f06
7 changed files with 87 additions and 7 deletions

View File

@@ -17,7 +17,22 @@ Set an OpenRouter API key, then process a transcript with a glossary:
```sh
export OPENROUTER_API_KEY=...
uv run audia process transcript.json --glossary glossary.yaml --output corrected.json
uv run audita process transcript.json --glossary glossary.yaml --output corrected.json
```
From a checked-out repository, you can also use the root launcher:
```sh
./audita process transcript.json --glossary glossary.yaml --output corrected.json
```
For a system-wide command, install the source tree under `/usr/local/src/audita`, sync dependencies there, and symlink the root launcher into your `PATH`:
```sh
cd /usr/local/src/audita
uv sync --extra dev
ln -s /usr/local/src/audita/audita /usr/local/bin/audita
audita process transcript.json --glossary glossary.yaml --output corrected.json
```
Without `--output`, Audita writes the corrected transcript JSON to stdout and progress logs to stderr.

24
audita Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/env python3
import os
import shutil
import sys
from pathlib import Path
def main() -> int:
uv = shutil.which("uv")
if uv is None:
print(
"audita: error: uv is required to run this launcher. Install uv and run `uv sync` in the Audita project.",
file=sys.stderr,
)
return 1
project_root = Path(__file__).resolve().parent
command = [uv, "run", "--project", str(project_root), "python", "-m", "audita", *sys.argv[1:]]
os.execv(uv, command)
return 1
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -20,7 +20,7 @@ dev = [
]
[project.scripts]
audia = "audita.cli:main"
audita = "audita.cli:main"
[build-system]
requires = ["hatchling"]

View File

@@ -22,7 +22,7 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
def _build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(prog="audia")
parser = argparse.ArgumentParser(prog="audita")
subparsers = parser.add_subparsers(dest="command", required=True)
process = subparsers.add_parser("process", help="correct a transcript using a glossary")
@@ -65,6 +65,5 @@ def _process(args: argparse.Namespace) -> int:
sys.stdout.write(transcript_to_json(revised))
return 0
except AuditaError as exc:
print(f"audia: error: {exc}", file=sys.stderr)
print(f"audita: error: {exc}", file=sys.stderr)
return 1

View File

@@ -13,7 +13,7 @@ class InstructorLLMClient:
from openai import OpenAI
except ImportError as exc:
raise AuditaLLMError(
"The LLM dependencies are not installed. Run `uv sync` before using audia."
"The LLM dependencies are not installed. Run `uv sync` before using audita."
) from exc
self._instructor = instructor
@@ -42,4 +42,3 @@ def _normalize_openrouter_model(model: str) -> str:
if model.startswith(prefix):
return model[len(prefix) :]
return model

12
tests/test_cli.py Normal file
View File

@@ -0,0 +1,12 @@
import pytest
from audita.cli import main
def test_cli_help_uses_audita_program_name(capsys):
with pytest.raises(SystemExit) as exc:
main(["--help"])
assert exc.value.code == 0
assert capsys.readouterr().out.startswith("usage: audita ")

31
tests/test_launcher.py Normal file
View File

@@ -0,0 +1,31 @@
import os
import shutil
import subprocess
from pathlib import Path
import pytest
ROOT = Path(__file__).resolve().parents[1]
LAUNCHER = ROOT / "audita"
def test_root_launcher_exists_and_is_executable():
assert LAUNCHER.is_file()
assert os.access(LAUNCHER, os.X_OK)
def test_root_launcher_help_smoke():
if shutil.which("uv") is None:
pytest.skip("uv is not installed")
result = subprocess.run(
[str(LAUNCHER), "--help"],
cwd=ROOT,
text=True,
capture_output=True,
check=False,
)
assert result.returncode == 0
assert result.stdout.startswith("usage: audita ")