conduct-cli 0.4.33__tar.gz → 0.4.35__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.33
3
+ Version: 0.4.35
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "conduct-cli"
7
- version = "0.4.33"
7
+ version = "0.4.35"
8
8
  description = "CLI for Conduct AI — install agents, manage projects, run tests"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -1280,82 +1280,48 @@ def _build_state(issue: dict, repo_full_name: str) -> dict:
1280
1280
 
1281
1281
 
1282
1282
  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
1283
  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
1284
  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
1285
 
1303
- if not workflow_id:
1304
- workflow_id = api.find_or_create_workflow(server, name, json_h)
1305
- print(f" workflow: {workflow_id}")
1306
- print(f" pushing YAML… ", end="", flush=True)
1307
- api.req_text("PUT", f"{server}/workflows/{workflow_id}/yaml", yaml_h, raw_yaml)
1308
- print(f"{GREEN}ok{RESET}\n")
1309
-
1310
- if trigger_type == "github_issue_labeled":
1311
- repo = trigger_cfg.get("repo_allowlist", "")
1312
- label = trigger_cfg.get("label", "")
1286
+ # Parse --input key=value pairs into initial_state
1287
+ initial_state: dict = {}
1288
+ for kv in (args.input or []):
1289
+ if "=" not in kv:
1290
+ print(f"{RED}Bad --input format '{kv}' expected key=value{RESET}")
1291
+ sys.exit(1)
1292
+ k, v = kv.split("=", 1)
1293
+ initial_state[k] = v
1313
1294
 
1314
- print(f" Fetching issues from {repo} with label '{label}'…")
1315
- qs = urllib.parse.urlencode({"repo": repo, "label": label})
1316
- issues = api.req("GET", f"{server}/credentials/github/issues?{qs}", json_h)
1295
+ # Resolve agent by name
1296
+ target = args.agent
1297
+ workflows = api.req("GET", f"{server}/workflows", json_h)
1317
1298
 
1318
- if not issues:
1319
- print(f" No open issues found with label '{label}'.")
1320
- return
1299
+ # Filter by project if given
1300
+ if args.project:
1301
+ projects = api.req("GET", f"{server}/workspaces/{workspace_id}/projects", json_h)
1302
+ proj = next((p for p in projects if p["name"].lower() == args.project.lower()), None)
1303
+ if not proj:
1304
+ print(f"{RED}Project '{args.project}' not found.{RESET}")
1305
+ sys.exit(1)
1306
+ workflows = [w for w in workflows if w.get("project_id") == proj["id"]]
1321
1307
 
1322
- print(f" Found {len(issues)} issue(s)\n")
1323
-
1324
- passed = failed = 0
1325
- for issue in issues:
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()
1308
+ wf = next((w for w in workflows if w["name"].lower() == target.lower()), None)
1309
+ if not wf:
1310
+ print(f"{RED}Agent '{target}' not found. Run 'conduct agents' to list agents.{RESET}")
1311
+ sys.exit(1)
1350
1312
 
1351
- print(f"{BOLD} Summary: {passed} passed, {failed} failed{RESET}\n")
1313
+ workflow_id = wf["id"]
1314
+ print(f"\n{BOLD}▶ conduct run — {wf['name']}{RESET}")
1315
+ if initial_state:
1316
+ for k, v in initial_state.items():
1317
+ print(f" {GRAY}{k}={v}{RESET}")
1318
+ print()
1352
1319
 
1353
- else:
1354
- run = api.req("POST", f"{server}/workflows/{workflow_id}/runs", json_h, {
1355
- "triggered_by": "cli",
1356
- "initial_state": {},
1357
- })
1358
- _stream_run(server, workflow_id, run["id"], workspace_id, token)
1320
+ run = api.req("POST", f"{server}/workflows/{workflow_id}/runs", json_h, {
1321
+ "triggered_by": "cli",
1322
+ "initial_state": initial_state,
1323
+ })
1324
+ _stream_run(server, workflow_id, run["id"], workspace_id, token, api_key)
1359
1325
 
1360
1326
 
1361
1327
  # ── Entry point ───────────────────────────────────────────────────────────────
@@ -1458,8 +1424,10 @@ def main():
1458
1424
  help="Input value applied to all playbooks (repeatable)")
1459
1425
 
1460
1426
  # conduct run (existing)
1461
- run_p = sub.add_parser("run", help="Run a workflow from a YAML file")
1462
- run_p.add_argument("yaml", help="Path to workflow YAML")
1427
+ run_p = sub.add_parser("run", help="Run an installed agent by name")
1428
+ run_p.add_argument("agent", help="Agent name (e.g. 'security_autopilot_fix')")
1429
+ run_p.add_argument("--project", metavar="name", help="Narrow to a specific project")
1430
+ run_p.add_argument("--input", action="append", metavar="key=value", help="Runtime input (repeatable)")
1463
1431
 
1464
1432
  # conduct guard
1465
1433
  guard_p, _guard_sub = _guard.register_guard_parser(sub)
@@ -1487,7 +1455,8 @@ def main():
1487
1455
  elif args.command == "projects":
1488
1456
  cmd_projects(args)
1489
1457
  elif args.command == "create":
1490
- if getattr(args, "create_type", None) == "project":
1458
+ create_args = getattr(args, "create_args", None)
1459
+ if create_args:
1491
1460
  cmd_create(args)
1492
1461
  else:
1493
1462
  create_p.print_help()
@@ -1496,7 +1465,8 @@ def main():
1496
1465
  elif args.command == "install":
1497
1466
  cmd_install(args)
1498
1467
  elif args.command == "delete":
1499
- if getattr(args, "delete_type", None) == "project":
1468
+ delete_args = getattr(args, "delete_args", None)
1469
+ if delete_args:
1500
1470
  cmd_delete(args)
1501
1471
  else:
1502
1472
  delete_p.print_help()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: conduct-cli
3
- Version: 0.4.33
3
+ Version: 0.4.35
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
File without changes
File without changes
File without changes