conduct-cli 0.14.4__tar.gz → 0.14.5__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.
Files changed (59) hide show
  1. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/PKG-INFO +1 -1
  2. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/pyproject.toml +1 -1
  3. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/posttooluse.py +14 -0
  4. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/session_start.py +7 -4
  5. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli.egg-info/PKG-INFO +1 -1
  6. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli.egg-info/SOURCES.txt +1 -0
  7. conduct_cli-0.14.5/tests/test_session_start.py +40 -0
  8. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/LICENSE +0 -0
  9. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/README.md +0 -0
  10. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/setup.cfg +0 -0
  11. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/setup.py +0 -0
  12. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/__init__.py +0 -0
  13. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/api.py +0 -0
  14. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/guard.py +0 -0
  15. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/guard_policy.md +0 -0
  16. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/__init__.py +0 -0
  17. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/base.py +0 -0
  18. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/precompact.py +0 -0
  19. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/pretooluse.py +0 -0
  20. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/session_parser.py +0 -0
  21. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/session_report_push.py +0 -0
  22. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/hooks/stop.py +0 -0
  23. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/log_util.py +0 -0
  24. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/main.py +0 -0
  25. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/memory.py +0 -0
  26. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/paxel.py +0 -0
  27. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli/tool_groups.py +0 -0
  28. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
  29. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli.egg-info/entry_points.txt +0 -0
  30. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli.egg-info/requires.txt +0 -0
  31. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/src/conduct_cli.egg-info/top_level.txt +0 -0
  32. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_advisory_and_hook.py +0 -0
  33. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_api_client.py +0 -0
  34. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_bash_operator_signature.py +0 -0
  35. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_bash_scan_target.py +0 -0
  36. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_blast_radius.py +0 -0
  37. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_cli_matrix.py +0 -0
  38. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_cmd_run.py +0 -0
  39. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_command_word_matcher.py +0 -0
  40. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_drain_daemon_health.py +0 -0
  41. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_guard_approvals.py +0 -0
  42. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_guard_policy.py +0 -0
  43. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_guard_savings.py +0 -0
  44. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_guard_status.py +0 -0
  45. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_hook_dispatch.py +0 -0
  46. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_hook_journal.py +0 -0
  47. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_hook_receipt.py +0 -0
  48. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_install_all.py +0 -0
  49. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_instruction_files.py +0 -0
  50. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_journal_drain.py +0 -0
  51. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_log_util.py +0 -0
  52. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_pretooluse_approval_e2e.py +0 -0
  53. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_pretooluse_check_policy.py +0 -0
  54. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_proxy_coverage.py +0 -0
  55. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_proxy_env.py +0 -0
  56. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_report_tool_coverage.py +0 -0
  57. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_signed_policy.py +0 -0
  58. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_switch.py +0 -0
  59. {conduct_cli-0.14.4 → conduct_cli-0.14.5}/tests/test_token_lifecycle.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.14.4
3
+ Version: 0.14.5
4
4
  Summary: Runtime governance for AI agents. CLI for Conduct AI — secure, govern, install agents, manage projects, run tests
5
5
  Author-email: Conduct AI <hello@conductai.ai>
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "conduct-cli"
7
- version = "0.14.4"
7
+ version = "0.14.5"
8
8
  description = "Runtime governance for AI agents. CLI for Conduct AI — secure, govern, install agents, manage projects, run tests"
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -301,6 +301,20 @@ def main() -> None:
301
301
  if action == "warn" and session_id and rule_id:
302
302
  _record_session_warn(session_id, rule_id)
303
303
  post_event(tool_name, {}, decision, rule_id, message, session_id, drain_via=_this_file, blast_radius=blast_radius)
304
+ elif session_id:
305
+ # Some Codex clients omit transcript_path. Still send the PostToolUse
306
+ # update so the pre-tool audit row is correlated and execution status
307
+ # is visible; token backfill can remain unavailable for this call.
308
+ _post_usage(
309
+ session_id,
310
+ tool_name or "unknown",
311
+ 0,
312
+ 0,
313
+ None,
314
+ blast_radius,
315
+ execution_status,
316
+ result_summary,
317
+ )
304
318
 
305
319
  sys.exit(0)
306
320
 
@@ -2,6 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import json
5
+ import re
5
6
  import sys
6
7
  from datetime import datetime, timezone
7
8
  from pathlib import Path
@@ -18,6 +19,11 @@ from conduct_cli.hooks.base import (
18
19
 
19
20
  MAX_AGE_HOURS = 2
20
21
 
22
+ _PROXY_TOKEN_RE = re.compile(
23
+ r"^\s*(?:export\s+)?ANTHROPIC_API_KEY\s*=\s*['\"]?(?:cond_agt_|guard-mt-)[A-Za-z0-9_-]+['\"]?\s*$",
24
+ re.MULTILINE,
25
+ )
26
+
21
27
 
22
28
  def _check_proxy_token() -> None:
23
29
  """Warn + alert server if the proxy token is missing, malformed, or expired.
@@ -31,10 +37,7 @@ def _check_proxy_token() -> None:
31
37
  return
32
38
  env_text = CONDUCT_ENV_PATH.read_text()
33
39
  has_base_url = "ANTHROPIC_BASE_URL=" in env_text
34
- has_valid_token = (
35
- 'ANTHROPIC_API_KEY="guard-mt-' in env_text
36
- or "ANTHROPIC_API_KEY='guard-mt-" in env_text
37
- )
40
+ has_valid_token = bool(_PROXY_TOKEN_RE.search(env_text))
38
41
  if not has_base_url:
39
42
  return
40
43
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.14.4
3
+ Version: 0.14.5
4
4
  Summary: Runtime governance for AI agents. CLI for Conduct AI — secure, govern, install agents, manage projects, run tests
5
5
  Author-email: Conduct AI <hello@conductai.ai>
6
6
  License: Apache-2.0
@@ -51,6 +51,7 @@ tests/test_pretooluse_check_policy.py
51
51
  tests/test_proxy_coverage.py
52
52
  tests/test_proxy_env.py
53
53
  tests/test_report_tool_coverage.py
54
+ tests/test_session_start.py
54
55
  tests/test_signed_policy.py
55
56
  tests/test_switch.py
56
57
  tests/test_token_lifecycle.py
@@ -0,0 +1,40 @@
1
+ from datetime import datetime, timedelta, timezone
2
+
3
+ import pytest
4
+
5
+ from conduct_cli.hooks import session_start
6
+
7
+
8
+ @pytest.mark.parametrize("token", ["cond_agt_current-token", "guard-mt-legacy-token"])
9
+ def test_proxy_token_check_accepts_current_and_legacy_tokens(tmp_path, monkeypatch, capsys, token):
10
+ env_path = tmp_path / "env"
11
+ env_path.write_text(
12
+ "export ANTHROPIC_BASE_URL=\"https://api.conductai.ai/gateway/v1/anthropic\"\n"
13
+ f"export ANTHROPIC_API_KEY=\"{token}\"\n"
14
+ )
15
+ monkeypatch.setattr(session_start, "CONDUCT_ENV_PATH", env_path)
16
+ monkeypatch.setattr(
17
+ session_start,
18
+ "load_config",
19
+ lambda: {"token_expires_at": (datetime.now(timezone.utc) + timedelta(hours=1)).isoformat()},
20
+ )
21
+ monkeypatch.setattr(session_start, "post_event", lambda *args, **kwargs: pytest.fail("unexpected warning"))
22
+
23
+ session_start._check_proxy_token()
24
+
25
+ assert "missing or malformed" not in capsys.readouterr().out
26
+
27
+
28
+ def test_proxy_token_check_warns_for_malformed_token(tmp_path, monkeypatch, capsys):
29
+ env_path = tmp_path / "env"
30
+ env_path.write_text(
31
+ "export ANTHROPIC_BASE_URL=\"https://api.conductai.ai/gateway/v1/anthropic\"\n"
32
+ "export ANTHROPIC_API_KEY=\"not-a-conduct-token\"\n"
33
+ )
34
+ monkeypatch.setattr(session_start, "CONDUCT_ENV_PATH", env_path)
35
+ monkeypatch.setattr(session_start, "load_config", lambda: {})
36
+ monkeypatch.setattr(session_start, "post_event", lambda *args, **kwargs: None)
37
+
38
+ session_start._check_proxy_token()
39
+
40
+ assert "proxy token missing or malformed" in capsys.readouterr().out
File without changes
File without changes
File without changes
File without changes