conduct-cli 0.4.34__tar.gz → 0.4.36__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.
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/PKG-INFO +1 -1
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/pyproject.toml +1 -1
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli/main.py +44 -72
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli.egg-info/PKG-INFO +1 -1
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/README.md +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/setup.cfg +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/setup.py +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli/__init__.py +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli/api.py +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli/guard.py +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli/guardmcp.py +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli/mcp_server.py +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli.egg-info/SOURCES.txt +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli.egg-info/dependency_links.txt +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli.egg-info/entry_points.txt +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli.egg-info/requires.txt +0 -0
- {conduct_cli-0.4.34 → conduct_cli-0.4.36}/src/conduct_cli.egg-info/top_level.txt +0 -0
|
@@ -1084,8 +1084,12 @@ def cmd_install(args):
|
|
|
1084
1084
|
proj = _resolve_project(server, workspace_id, hdrs, args.project)
|
|
1085
1085
|
project_id = proj["id"]
|
|
1086
1086
|
|
|
1087
|
-
# Agent name —
|
|
1088
|
-
|
|
1087
|
+
# Agent name — explicit --name wins; otherwise auto-suffix with 4-char ID
|
|
1088
|
+
# e.g. "Security Autopilot Fix [A4B2]" so multiple installs are distinguishable
|
|
1089
|
+
import random, string
|
|
1090
|
+
_base = _FRIENDLY_NAMES.get(slug) or pb["name"]
|
|
1091
|
+
_uid = "".join(random.choices(string.ascii_uppercase + string.digits, k=4))
|
|
1092
|
+
agent_name = args.name or f"{_base} [{_uid}]"
|
|
1089
1093
|
|
|
1090
1094
|
# Repo input — inject into inputs if playbook expects github_repo
|
|
1091
1095
|
if args.repo:
|
|
@@ -1280,82 +1284,48 @@ def _build_state(issue: dict, repo_full_name: str) -> dict:
|
|
|
1280
1284
|
|
|
1281
1285
|
|
|
1282
1286
|
def cmd_run(args):
|
|
1283
|
-
path = Path(args.yaml)
|
|
1284
|
-
if not path.exists():
|
|
1285
|
-
print(f"ERROR: file not found: {path}")
|
|
1286
|
-
sys.exit(1)
|
|
1287
|
-
|
|
1288
|
-
raw_yaml = path.read_text()
|
|
1289
|
-
cfg = yaml.safe_load(raw_yaml)
|
|
1290
|
-
name = cfg.get("name", path.stem)
|
|
1291
|
-
workflow_id = cfg.get("id")
|
|
1292
1287
|
server, workspace_id, api_key, token = _require_auth(args)
|
|
1293
|
-
on_block = cfg.get("on") or {}
|
|
1294
|
-
trigger_type = next(iter(on_block), None)
|
|
1295
|
-
trigger_cfg = on_block.get(trigger_type, {})
|
|
1296
|
-
|
|
1297
1288
|
json_h = api.headers(workspace_id, token, "application/json", api_key)
|
|
1298
|
-
yaml_h = api.headers(workspace_id, token, "application/x-yaml", api_key)
|
|
1299
|
-
|
|
1300
|
-
print(f"\n{BOLD}▶ conduct run — {name}{RESET}")
|
|
1301
|
-
print(f" server: {server}\n")
|
|
1302
1289
|
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
repo = trigger_cfg.get("repo_allowlist", "")
|
|
1312
|
-
label = trigger_cfg.get("label", "")
|
|
1290
|
+
# Parse --input key=value pairs into initial_state
|
|
1291
|
+
initial_state: dict = {}
|
|
1292
|
+
for kv in (args.input or []):
|
|
1293
|
+
if "=" not in kv:
|
|
1294
|
+
print(f"{RED}Bad --input format '{kv}' — expected key=value{RESET}")
|
|
1295
|
+
sys.exit(1)
|
|
1296
|
+
k, v = kv.split("=", 1)
|
|
1297
|
+
initial_state[k] = v
|
|
1313
1298
|
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1299
|
+
# Resolve agent by name
|
|
1300
|
+
target = args.agent
|
|
1301
|
+
workflows = api.req("GET", f"{server}/workflows", json_h)
|
|
1317
1302
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1303
|
+
# Filter by project if given
|
|
1304
|
+
if args.project:
|
|
1305
|
+
projects = api.req("GET", f"{server}/workspaces/{workspace_id}/projects", json_h)
|
|
1306
|
+
proj = next((p for p in projects if p["name"].lower() == args.project.lower()), None)
|
|
1307
|
+
if not proj:
|
|
1308
|
+
print(f"{RED}Project '{args.project}' not found.{RESET}")
|
|
1309
|
+
sys.exit(1)
|
|
1310
|
+
workflows = [w for w in workflows if w.get("project_id") == proj["id"]]
|
|
1321
1311
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
print(f"{CYAN} ── Issue #{issue['number']}: {issue['title']}{RESET}")
|
|
1327
|
-
state = _build_state(issue, repo)
|
|
1328
|
-
|
|
1329
|
-
max_turns = None
|
|
1330
|
-
try:
|
|
1331
|
-
pf = api.req("POST", f"{server}/workflows/{workflow_id}/preflight", json_h, {
|
|
1332
|
-
"issue_title": issue["title"],
|
|
1333
|
-
"issue_body": issue.get("body") or "",
|
|
1334
|
-
})
|
|
1335
|
-
suggested = pf.get("suggested_max_turns", 20)
|
|
1336
|
-
if suggested > 20:
|
|
1337
|
-
print(f"{GRAY} ⚠ estimated {suggested} turns — bumping max_turns{RESET}")
|
|
1338
|
-
max_turns = suggested
|
|
1339
|
-
except Exception:
|
|
1340
|
-
pass
|
|
1341
|
-
|
|
1342
|
-
payload = {"triggered_by": f"cli:issue#{issue['number']}", "initial_state": state}
|
|
1343
|
-
if max_turns:
|
|
1344
|
-
payload["max_turns"] = max_turns
|
|
1345
|
-
run = api.req("POST", f"{server}/workflows/{workflow_id}/runs", json_h, payload)
|
|
1346
|
-
ok = _stream_run(server, workflow_id, run["id"], workspace_id, token, api_key)
|
|
1347
|
-
passed += ok
|
|
1348
|
-
failed += not ok
|
|
1349
|
-
print()
|
|
1312
|
+
wf = next((w for w in workflows if w["name"].lower() == target.lower()), None)
|
|
1313
|
+
if not wf:
|
|
1314
|
+
print(f"{RED}Agent '{target}' not found. Run 'conduct agents' to list agents.{RESET}")
|
|
1315
|
+
sys.exit(1)
|
|
1350
1316
|
|
|
1351
|
-
|
|
1317
|
+
workflow_id = wf["id"]
|
|
1318
|
+
print(f"\n{BOLD}▶ conduct run — {wf['name']}{RESET}")
|
|
1319
|
+
if initial_state:
|
|
1320
|
+
for k, v in initial_state.items():
|
|
1321
|
+
print(f" {GRAY}{k}={v}{RESET}")
|
|
1322
|
+
print()
|
|
1352
1323
|
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
_stream_run(server, workflow_id, run["id"], workspace_id, token)
|
|
1324
|
+
run = api.req("POST", f"{server}/workflows/{workflow_id}/runs", json_h, {
|
|
1325
|
+
"triggered_by": "cli",
|
|
1326
|
+
"initial_state": initial_state,
|
|
1327
|
+
})
|
|
1328
|
+
_stream_run(server, workflow_id, run["id"], workspace_id, token, api_key)
|
|
1359
1329
|
|
|
1360
1330
|
|
|
1361
1331
|
# ── Entry point ───────────────────────────────────────────────────────────────
|
|
@@ -1458,8 +1428,10 @@ def main():
|
|
|
1458
1428
|
help="Input value applied to all playbooks (repeatable)")
|
|
1459
1429
|
|
|
1460
1430
|
# conduct run (existing)
|
|
1461
|
-
run_p = sub.add_parser("run", help="Run
|
|
1462
|
-
run_p.add_argument("
|
|
1431
|
+
run_p = sub.add_parser("run", help="Run an installed agent by name")
|
|
1432
|
+
run_p.add_argument("agent", help="Agent name (e.g. 'security_autopilot_fix')")
|
|
1433
|
+
run_p.add_argument("--project", metavar="name", help="Narrow to a specific project")
|
|
1434
|
+
run_p.add_argument("--input", action="append", metavar="key=value", help="Runtime input (repeatable)")
|
|
1463
1435
|
|
|
1464
1436
|
# conduct guard
|
|
1465
1437
|
guard_p, _guard_sub = _guard.register_guard_parser(sub)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|