conduct-cli 0.7.44__tar.gz → 0.7.45__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 (47) hide show
  1. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/PKG-INFO +1 -1
  2. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/pyproject.toml +1 -1
  3. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/guard.py +65 -12
  4. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli.egg-info/PKG-INFO +1 -1
  5. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/README.md +0 -0
  6. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/setup.cfg +0 -0
  7. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/setup.py +0 -0
  8. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/__init__.py +0 -0
  9. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/api.py +0 -0
  10. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/guardmcp.py +0 -0
  11. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/__init__.py +0 -0
  12. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/base.py +0 -0
  13. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/posttooluse.py +0 -0
  14. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/precompact.py +0 -0
  15. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/pretooluse.py +0 -0
  16. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/session_parser.py +0 -0
  17. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/session_report_push.py +0 -0
  18. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/session_start.py +0 -0
  19. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/hooks/stop.py +0 -0
  20. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/log_util.py +0 -0
  21. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/main.py +0 -0
  22. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/mcp_server.py +0 -0
  23. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/memory.py +0 -0
  24. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/paxel.py +0 -0
  25. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli/tool_groups.py +0 -0
  26. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli.egg-info/SOURCES.txt +0 -0
  27. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
  28. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli.egg-info/entry_points.txt +0 -0
  29. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli.egg-info/requires.txt +0 -0
  30. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/src/conduct_cli.egg-info/top_level.txt +0 -0
  31. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_advisory_and_hook.py +0 -0
  32. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_api_client.py +0 -0
  33. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_bash_operator_signature.py +0 -0
  34. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_blast_radius.py +0 -0
  35. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_cmd_run.py +0 -0
  36. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_command_word_matcher.py +0 -0
  37. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_drain_daemon_health.py +0 -0
  38. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_guard_policy.py +0 -0
  39. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_guard_savings.py +0 -0
  40. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_hook_dispatch.py +0 -0
  41. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_journal_drain.py +0 -0
  42. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_log_util.py +0 -0
  43. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_proxy_coverage.py +0 -0
  44. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_proxy_env.py +0 -0
  45. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_signed_policy.py +0 -0
  46. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/tests/test_switch.py +0 -0
  47. {conduct_cli-0.7.44 → conduct_cli-0.7.45}/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.7.44
3
+ Version: 0.7.45
4
4
  Summary: CLI for Conduct AI — secure, govern, install agents, manage projects, run tests
5
5
  Author-email: Conduct AI <hello@conductai.ai>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "conduct-cli"
7
- version = "0.7.44"
7
+ version = "0.7.45"
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" }
@@ -388,7 +388,7 @@ _MCP_TARGETS = [
388
388
  ]
389
389
 
390
390
 
391
- def _register_mcp(workspace_id: str, agent_token: str, api_url: str) -> None:
391
+ def _register_mcp(workspace_id: str, agent_token: str, api_url: str, dry_run: bool = False) -> None:
392
392
  """Write conductguard + agent-booster MCP entries into every AI tool config found.
393
393
 
394
394
  Credentials are NOT stored in the MCP config — the server reads them from
@@ -441,7 +441,7 @@ def _register_mcp(workspace_id: str, agent_token: str, api_url: str) -> None:
441
441
 
442
442
  # Cursor global rules — write Guard policies as user rules so they apply across all projects.
443
443
  _patch_cursor_global_rules()
444
- _patch_tool_instruction_files(agent_token, api_url)
444
+ _patch_tool_instruction_files(agent_token, api_url, dry_run=dry_run)
445
445
 
446
446
 
447
447
  def _patch_claude_desktop_proxy(api_url: str, agent_token: str) -> None:
@@ -542,7 +542,7 @@ def _patch_cursor_global_rules() -> None:
542
542
  print(f" {GREEN}Cursor global rules updated with ConductGuard policy{RESET}")
543
543
 
544
544
 
545
- def _patch_tool_instruction_files(agent_token: str, api_url: str) -> None:
545
+ def _patch_tool_instruction_files(agent_token: str, api_url: str, dry_run: bool = False) -> None:
546
546
  """Write ConductGuard policy block into instruction files for all AI tools.
547
547
 
548
548
  Targets:
@@ -597,19 +597,64 @@ def _patch_tool_instruction_files(agent_token: str, api_url: str) -> None:
597
597
  path = repo_path if (repo_path and repo_path.exists()) else global_path
598
598
  if not path.exists() and repo_path:
599
599
  path = repo_path
600
- path.parent.mkdir(parents=True, exist_ok=True)
601
600
  existing = path.read_text() if path.exists() else ""
602
601
  if MARKER_START in existing:
603
602
  updated = pattern.sub(guard_block, existing)
604
- if updated == existing:
605
- print(f" {GRAY}{label} already up to date{RESET}")
603
+ if dry_run:
604
+ if updated == existing:
605
+ print(f" [dry-run] No change: {path}")
606
+ else:
607
+ print(f" [dry-run] Would write: {path}")
606
608
  else:
607
- path.write_text(updated)
608
- print(f" {GREEN}{label} updated{RESET}")
609
+ path.parent.mkdir(parents=True, exist_ok=True)
610
+ if updated == existing:
611
+ print(f" {GRAY}{label} already up to date{RESET}")
612
+ else:
613
+ path.write_text(updated)
614
+ print(f" {GREEN}{label} updated{RESET}")
609
615
  else:
610
- sep = "\n\n" if existing.strip() else ""
611
- path.write_text((existing.rstrip() + sep + guard_block + "\n").lstrip())
612
- print(f" {GREEN}{label} ConductGuard block added{RESET}")
616
+ new_content = (existing.rstrip() + ("\n\n" if existing.strip() else "") + guard_block + "\n").lstrip()
617
+ if dry_run:
618
+ if new_content == existing:
619
+ print(f" [dry-run] No change: {path}")
620
+ else:
621
+ print(f" [dry-run] Would write: {path}")
622
+ else:
623
+ path.parent.mkdir(parents=True, exist_ok=True)
624
+ path.write_text(new_content)
625
+ print(f" {GREEN}{label} — ConductGuard block added{RESET}")
626
+
627
+
628
+ def _reset_tool_instruction_files() -> None:
629
+ """Remove ConductGuard blocks from all instruction files."""
630
+ import re as _re
631
+ MARKER_RE = _re.compile(
632
+ r"\n?<!-- ConductGuard -->\n.*?<!-- /ConductGuard -->\n?",
633
+ _re.DOTALL,
634
+ )
635
+ targets = [
636
+ Path.home() / "CLAUDE.md",
637
+ Path.cwd() / "CLAUDE.md",
638
+ Path.cwd() / ".github" / "copilot-instructions.md",
639
+ Path.cwd() / "AGENTS.md",
640
+ Path.cwd() / ".cursorrules",
641
+ Path.cwd() / ".windsurfrules",
642
+ ]
643
+ removed = 0
644
+ for p in targets:
645
+ if not p.exists():
646
+ continue
647
+ original = p.read_text(encoding="utf-8")
648
+ cleaned = MARKER_RE.sub("", original).strip()
649
+ if cleaned != original.strip():
650
+ p.write_text(cleaned + "\n", encoding="utf-8")
651
+ print(f" {GREEN}Removed ConductGuard block: {p}{RESET}")
652
+ removed += 1
653
+ else:
654
+ print(f" {YELLOW}No ConductGuard block found: {p}{RESET}")
655
+ if removed == 0:
656
+ print(" No ConductGuard blocks found in any instruction files.")
657
+
613
658
 
614
659
  def _install_codex_hook(hook_path: Path) -> None:
615
660
  """Register PreToolUse and PostToolUse hooks in ~/.codex/hooks.json."""
@@ -1319,6 +1364,12 @@ def cmd_guard_sync(args):
1319
1364
  # Persona selection — prompt once, skip if already chosen
1320
1365
 
1321
1366
  dry_run = getattr(args, "dry_run", False)
1367
+
1368
+ if getattr(args, "reset_instructions", False):
1369
+ print("Removing ConductGuard blocks from instruction files…")
1370
+ _reset_tool_instruction_files()
1371
+ return
1372
+
1322
1373
  print(f"{'[dry-run] ' if dry_run else ''}Syncing policy…")
1323
1374
  _check_and_upgrade_packages()
1324
1375
 
@@ -1463,7 +1514,7 @@ def cmd_guard_sync(args):
1463
1514
  _install_claude_hook(hook_path)
1464
1515
  _install_codex_hook(hook_path)
1465
1516
  cfg2 = _load_guard_config()
1466
- _register_mcp(workspace_id, cfg2.get("agent_token", ""), base_url)
1517
+ _register_mcp(workspace_id, cfg2.get("agent_token", ""), base_url, dry_run=dry_run)
1467
1518
  try:
1468
1519
  _install_session_hooks()
1469
1520
  except Exception:
@@ -2176,6 +2227,8 @@ def register_guard_parser(sub):
2176
2227
  sync_p = guard_sub.add_parser("sync", help="Refresh policy and re-scan for AI tools")
2177
2228
  sync_p.add_argument("--cursor", action="store_true", help="Write active Guard policies to .cursorrules")
2178
2229
  sync_p.add_argument("--dry-run", action="store_true", help="Preview policy changes without writing anything")
2230
+ sync_p.add_argument("--reset-instructions", action="store_true", dest="reset_instructions",
2231
+ help="Remove ConductGuard blocks from all instruction files")
2179
2232
  sync_p.add_argument("--proxy-url", default=None,
2180
2233
  help="Override the Guard proxy URL (default: https://api.conductai.ai/proxy/anthropic)")
2181
2234
  sync_p.add_argument("--no-local-audit", action="store_true",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.7.44
3
+ Version: 0.7.45
4
4
  Summary: CLI for Conduct AI — secure, govern, install agents, manage projects, run tests
5
5
  Author-email: Conduct AI <hello@conductai.ai>
6
6
  License: MIT
File without changes
File without changes
File without changes