conduct-cli 0.7.26__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.26 → conduct_cli-0.7.28}/PKG-INFO +1 -1
  2. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/pyproject.toml +1 -1
  3. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/guard.py +6 -2
  4. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/main.py +41 -2
  5. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/PKG-INFO +1 -1
  6. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/README.md +0 -0
  7. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/setup.cfg +0 -0
  8. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/setup.py +0 -0
  9. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/__init__.py +0 -0
  10. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/api.py +0 -0
  11. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/guardmcp.py +0 -0
  12. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/__init__.py +0 -0
  13. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/base.py +0 -0
  14. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/posttooluse.py +0 -0
  15. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/precompact.py +0 -0
  16. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/pretooluse.py +0 -0
  17. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/session_parser.py +0 -0
  18. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/session_report_push.py +0 -0
  19. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/session_start.py +0 -0
  20. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/hooks/stop.py +0 -0
  21. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/log_util.py +0 -0
  22. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/mcp_server.py +0 -0
  23. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/memory.py +0 -0
  24. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/paxel.py +0 -0
  25. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli/tool_groups.py +0 -0
  26. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/SOURCES.txt +0 -0
  27. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
  28. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/entry_points.txt +0 -0
  29. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/requires.txt +0 -0
  30. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/src/conduct_cli.egg-info/top_level.txt +0 -0
  31. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_advisory_and_hook.py +0 -0
  32. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_bash_operator_signature.py +0 -0
  33. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_blast_radius.py +0 -0
  34. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_command_word_matcher.py +0 -0
  35. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_drain_daemon_health.py +0 -0
  36. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_guard_policy.py +0 -0
  37. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_guard_savings.py +0 -0
  38. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_hook_dispatch.py +0 -0
  39. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_journal_drain.py +0 -0
  40. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_log_util.py +0 -0
  41. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_proxy_coverage.py +0 -0
  42. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_proxy_env.py +0 -0
  43. {conduct_cli-0.7.26 → conduct_cli-0.7.28}/tests/test_signed_policy.py +0 -0
  44. {conduct_cli-0.7.26 → 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.26
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.26"
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" }
@@ -1266,8 +1266,12 @@ def cmd_guard_sync(args):
1266
1266
  fresh_agent_token = installed.get("agent_token") or ""
1267
1267
  if fresh_agent_token:
1268
1268
  cfg["agent_token"] = fresh_agent_token
1269
- _save_guard_config(cfg)
1270
- else:
1269
+ if installed.get("user_email"):
1270
+ cfg["user_email"] = installed["user_email"]
1271
+ if installed.get("clerk_user_id"):
1272
+ cfg["clerk_user_id"] = installed["clerk_user_id"]
1273
+ _save_guard_config(cfg)
1274
+ if not fresh_agent_token:
1271
1275
  print(f" {YELLOW}Warning: server returned no token — proxy env may be stale{RESET}")
1272
1276
  except Exception as e:
1273
1277
  print(f" {YELLOW}Warning: could not refresh token ({e}) — using cached value{RESET}")
@@ -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.26
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