abrade-cli 0.3.0__tar.gz → 0.3.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.
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/PKG-INFO +2 -2
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/pyproject.toml +2 -2
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/pyproject.toml.orig +6 -2
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/cli.py +3 -1
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/upgrade.py +33 -9
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/README.md +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/__init__.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/action_ledger.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/agent_http.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/assertions.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/auth.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/baseline.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/bounded_http.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/canary.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/ci_trust.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/config.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/containment.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/corpus.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/data/__init__.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/data/sample_corpus.yaml +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/evaluator.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/execution.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/Archivo-Bold.ttf +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/IBMPlexMono-Regular.ttf +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/IBMPlexMono-SemiBold.ttf +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/Inter-Regular.ttf +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/Inter-SemiBold.ttf +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/LICENSE-fonts.txt +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/fonts/README.md +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/model_names.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/models.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/release_guard.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/report.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/report_theme.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/response_limits.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/run_contract.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/runner.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/safeio.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/sarif.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/storage.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/tos.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/upstream_errors.py +0 -0
- {abrade_cli-0.3.0 → abrade_cli-0.3.1}/src/abrade_cli/verify.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abrade-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Abrade's self-hosted CLI — run the injection suite on your own machine, results stay local, no SaaS account required.
|
|
5
5
|
Keywords: ai-agents,security-testing,prompt-injection,red-teaming,llm-security
|
|
6
6
|
Author: Abrade
|
|
@@ -14,7 +14,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Classifier: Topic :: Security
|
|
16
16
|
Classifier: Topic :: Software Development :: Testing
|
|
17
|
-
Requires-Dist: anthropic>=0.119.0
|
|
17
|
+
Requires-Dist: anthropic>=0.119.0,<1
|
|
18
18
|
Requires-Dist: fpdf2>=2.8.7
|
|
19
19
|
Requires-Dist: httpx>=0.28.1,<1
|
|
20
20
|
Requires-Dist: pydantic>=2.13.4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "abrade-cli"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.1"
|
|
4
4
|
description = "Abrade's self-hosted CLI — run the injection suite on your own machine, results stay local, no SaaS account required."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
@@ -23,7 +23,7 @@ classifiers = [
|
|
|
23
23
|
"Topic :: Software Development :: Testing",
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
|
-
"anthropic>=0.119.0",
|
|
26
|
+
"anthropic>=0.119.0,<1",
|
|
27
27
|
"fpdf2>=2.8.7",
|
|
28
28
|
"httpx>=0.28.1,<1",
|
|
29
29
|
"pydantic>=2.13.4",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "abrade-cli"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.1"
|
|
4
4
|
description = "Abrade's self-hosted CLI — run the injection suite on your own machine, results stay local, no SaaS account required."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
# The project, not a personal handle. PyPI renders this as "Author" on
|
|
@@ -40,7 +40,11 @@ classifiers = [
|
|
|
40
40
|
"Topic :: Software Development :: Testing",
|
|
41
41
|
]
|
|
42
42
|
dependencies = [
|
|
43
|
-
|
|
43
|
+
# Below 1 because we hand the SDK an httpx client, which is where the response
|
|
44
|
+
# budgets live, and anthropic 2 accepts only httpx2. pip resolves the newest this
|
|
45
|
+
# allows and never reads uv.lock, so without a cap 0.3.0 crashed on the default config
|
|
46
|
+
# for anyone installing it while passing everything run on the lock.
|
|
47
|
+
"anthropic>=0.119.0,<1",
|
|
44
48
|
"fpdf2>=2.8.7",
|
|
45
49
|
"httpx>=0.28.1,<1",
|
|
46
50
|
"pydantic>=2.13.4",
|
|
@@ -162,7 +162,9 @@ def upgrade(
|
|
|
162
162
|
f"[yellow]Update available:[/yellow] "
|
|
163
163
|
f"{release.installed} → [bold]{release.latest}[/bold]"
|
|
164
164
|
)
|
|
165
|
-
|
|
165
|
+
# Written out to be copied: a long path must not wrap, and a bracket is not markup.
|
|
166
|
+
command = escape(upgrade_module.install_command())
|
|
167
|
+
console.print(f"\n {command}\n", soft_wrap=True)
|
|
166
168
|
if check_only:
|
|
167
169
|
raise typer.Exit(code=1)
|
|
168
170
|
|
|
@@ -17,8 +17,11 @@ updated it and the new command still isn't there".
|
|
|
17
17
|
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
|
|
20
|
+
import importlib.util
|
|
20
21
|
import json
|
|
21
22
|
import os
|
|
23
|
+
import shlex
|
|
24
|
+
import subprocess
|
|
22
25
|
import sys
|
|
23
26
|
import urllib.error
|
|
24
27
|
import urllib.request
|
|
@@ -72,25 +75,46 @@ def latest_version(*, timeout: float = 10.0) -> str:
|
|
|
72
75
|
raise UpgradeCheckError("PyPI returned an unexpected response.") from exc
|
|
73
76
|
|
|
74
77
|
|
|
78
|
+
def _has_pip() -> bool:
|
|
79
|
+
return importlib.util.find_spec("pip") is not None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _quoted(path: str) -> str:
|
|
83
|
+
return subprocess.list2cmdline([path]) if os.name == "nt" else shlex.quote(path)
|
|
84
|
+
|
|
85
|
+
|
|
75
86
|
def install_command() -> str:
|
|
76
87
|
"""The upgrade command for whichever installer put this here.
|
|
77
88
|
|
|
78
89
|
Detected from the path of the running interpreter rather than asked
|
|
79
90
|
for, because the common failure is not knowing which manager was used
|
|
80
91
|
— and the answer is sitting in sys.executable.
|
|
81
|
-
"""
|
|
82
|
-
executable = Path(sys.executable).resolve()
|
|
83
|
-
parts = {p.lower() for p in executable.parts}
|
|
84
92
|
|
|
85
|
-
|
|
93
|
+
The path as it stands, never resolved. A venv's python is a symlink to the
|
|
94
|
+
interpreter it was made from, so following it leaves the one directory that
|
|
95
|
+
says who installed this.
|
|
96
|
+
"""
|
|
97
|
+
executable = Path(sys.executable)
|
|
98
|
+
ordered = [p.lower() for p in executable.parts]
|
|
99
|
+
parts = set(ordered)
|
|
100
|
+
uv_tool_dir = os.environ.get("UV_TOOL_DIR")
|
|
101
|
+
|
|
102
|
+
if (
|
|
103
|
+
("uv", "tools") in zip(ordered, ordered[1:], strict=False)
|
|
104
|
+
or "uv-tool" in parts
|
|
105
|
+
or (uv_tool_dir and executable.is_relative_to(uv_tool_dir))
|
|
106
|
+
):
|
|
86
107
|
return "uv tool upgrade abrade-cli"
|
|
87
108
|
if "pipx" in parts:
|
|
88
109
|
return "pipx upgrade abrade-cli"
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
110
|
+
# Aimed at this interpreter either way. A bare `pip` is whichever is first on PATH,
|
|
111
|
+
# and a bare `uv pip` whichever environment it finds from the working directory.
|
|
112
|
+
# Upgrading another copy succeeds and changes nothing about the one that asked.
|
|
113
|
+
python = _quoted(sys.executable)
|
|
114
|
+
if _has_pip():
|
|
115
|
+
return f"{python} -m pip install --upgrade abrade-cli"
|
|
116
|
+
# `uv venv` leaves pip out, so `-m pip` would only fail.
|
|
117
|
+
return f"uv pip install --python {python} --upgrade abrade-cli"
|
|
94
118
|
|
|
95
119
|
|
|
96
120
|
def check(installed: str, *, timeout: float = 10.0) -> Release:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|