conduct-cli 0.7.27__tar.gz → 0.7.28__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 (44) hide show
  1. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/PKG-INFO +1 -1
  2. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/pyproject.toml +1 -1
  3. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/main.py +41 -2
  4. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/PKG-INFO +1 -1
  5. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/README.md +0 -0
  6. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/setup.cfg +0 -0
  7. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/setup.py +0 -0
  8. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/__init__.py +0 -0
  9. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/api.py +0 -0
  10. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/guard.py +0 -0
  11. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/guardmcp.py +0 -0
  12. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/__init__.py +0 -0
  13. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/base.py +0 -0
  14. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/posttooluse.py +0 -0
  15. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/precompact.py +0 -0
  16. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/pretooluse.py +0 -0
  17. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/session_parser.py +0 -0
  18. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/session_report_push.py +0 -0
  19. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/session_start.py +0 -0
  20. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/hooks/stop.py +0 -0
  21. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/log_util.py +0 -0
  22. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/mcp_server.py +0 -0
  23. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/memory.py +0 -0
  24. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/paxel.py +0 -0
  25. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli/tool_groups.py +0 -0
  26. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/SOURCES.txt +0 -0
  27. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
  28. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/entry_points.txt +0 -0
  29. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/requires.txt +0 -0
  30. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/top_level.txt +0 -0
  31. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_advisory_and_hook.py +0 -0
  32. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_bash_operator_signature.py +0 -0
  33. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_blast_radius.py +0 -0
  34. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_command_word_matcher.py +0 -0
  35. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_drain_daemon_health.py +0 -0
  36. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_guard_policy.py +0 -0
  37. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_guard_savings.py +0 -0
  38. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_hook_dispatch.py +0 -0
  39. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_journal_drain.py +0 -0
  40. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_log_util.py +0 -0
  41. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_proxy_coverage.py +0 -0
  42. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_proxy_env.py +0 -0
  43. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_signed_policy.py +0 -0
  44. {conduct_cli-0.7.27 → conduct_cli-0.7.28}/tests/test_switch.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.7.27
3
+ Version: 0.7.28
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.27"
7
+ version = "0.7.28"
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,6 +6,7 @@ import os
6
6
  import subprocess
7
7
  import sys
8
8
  import time
9
+ import urllib.error
9
10
  import urllib.parse
10
11
  import urllib.request
11
12
  from pathlib import Path
@@ -426,6 +427,36 @@ def _find_free_port() -> int:
426
427
  return s.getsockname()[1]
427
428
 
428
429
 
430
+ def _exchange_clerk_token(api_url: str, clerk_token: str, workspace_id: str) -> dict:
431
+ """POST /token (RFC 8693) to exchange a Clerk JWT for cond_agt_* + cond_ref_*."""
432
+ _GRANT = "urn:ietf:params:oauth:grant-type:token-exchange"
433
+ _TYPE = "urn:ietf:params:oauth:token-type:jwt"
434
+ body = urllib.parse.urlencode({
435
+ "grant_type": _GRANT,
436
+ "subject_token": clerk_token,
437
+ "subject_token_type": _TYPE,
438
+ "resource": workspace_id,
439
+ }).encode()
440
+ req = urllib.request.Request(
441
+ f"{api_url}/token",
442
+ data=body,
443
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
444
+ method="POST",
445
+ )
446
+ try:
447
+ with urllib.request.urlopen(req, timeout=15) as r:
448
+ data = json.loads(r.read())
449
+ return {
450
+ "agent_token": data["access_token"],
451
+ "refresh_token": data.get("refresh_token", ""),
452
+ "workspace_id": data.get("workspace_id", workspace_id),
453
+ }
454
+ except urllib.error.HTTPError as e:
455
+ body_text = e.read().decode(errors="replace")
456
+ print(f"{RED}Token exchange failed ({e.code}): {body_text[:120]}{RESET}")
457
+ sys.exit(1)
458
+
459
+
429
460
  def _web_login_flow(api_url: str, web_url: str) -> dict:
430
461
  """Open browser → localhost callback → return {agent_token, refresh_token, workspace_id}."""
431
462
  import http.server
@@ -480,8 +511,16 @@ def _web_login_flow(api_url: str, web_url: str) -> dict:
480
511
 
481
512
  server.shutdown()
482
513
 
483
- if not result.get("agent_token") or not result.get("workspace_id"):
484
- print(f"{RED}Login failed — missing token in callback. Try again.{RESET}")
514
+ if not result.get("workspace_id"):
515
+ print(f"{RED}Login failed — missing workspace in callback. Try again.{RESET}")
516
+ sys.exit(1)
517
+
518
+ # RFC 8693: web page relays Clerk JWT; CLI exchanges it at POST /token
519
+ if result.get("clerk_token") and not result.get("agent_token"):
520
+ result = _exchange_clerk_token(api_url, result["clerk_token"], result["workspace_id"])
521
+
522
+ if not result.get("agent_token"):
523
+ print(f"{RED}Login failed — token exchange failed. Try again.{RESET}")
485
524
  sys.exit(1)
486
525
 
487
526
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.7.27
3
+ Version: 0.7.28
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