conduct-cli 0.7.8__tar.gz → 0.7.10__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.8 → conduct_cli-0.7.10}/PKG-INFO +1 -1
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/pyproject.toml +1 -1
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/guard.py +3 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/base.py +1 -1
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli.egg-info/PKG-INFO +1 -1
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_hook_dispatch.py +27 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/README.md +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/setup.cfg +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/setup.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/__init__.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/api.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/guardmcp.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/__init__.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/posttooluse.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/precompact.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/pretooluse.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/session_parser.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/session_report_push.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/session_start.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/hooks/stop.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/log_util.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/main.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/mcp_server.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/memory.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli/paxel.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli.egg-info/SOURCES.txt +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli.egg-info/entry_points.txt +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli.egg-info/requires.txt +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/src/conduct_cli.egg-info/top_level.txt +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_advisory_and_hook.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_bash_operator_signature.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_command_word_matcher.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_guard_policy.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_guard_savings.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_hook_syntax.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_journal_drain.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_log_util.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_proxy_env.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/tests/test_signed_policy.py +0 -0
- {conduct_cli-0.7.8 → conduct_cli-0.7.10}/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.10"
|
|
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" }
|
|
@@ -38,6 +38,9 @@ _THIN_LAUNCHERS = {
|
|
|
38
38
|
"if _cmd == 'post':\n"
|
|
39
39
|
" try:\n from conduct_cli.hooks.posttooluse import main; main()\n"
|
|
40
40
|
" except (ImportError, ModuleNotFoundError): sys.exit(0)\n"
|
|
41
|
+
"elif _cmd == 'drain':\n"
|
|
42
|
+
" try:\n from conduct_cli.hooks.base import run_drain_daemon; run_drain_daemon()\n"
|
|
43
|
+
" except (ImportError, ModuleNotFoundError): sys.exit(0)\n"
|
|
41
44
|
"else:\n"
|
|
42
45
|
" try:\n from conduct_cli.hooks.pretooluse import main; main()\n"
|
|
43
46
|
" except (ImportError, ModuleNotFoundError): sys.exit(0)\n"
|
|
@@ -227,7 +227,7 @@ def post_event(
|
|
|
227
227
|
"clerk_user_id": cfg.get("user_email"),
|
|
228
228
|
"user_email": cfg.get("user_email"),
|
|
229
229
|
"ai_tool": detect_ai_tool(),
|
|
230
|
-
"tool_call": tool_name,
|
|
230
|
+
"tool_call": tool_name[:255],
|
|
231
231
|
"input_summary": _safe_summary(tool_input),
|
|
232
232
|
"decision": decision,
|
|
233
233
|
"rule_id": rule_id,
|
|
@@ -41,6 +41,12 @@ def test_hook_py_dispatches_default_to_pretooluse():
|
|
|
41
41
|
assert "pretooluse" in content, "hook.py must route default to pretooluse"
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
def test_hook_py_dispatches_drain_to_run_drain_daemon():
|
|
45
|
+
content = _hook_py_content()
|
|
46
|
+
assert "drain" in content, "hook.py must branch on 'drain' arg"
|
|
47
|
+
assert "run_drain_daemon" in content, "hook.py must route 'drain' to run_drain_daemon"
|
|
48
|
+
|
|
49
|
+
|
|
44
50
|
def test_hook_py_is_valid_python():
|
|
45
51
|
import py_compile, tempfile, os
|
|
46
52
|
content = _hook_py_content()
|
|
@@ -166,6 +172,27 @@ def test_read_tokens_extracts_from_valid_transcript(tmp_path):
|
|
|
166
172
|
|
|
167
173
|
# ── 5. Journal payload structure ─────────────────────────────────────────────
|
|
168
174
|
|
|
175
|
+
def test_post_event_tool_call_fits_db_column(tmp_path):
|
|
176
|
+
"""tool_call in journal payload must not exceed 255 chars (DB column limit)."""
|
|
177
|
+
from conduct_cli.hooks import base
|
|
178
|
+
|
|
179
|
+
journal_dir = tmp_path / "journal"
|
|
180
|
+
cfg = {"workspace_id": "test-ws", "user_email": "x@x.com", "api_url": "https://api.conductai.ai"}
|
|
181
|
+
long_name = "mcp__" + "x" * 260 # deliberately over 255
|
|
182
|
+
|
|
183
|
+
with (
|
|
184
|
+
patch.object(base, "JOURNAL_DIR", journal_dir),
|
|
185
|
+
patch.object(base, "JOURNAL_PID_PATH", journal_dir / "drain.pid"),
|
|
186
|
+
patch.object(base, "load_config", return_value=cfg),
|
|
187
|
+
patch.object(base, "ensure_drain_daemon"),
|
|
188
|
+
):
|
|
189
|
+
base.post_event(long_name, {}, "allowed", session_id="s")
|
|
190
|
+
|
|
191
|
+
files = list(journal_dir.glob("*.json"))
|
|
192
|
+
payload = json.loads(json.loads(files[0].read_text())["payload"])
|
|
193
|
+
assert len(payload["tool_call"]) <= 255, "tool_call must be truncated to 255 chars"
|
|
194
|
+
|
|
195
|
+
|
|
169
196
|
def test_post_event_journal_payload_has_required_fields(tmp_path):
|
|
170
197
|
"""post_event must journal a payload with workspace_id and hook_session_id."""
|
|
171
198
|
from conduct_cli.hooks import base
|
|
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
|