conduct-cli 0.7.33__tar.gz → 0.7.34__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.
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/PKG-INFO +1 -1
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/pyproject.toml +1 -1
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/api.py +18 -5
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/main.py +17 -6
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli.egg-info/PKG-INFO +1 -1
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/README.md +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/setup.cfg +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/setup.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/__init__.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/guard.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/guardmcp.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/__init__.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/base.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/posttooluse.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/precompact.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/pretooluse.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/session_parser.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/session_report_push.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/session_start.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/hooks/stop.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/log_util.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/mcp_server.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/memory.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/paxel.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli/tool_groups.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli.egg-info/SOURCES.txt +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli.egg-info/entry_points.txt +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli.egg-info/requires.txt +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/src/conduct_cli.egg-info/top_level.txt +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_advisory_and_hook.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_bash_operator_signature.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_blast_radius.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_command_word_matcher.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_drain_daemon_health.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_guard_policy.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_guard_savings.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_hook_dispatch.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_journal_drain.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_log_util.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_proxy_coverage.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_proxy_env.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_signed_policy.py +0 -0
- {conduct_cli-0.7.33 → conduct_cli-0.7.34}/tests/test_switch.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "conduct-cli"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.34"
|
|
8
8
|
description = "CLI for Conduct AI — secure, govern, install agents, manage projects, run tests"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -6,7 +6,20 @@ import urllib.error
|
|
|
6
6
|
|
|
7
7
|
RED = "\033[31m"
|
|
8
8
|
RESET = "\033[0m"
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
_HINTS = {
|
|
11
|
+
401: "run `conduct login` to re-authenticate",
|
|
12
|
+
403: "check your permissions or run `conduct login`",
|
|
13
|
+
404: "not found — check the agent name or run ID",
|
|
14
|
+
429: "rate limited — wait a moment and try again",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _friendly(code: int, detail: str) -> str:
|
|
19
|
+
hint = _HINTS.get(code)
|
|
20
|
+
if hint and hint.lower() not in detail.lower():
|
|
21
|
+
return f"{detail} — {hint}"
|
|
22
|
+
return detail
|
|
10
23
|
|
|
11
24
|
|
|
12
25
|
def headers(workspace_id: str, token=None, content_type="application/json", api_key=None) -> dict:
|
|
@@ -31,10 +44,10 @@ def req(method: str, url: str, hdrs: dict, body=None, timeout: int = 30) -> dict
|
|
|
31
44
|
detail = json.loads(raw).get("detail", raw)
|
|
32
45
|
except Exception:
|
|
33
46
|
detail = raw
|
|
34
|
-
print(f"{RED}
|
|
47
|
+
print(f"{RED}{_friendly(e.code, detail)}{RESET}")
|
|
35
48
|
sys.exit(1)
|
|
36
49
|
except (socket.timeout, TimeoutError):
|
|
37
|
-
print(f"{RED}Request timed out
|
|
50
|
+
print(f"{RED}Request timed out — check your network connection{RESET}")
|
|
38
51
|
sys.exit(1)
|
|
39
52
|
|
|
40
53
|
|
|
@@ -50,10 +63,10 @@ def req_text(method: str, url: str, hdrs: dict, body_text: str, timeout: int = 3
|
|
|
50
63
|
detail = json.loads(raw).get("detail", raw)
|
|
51
64
|
except Exception:
|
|
52
65
|
detail = raw
|
|
53
|
-
print(f"{RED}
|
|
66
|
+
print(f"{RED}{_friendly(e.code, detail)}{RESET}")
|
|
54
67
|
sys.exit(1)
|
|
55
68
|
except (socket.timeout, TimeoutError):
|
|
56
|
-
print(f"{RED}Request timed out
|
|
69
|
+
print(f"{RED}Request timed out — check your network connection{RESET}")
|
|
57
70
|
sys.exit(1)
|
|
58
71
|
|
|
59
72
|
|
|
@@ -161,10 +161,16 @@ def _stream_run(server: str, workflow_id: str, run_id: str, workspace_id: str, t
|
|
|
161
161
|
summary = payload.get("summary", payload.get("tool", ""))
|
|
162
162
|
print(f" · {summary}{RESET}")
|
|
163
163
|
elif kind == "guard_check":
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
n = payload.get("rules_checked", 0)
|
|
165
|
+
block_type = payload.get("block_type", "")
|
|
166
|
+
if payload.get("warnings"):
|
|
167
|
+
for w in payload["warnings"]:
|
|
168
|
+
print(f"{YELLOW} ⚠ [guard:{block_type}] {w.get('rule_id', '')}: {w.get('message', '')}{RESET}")
|
|
169
|
+
elif payload.get("audited"):
|
|
170
|
+
for a in payload["audited"]:
|
|
171
|
+
print(f"{BLUE} ● [guard:{block_type}] {a.get('rule_id', '')}: {a.get('message', '')}{RESET}")
|
|
172
|
+
else:
|
|
173
|
+
print(f"{GREEN} ✓ [guard:{block_type}] {n} rules checked — passed{RESET}")
|
|
168
174
|
elif kind == "run_completed":
|
|
169
175
|
print(f"{BOLD}{GREEN} ✓ done{RESET}")
|
|
170
176
|
elif kind == "run_failed":
|
|
@@ -458,7 +464,11 @@ def _exchange_clerk_token(api_url: str, clerk_token: str, workspace_id: str) ->
|
|
|
458
464
|
}
|
|
459
465
|
except urllib.error.HTTPError as e:
|
|
460
466
|
body_text = e.read().decode(errors="replace")
|
|
461
|
-
|
|
467
|
+
try:
|
|
468
|
+
detail = json.loads(body_text).get("detail", body_text)
|
|
469
|
+
except Exception:
|
|
470
|
+
detail = body_text[:120]
|
|
471
|
+
print(f"{RED}Login failed: {detail} — run `conduct login` to try again{RESET}")
|
|
462
472
|
sys.exit(1)
|
|
463
473
|
|
|
464
474
|
|
|
@@ -3020,7 +3030,8 @@ def cmd_skill(args):
|
|
|
3020
3030
|
msg = json.loads(body).get("detail", body)
|
|
3021
3031
|
except Exception:
|
|
3022
3032
|
msg = body
|
|
3023
|
-
|
|
3033
|
+
from conduct_cli.api import _friendly
|
|
3034
|
+
print(f"{RED}{_friendly(e.code, msg)}{RESET}")
|
|
3024
3035
|
sys.exit(1)
|
|
3025
3036
|
|
|
3026
3037
|
if skill_command == "list":
|
|
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
|
|
File without changes
|