conduct-cli 0.4.23__tar.gz → 0.4.24__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.4.23
3
+ Version: 0.4.24
4
4
  Summary: CLI for Conduct AI — install agents, manage projects, run tests
5
5
  Author-email: Conduct AI <hello@conductai.ai>
6
6
  License: MIT
@@ -110,13 +110,14 @@ ConductGuard is AI tool fleet management — your security team sets policies on
110
110
  ### How it works
111
111
 
112
112
  ```
113
- Manager installs Guard (conductai.ai/settings/modules)
114
- └─ generates an invite code
113
+ Admin configures policies and budgets in the Guard dashboard
114
+ └─ developers are workspace members automatically — no invite step needed
115
115
 
116
- Developer runs: conduct guard join <invite-code>
117
- ├─ downloads team policy to ~/.conductguard/policy.json
118
- ├─ writes PreToolUse hook → ~/.claude/settings.json
119
- └─ registers conductguard-mcp → ~/.claude/settings.json (mcpServers)
116
+ Developer runs: conduct guard sync
117
+ ├─ pulls latest policy to ~/.conductguard/policy.json
118
+ ├─ writes PreToolUse hook → ~/.conductguard/hook.py
119
+ ├─ registers hook → ~/.claude/settings.json
120
+ └─ registers conductguard-mcp → ~/.claude/settings.json (mcpServers) + Codex
120
121
 
121
122
  Every Claude Code tool call:
122
123
  ├─ PreToolUse hook fires (hook.py) → checks policy → block / warn / audit
@@ -126,10 +127,13 @@ Every Claude Code tool call:
126
127
  ### Developer setup
127
128
 
128
129
  ```bash
129
- # Get the invite code from your manager (Settings → Modules → ConductGuard)
130
- conduct guard join <invite-code>
130
+ pip install conduct-cli
131
+
132
+ # Authenticate (already done if you use Conduct)
133
+ conduct login --server https://api.conductai.ai --api-key <api-key>
131
134
 
132
- # Enter your email when prompted you'll be connected immediately
135
+ # Sync Guard installs hook + MCP, pulls policies
136
+ conduct guard sync
133
137
  ```
134
138
 
135
139
  That's it. Policy enforcement is active from the next tool call.
@@ -138,14 +142,13 @@ That's it. Policy enforcement is active from the next tool call.
138
142
 
139
143
  | Command | Description |
140
144
  |---------|-------------|
141
- | `conduct guard join <code>` | Join a team, download policy, register hook + MCP |
142
- | `conduct guard sync` | Pull latest policy from server (run after security team updates rules) |
145
+ | `conduct guard sync` | Pull latest policy, write hook to `~/.conductguard/hook.py`, register hook + MCP |
143
146
  | `conduct guard status` | Show today's spend, session count, and violations |
144
147
  | `conduct guard audit [--since 7d]` | Print recent guard events in a table |
145
148
 
146
149
  ### How the PreToolUse hook works
147
150
 
148
- When you run `conduct guard join`, the CLI writes a Python script to `~/.conductguard/hook.py` and registers it as a `PreToolUse` hook in `~/.claude/settings.json`:
151
+ When you run `conduct guard sync`, the CLI writes a Python script to `~/.conductguard/hook.py` and registers it as a `PreToolUse` hook in `~/.claude/settings.json`:
149
152
 
150
153
  ```json
151
154
  {
@@ -173,7 +176,7 @@ Before every tool call, Claude Code runs the hook. The hook:
173
176
 
174
177
  ### How conductguard-mcp works
175
178
 
176
- `conduct guard join` also registers an MCP server entry in `~/.claude/settings.json`:
179
+ `conduct guard sync` also registers an MCP server entry in `~/.claude/settings.json`:
177
180
 
178
181
  ```json
179
182
  {
@@ -244,7 +247,7 @@ Policy is stored at `~/.conductguard/policy.json` and synced from the server:
244
247
 
245
248
  ### Keeping policy up to date
246
249
 
247
- Policy is written to disk at `join` time. Run `conduct guard sync` after your security team updates rules in the ConductGuard dashboard. The sync command also re-registers the MCP entry in any newly detected AI tool configs.
250
+ Run `conduct guard sync` after your security team updates rules in the ConductGuard dashboard. The sync command pulls the latest policy, rewrites the hook, and re-registers the MCP entry in any newly detected AI tool configs.
248
251
 
249
252
  ```bash
250
253
  # Add to a daily cron or run manually after policy changes
@@ -86,13 +86,14 @@ ConductGuard is AI tool fleet management — your security team sets policies on
86
86
  ### How it works
87
87
 
88
88
  ```
89
- Manager installs Guard (conductai.ai/settings/modules)
90
- └─ generates an invite code
89
+ Admin configures policies and budgets in the Guard dashboard
90
+ └─ developers are workspace members automatically — no invite step needed
91
91
 
92
- Developer runs: conduct guard join <invite-code>
93
- ├─ downloads team policy to ~/.conductguard/policy.json
94
- ├─ writes PreToolUse hook → ~/.claude/settings.json
95
- └─ registers conductguard-mcp → ~/.claude/settings.json (mcpServers)
92
+ Developer runs: conduct guard sync
93
+ ├─ pulls latest policy to ~/.conductguard/policy.json
94
+ ├─ writes PreToolUse hook → ~/.conductguard/hook.py
95
+ ├─ registers hook → ~/.claude/settings.json
96
+ └─ registers conductguard-mcp → ~/.claude/settings.json (mcpServers) + Codex
96
97
 
97
98
  Every Claude Code tool call:
98
99
  ├─ PreToolUse hook fires (hook.py) → checks policy → block / warn / audit
@@ -102,10 +103,13 @@ Every Claude Code tool call:
102
103
  ### Developer setup
103
104
 
104
105
  ```bash
105
- # Get the invite code from your manager (Settings → Modules → ConductGuard)
106
- conduct guard join <invite-code>
106
+ pip install conduct-cli
107
+
108
+ # Authenticate (already done if you use Conduct)
109
+ conduct login --server https://api.conductai.ai --api-key <api-key>
107
110
 
108
- # Enter your email when prompted you'll be connected immediately
111
+ # Sync Guard installs hook + MCP, pulls policies
112
+ conduct guard sync
109
113
  ```
110
114
 
111
115
  That's it. Policy enforcement is active from the next tool call.
@@ -114,14 +118,13 @@ That's it. Policy enforcement is active from the next tool call.
114
118
 
115
119
  | Command | Description |
116
120
  |---------|-------------|
117
- | `conduct guard join <code>` | Join a team, download policy, register hook + MCP |
118
- | `conduct guard sync` | Pull latest policy from server (run after security team updates rules) |
121
+ | `conduct guard sync` | Pull latest policy, write hook to `~/.conductguard/hook.py`, register hook + MCP |
119
122
  | `conduct guard status` | Show today's spend, session count, and violations |
120
123
  | `conduct guard audit [--since 7d]` | Print recent guard events in a table |
121
124
 
122
125
  ### How the PreToolUse hook works
123
126
 
124
- When you run `conduct guard join`, the CLI writes a Python script to `~/.conductguard/hook.py` and registers it as a `PreToolUse` hook in `~/.claude/settings.json`:
127
+ When you run `conduct guard sync`, the CLI writes a Python script to `~/.conductguard/hook.py` and registers it as a `PreToolUse` hook in `~/.claude/settings.json`:
125
128
 
126
129
  ```json
127
130
  {
@@ -149,7 +152,7 @@ Before every tool call, Claude Code runs the hook. The hook:
149
152
 
150
153
  ### How conductguard-mcp works
151
154
 
152
- `conduct guard join` also registers an MCP server entry in `~/.claude/settings.json`:
155
+ `conduct guard sync` also registers an MCP server entry in `~/.claude/settings.json`:
153
156
 
154
157
  ```json
155
158
  {
@@ -220,7 +223,7 @@ Policy is stored at `~/.conductguard/policy.json` and synced from the server:
220
223
 
221
224
  ### Keeping policy up to date
222
225
 
223
- Policy is written to disk at `join` time. Run `conduct guard sync` after your security team updates rules in the ConductGuard dashboard. The sync command also re-registers the MCP entry in any newly detected AI tool configs.
226
+ Run `conduct guard sync` after your security team updates rules in the ConductGuard dashboard. The sync command pulls the latest policy, rewrites the hook, and re-registers the MCP entry in any newly detected AI tool configs.
224
227
 
225
228
  ```bash
226
229
  # Add to a daily cron or run manually after policy changes
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "conduct-cli"
7
- version = "0.4.23"
7
+ version = "0.4.24"
8
8
  description = "CLI for Conduct AI — install agents, manage projects, run tests"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -482,7 +482,7 @@ def _register_mcp(workspace_id: str, member_token: str, api_url: str) -> None:
482
482
  """Write conductguard MCP entry into every AI tool config found on this machine.
483
483
 
484
484
  Credentials are NOT stored in the MCP config — the server reads them from
485
- ~/.conductguard/config.json at startup, which is already written by guard join.
485
+ ~/.conductguard/config.json at startup, which is written by guard sync.
486
486
  """
487
487
  entry = {"command": "conductguard-mcp"}
488
488
  found_any = False
@@ -840,9 +840,90 @@ def cmd_guard_sync(args):
840
840
  _register_mcp(workspace_id, cfg2.get("member_token", ""), base_url)
841
841
  print(f" {GREEN}Hook script updated{RESET}")
842
842
 
843
+ # Capture savings from RTK and Agent Booster
844
+ _report_savings(cfg, base_url, api_key)
845
+
843
846
  print(f"\n{BOLD}Policy refreshed ({rule_count} rule(s)).{RESET}")
844
847
 
845
848
 
849
+ def _report_savings(cfg: dict, base_url: str, api_key: str) -> None:
850
+ import subprocess
851
+
852
+ rtk_data = {}
853
+ booster_data = {}
854
+
855
+ # Read RTK savings — rtk gain -f json nests under "summary" key
856
+ try:
857
+ r = subprocess.run(["rtk", "gain", "-f", "json"], capture_output=True, text=True, timeout=10)
858
+ if r.returncode == 0:
859
+ raw = json.loads(r.stdout)
860
+ summary = raw.get("summary", raw)
861
+ rtk_data = {
862
+ "saved_tokens": summary.get("total_saved", 0),
863
+ "savings_pct": summary.get("avg_savings_pct", 0.0),
864
+ "total_commands": summary.get("total_commands", 0),
865
+ }
866
+ except Exception:
867
+ pass
868
+
869
+ # Read Agent Booster savings
870
+ try:
871
+ r = subprocess.run(["booster", "gain", "-f", "json"], capture_output=True, text=True, timeout=10)
872
+ if r.returncode == 0:
873
+ raw = json.loads(r.stdout)
874
+ booster_data = {
875
+ "saved_tokens": raw.get("saved_tokens", 0),
876
+ "savings_pct": raw.get("savings_pct", 0.0),
877
+ "total_reads": raw.get("total_reads", 0),
878
+ }
879
+ except Exception:
880
+ pass
881
+
882
+ # If neither tool returned data, skip silently
883
+ if not rtk_data and not booster_data:
884
+ return
885
+
886
+ # Load baseline to compute period_start
887
+ baseline_path = GUARD_DIR / "savings_baseline.json"
888
+ period_start = None
889
+ try:
890
+ if baseline_path.exists():
891
+ baseline = json.loads(baseline_path.read_text())
892
+ period_start = baseline.get("recorded_at")
893
+ except Exception:
894
+ pass
895
+
896
+ now_iso = datetime.now(timezone.utc).isoformat()
897
+
898
+ payload = {
899
+ "workspace_id": cfg.get("workspace_id", ""),
900
+ "member_email": cfg.get("user_email", ""),
901
+ "rtk": rtk_data,
902
+ "booster": booster_data,
903
+ "period_start": period_start,
904
+ "period_end": now_iso,
905
+ }
906
+
907
+ try:
908
+ headers = {"Content-Type": "application/json"}
909
+ if api_key:
910
+ headers["X-Api-Key"] = api_key
911
+ data = json.dumps(payload).encode()
912
+ req = urllib.request.Request(
913
+ f"{base_url}/guard/savings",
914
+ data=data,
915
+ headers=headers,
916
+ method="POST",
917
+ )
918
+ with urllib.request.urlopen(req, timeout=15) as resp:
919
+ resp.read()
920
+ # Save baseline for next diff
921
+ baseline_path.write_text(json.dumps({"recorded_at": now_iso, "rtk": rtk_data, "booster": booster_data}))
922
+ print(f" {GREEN}Savings reported{RESET}")
923
+ except Exception:
924
+ pass # Never fail sync because savings POST failed
925
+
926
+
846
927
  def cmd_guard_status(args):
847
928
  cfg = _require_guard_config()
848
929
  workspace_id = cfg.get("workspace_id")
@@ -3,7 +3,7 @@
3
3
  conductguard-mcp — ConductGuard MCP server.
4
4
 
5
5
  Runs as a subprocess started by Claude Code / Cursor / Windsurf via the
6
- mcpServers config written by `conduct guard join`. Communicates over
6
+ mcpServers config written by `conduct guard sync`. Communicates over
7
7
  stdin/stdout using JSON-RPC 2.0 (MCP stdio transport).
8
8
 
9
9
  Exposes three tools:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.4.23
3
+ Version: 0.4.24
4
4
  Summary: CLI for Conduct AI — install agents, manage projects, run tests
5
5
  Author-email: Conduct AI <hello@conductai.ai>
6
6
  License: MIT
@@ -110,13 +110,14 @@ ConductGuard is AI tool fleet management — your security team sets policies on
110
110
  ### How it works
111
111
 
112
112
  ```
113
- Manager installs Guard (conductai.ai/settings/modules)
114
- └─ generates an invite code
113
+ Admin configures policies and budgets in the Guard dashboard
114
+ └─ developers are workspace members automatically — no invite step needed
115
115
 
116
- Developer runs: conduct guard join <invite-code>
117
- ├─ downloads team policy to ~/.conductguard/policy.json
118
- ├─ writes PreToolUse hook → ~/.claude/settings.json
119
- └─ registers conductguard-mcp → ~/.claude/settings.json (mcpServers)
116
+ Developer runs: conduct guard sync
117
+ ├─ pulls latest policy to ~/.conductguard/policy.json
118
+ ├─ writes PreToolUse hook → ~/.conductguard/hook.py
119
+ ├─ registers hook → ~/.claude/settings.json
120
+ └─ registers conductguard-mcp → ~/.claude/settings.json (mcpServers) + Codex
120
121
 
121
122
  Every Claude Code tool call:
122
123
  ├─ PreToolUse hook fires (hook.py) → checks policy → block / warn / audit
@@ -126,10 +127,13 @@ Every Claude Code tool call:
126
127
  ### Developer setup
127
128
 
128
129
  ```bash
129
- # Get the invite code from your manager (Settings → Modules → ConductGuard)
130
- conduct guard join <invite-code>
130
+ pip install conduct-cli
131
+
132
+ # Authenticate (already done if you use Conduct)
133
+ conduct login --server https://api.conductai.ai --api-key <api-key>
131
134
 
132
- # Enter your email when prompted you'll be connected immediately
135
+ # Sync Guard installs hook + MCP, pulls policies
136
+ conduct guard sync
133
137
  ```
134
138
 
135
139
  That's it. Policy enforcement is active from the next tool call.
@@ -138,14 +142,13 @@ That's it. Policy enforcement is active from the next tool call.
138
142
 
139
143
  | Command | Description |
140
144
  |---------|-------------|
141
- | `conduct guard join <code>` | Join a team, download policy, register hook + MCP |
142
- | `conduct guard sync` | Pull latest policy from server (run after security team updates rules) |
145
+ | `conduct guard sync` | Pull latest policy, write hook to `~/.conductguard/hook.py`, register hook + MCP |
143
146
  | `conduct guard status` | Show today's spend, session count, and violations |
144
147
  | `conduct guard audit [--since 7d]` | Print recent guard events in a table |
145
148
 
146
149
  ### How the PreToolUse hook works
147
150
 
148
- When you run `conduct guard join`, the CLI writes a Python script to `~/.conductguard/hook.py` and registers it as a `PreToolUse` hook in `~/.claude/settings.json`:
151
+ When you run `conduct guard sync`, the CLI writes a Python script to `~/.conductguard/hook.py` and registers it as a `PreToolUse` hook in `~/.claude/settings.json`:
149
152
 
150
153
  ```json
151
154
  {
@@ -173,7 +176,7 @@ Before every tool call, Claude Code runs the hook. The hook:
173
176
 
174
177
  ### How conductguard-mcp works
175
178
 
176
- `conduct guard join` also registers an MCP server entry in `~/.claude/settings.json`:
179
+ `conduct guard sync` also registers an MCP server entry in `~/.claude/settings.json`:
177
180
 
178
181
  ```json
179
182
  {
@@ -244,7 +247,7 @@ Policy is stored at `~/.conductguard/policy.json` and synced from the server:
244
247
 
245
248
  ### Keeping policy up to date
246
249
 
247
- Policy is written to disk at `join` time. Run `conduct guard sync` after your security team updates rules in the ConductGuard dashboard. The sync command also re-registers the MCP entry in any newly detected AI tool configs.
250
+ Run `conduct guard sync` after your security team updates rules in the ConductGuard dashboard. The sync command pulls the latest policy, rewrites the hook, and re-registers the MCP entry in any newly detected AI tool configs.
248
251
 
249
252
  ```bash
250
253
  # Add to a daily cron or run manually after policy changes
File without changes
File without changes