humanbound-cli 0.1.0__tar.gz → 0.3.0__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 (53) hide show
  1. {humanbound_cli-0.1.0/humanbound_cli.egg-info → humanbound_cli-0.3.0}/PKG-INFO +86 -27
  2. humanbound_cli-0.1.0/PKG-INFO → humanbound_cli-0.3.0/README.md +81 -51
  3. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/__init__.py +1 -1
  4. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/client.py +121 -5
  5. humanbound_cli-0.3.0/humanbound_cli/commands/__init__.py +27 -0
  6. humanbound_cli-0.3.0/humanbound_cli/commands/api_keys.py +225 -0
  7. humanbound_cli-0.3.0/humanbound_cli/commands/campaigns.py +174 -0
  8. humanbound_cli-0.3.0/humanbound_cli/commands/coverage.py +160 -0
  9. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/docs.py +24 -14
  10. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/experiments.py +138 -11
  11. humanbound_cli-0.3.0/humanbound_cli/commands/findings.py +177 -0
  12. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/init.py +159 -5
  13. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/logs.py +17 -9
  14. humanbound_cli-0.3.0/humanbound_cli/commands/members.py +179 -0
  15. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/posture.py +73 -1
  16. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/projects.py +96 -0
  17. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/test.py +45 -123
  18. humanbound_cli-0.3.0/humanbound_cli/commands/upload_logs.py +106 -0
  19. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/config.py +7 -1
  20. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/exceptions.py +18 -0
  21. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/main.py +33 -4
  22. humanbound_cli-0.3.0/humanbound_cli/report.py +719 -0
  23. humanbound_cli-0.3.0/humanbound_cli/serve/__init__.py +14 -0
  24. humanbound_cli-0.3.0/humanbound_cli/serve/config_builder.py +48 -0
  25. humanbound_cli-0.3.0/humanbound_cli/serve/local_server.py +206 -0
  26. humanbound_cli-0.3.0/humanbound_cli/serve/runtime_detector.py +421 -0
  27. humanbound_cli-0.3.0/humanbound_cli/serve/tunnel_client.py +236 -0
  28. humanbound_cli-0.1.0/README.md → humanbound_cli-0.3.0/humanbound_cli.egg-info/PKG-INFO +110 -24
  29. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli.egg-info/SOURCES.txt +13 -0
  30. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli.egg-info/requires.txt +3 -0
  31. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli.egg-info/top_level.txt +2 -0
  32. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/pyproject.toml +7 -4
  33. humanbound_cli-0.3.0/relay/relay.py +347 -0
  34. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/tests/cli_integration_test.py +427 -170
  35. humanbound_cli-0.1.0/humanbound_cli/commands/__init__.py +0 -17
  36. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/LICENSE +0 -0
  37. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/auth.py +0 -0
  38. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/guardrails.py +0 -0
  39. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/orgs.py +0 -0
  40. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/providers.py +0 -0
  41. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/commands/scan.py +0 -0
  42. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/extractors/__init__.py +0 -0
  43. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/extractors/openapi.py +0 -0
  44. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/extractors/repo.py +0 -0
  45. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/pytest_plugin/__init__.py +0 -0
  46. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/pytest_plugin/fixtures.py +0 -0
  47. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli/pytest_plugin/report.py +0 -0
  48. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli.egg-info/dependency_links.txt +0 -0
  49. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/humanbound_cli.egg-info/entry_points.txt +0 -0
  50. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/setup.cfg +0 -0
  51. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/tests/__init__.py +0 -0
  52. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/tests/conftest.py +0 -0
  53. {humanbound_cli-0.1.0 → humanbound_cli-0.3.0}/tests/test_cli_commands.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: humanbound-cli
3
- Version: 0.1.0
3
+ Version: 0.3.0
4
4
  Summary: Humanbound CLI - command line interface for AI agent security testing.
5
- Author-email: Kostas Siabanis <hello@humanbound.io>, Demetris Gerogiannis <hello@humanbound.io>
5
+ Author-email: Kostas Siabanis <hello@humanbound.ai>, Demetris Gerogiannis <hello@humanbound.ai>
6
6
  License: Apache-2.0
7
7
  Project-URL: Homepage, https://github.com/Humanbound/humanbound-cli
8
- Project-URL: Documentation, https://docs.humanbound.io/cli
8
+ Project-URL: Documentation, https://docs.humanbound.ai/cli
9
9
  Project-URL: Issues, https://github.com/Humanbound/humanbound-cli/issues
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: License :: OSI Approved :: Apache Software License
@@ -19,18 +19,21 @@ Requires-Dist: click>=8.1.0
19
19
  Requires-Dist: rich>=13.0.0
20
20
  Requires-Dist: requests>=2.32.0
21
21
  Requires-Dist: pyyaml>=6.0.0
22
+ Provides-Extra: serve
23
+ Requires-Dist: websockets>=12.0; extra == "serve"
22
24
  Provides-Extra: pytest
23
25
  Requires-Dist: pytest>=7.0.0; extra == "pytest"
24
26
  Provides-Extra: dev
25
27
  Requires-Dist: pytest>=7.0.0; extra == "dev"
26
28
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
27
29
 
28
- # Humanbound CLI (Beta)
30
+ # Humanbound CLI
29
31
 
30
32
  > CLI-first security testing for AI agents and chatbots. Adversarial attacks, behavioral QA, posture scoring, and guardrails export — from your terminal to your CI/CD pipeline.
31
33
 
32
34
  [![PyPI](https://img.shields.io/pypi/v/humanbound-cli)](https://pypi.org/project/humanbound-cli/)
33
35
  [![License](https://img.shields.io/badge/license-proprietary-blue)]()
36
+ [![Version](https://img.shields.io/badge/version-0.2.0-green)]()
34
37
 
35
38
  ```
36
39
  pip install humanbound-cli
@@ -113,7 +116,7 @@ hb test
113
116
  hb test -e ./bot-config.json
114
117
 
115
118
  # Choose test category and depth
116
- hb test -t owasp_multi_turn -l system
119
+ hb test -t humanbound/adversarial/owasp_multi_turn -l system
117
120
  ```
118
121
 
119
122
  ### 4. Review results
@@ -285,6 +288,8 @@ Providers are LLM configurations used for running security tests.
285
288
  | `projects use <id>` | Select project |
286
289
  | `projects current` | Show current project |
287
290
  | `projects show [id]` | Show project details |
291
+ | `projects update [id]` | Update project name/description |
292
+ | `projects delete [id]` | Delete project (with confirmation) |
288
293
 
289
294
  <details>
290
295
  <summary><code>init</code> — scan bot & create project</summary>
@@ -324,27 +329,15 @@ Testing Level:
324
329
  --testing-level, -l Depth of testing (default: unit)
325
330
  unit | system | acceptance
326
331
 
327
- Chat Endpoint (required):
328
- --chat-endpoint Chat completion URL of the bot to test
329
- --chat-header Header for chat endpoint (repeatable)
330
- --chat-payload JSON payload template for chat
331
-
332
- Init Endpoint (optional):
333
- --init-endpoint Thread initialization URL
334
- --init-header Header for init endpoint (repeatable)
335
- --init-payload JSON payload for init
336
-
337
- Auth Endpoint (optional):
338
- --auth-endpoint Auth/token endpoint URL
339
- --auth-header Header for auth endpoint (repeatable)
340
- --auth-payload JSON payload for auth
332
+ Endpoint Override (optional — only needed if no default integration):
333
+ -e, --endpoint Bot integration config JSON string or file path.
334
+ Same shape as 'hb init --endpoint'. Overrides default.
341
335
 
342
336
  Other:
343
337
  --provider-id Provider to use (default: first available)
344
338
  --name, -n Experiment name (auto-generated if omitted)
345
339
  --lang Language (default: english). Accepts codes: en, de, es...
346
340
  --adaptive Enable adaptive mode (evolutionary attack strategy)
347
- --streaming Enable streaming mode (requires wss:// endpoint)
348
341
  --no-auto-start Create without starting (manual mode)
349
342
  --wait, -w Wait for completion
350
343
  --fail-on SEVERITY Exit non-zero if findings >= severity
@@ -363,7 +356,8 @@ Other:
363
356
  | `experiments status <id> --watch` | Watch until completion |
364
357
  | `experiments wait <id>` | Wait with progressive backoff (30s -> 60s -> 120s -> 300s) |
365
358
  | `experiments logs <id>` | List experiment logs |
366
- | `experiments report <id>` | Download HTML report |
359
+ | `experiments terminate <id>` | Stop a running experiment |
360
+ | `experiments delete <id>` | Delete experiment (with confirmation) |
367
361
 
368
362
  `status` is also available as a top-level alias — without an ID it shows the most recent experiment:
369
363
 
@@ -371,14 +365,79 @@ Other:
371
365
  hb status [experiment_id] [--watch]
372
366
  ```
373
367
 
368
+ ### Findings
369
+
370
+ Track long-term security vulnerabilities across experiments.
371
+
372
+ | Command | Description |
373
+ |---------|-------------|
374
+ | `findings` | List findings (filterable by --status, --severity) |
375
+ | `findings update <id>` | Update finding status or severity |
376
+
377
+ Finding states: **open** → **stale** (30+ days unseen) → **fixed** (resolved). Findings can also **regress** (was fixed, reappeared).
378
+
379
+ ### Coverage
380
+
381
+ | Command | Description |
382
+ |---------|-------------|
383
+ | `coverage` | Test coverage summary |
384
+ | `coverage --gaps` | Include untested categories |
385
+
386
+ ### Campaigns
387
+
388
+ Continuous security assurance with automated campaign management (ASCAM).
389
+
390
+ | Command | Description |
391
+ |---------|-------------|
392
+ | `campaigns` | Show current campaign plan |
393
+ | `campaigns break` | Stop a running campaign |
394
+
395
+ ASCAM phases: Reconnaissance → Hardening → Red Teaming → Analysis → Monitoring
396
+
397
+ ### Upload Conversation Logs
398
+
399
+ Evaluate real production conversations against security judges.
400
+
401
+ | Command | Description |
402
+ |---------|-------------|
403
+ | `upload-logs <file>` | Upload JSON conversation logs |
404
+
405
+ Options: `--tag`, `--lang`
406
+
407
+ ### API Keys
408
+
409
+ | Command | Description |
410
+ |---------|-------------|
411
+ | `api-keys list` | List API keys |
412
+ | `api-keys create` | Create new key (--name required, --scopes: admin/write/read) |
413
+ | `api-keys update <id>` | Update key name, scopes, or active state |
414
+ | `api-keys revoke <id>` | Revoke (delete) an API key |
415
+
416
+ ### Members
417
+
418
+ | Command | Description |
419
+ |---------|-------------|
420
+ | `members list` | List organisation members |
421
+ | `members invite <email>` | Invite member (--role: admin/developer) |
422
+ | `members remove <id>` | Remove member |
423
+
374
424
  ### Results & Export
375
425
 
376
426
  ```bash
377
- # View experiment results (table, json, or csv)
378
- hb logs [experiment_id] [--format table] [--verdict pass|fail] [--page N] [--size N]
427
+ # View experiment results
428
+ hb logs [experiment_id] [--format table|json|html] [--verdict pass|fail] [--page N] [--size N]
429
+
430
+ # Export branded HTML report
431
+ hb logs <experiment_id> --format=html [-o report.html]
432
+
433
+ # Security posture
434
+ hb posture [--json] [--trends]
435
+
436
+ # Test coverage
437
+ hb coverage [--gaps] [--json]
379
438
 
380
- # Security posture score
381
- hb posture [--json]
439
+ # Findings
440
+ hb findings [--status open] [--severity high] [--json]
382
441
 
383
442
  # Export guardrails configuration
384
443
  hb guardrails [--vendor humanbound|openai] [--format json|yaml] [-o FILE]
@@ -406,7 +465,7 @@ hb switch abc123
406
465
  hb init -n "Support Bot" -e ./bot-config.json
407
466
 
408
467
  # Run adversarial test (uses project's default integration)
409
- hb test -t owasp_multi_turn -l unit
468
+ hb test -t humanbound/adversarial/owasp_multi_turn -l unit
410
469
 
411
470
  # Watch and review
412
471
  hb status --watch
@@ -494,5 +553,5 @@ hb login
494
553
 
495
554
  ## Links
496
555
 
497
- - [Documentation](https://docs.humanbound.io)
556
+ - [Documentation](https://docs.humanbound.ai)
498
557
  - [GitHub](https://github.com/Humanbound/humanbound-cli)
@@ -1,36 +1,10 @@
1
- Metadata-Version: 2.1
2
- Name: humanbound-cli
3
- Version: 0.1.0
4
- Summary: Humanbound CLI - command line interface for AI agent security testing.
5
- Author-email: Kostas Siabanis <hello@humanbound.io>, Demetris Gerogiannis <hello@humanbound.io>
6
- License: Apache-2.0
7
- Project-URL: Homepage, https://github.com/Humanbound/humanbound-cli
8
- Project-URL: Documentation, https://docs.humanbound.io/cli
9
- Project-URL: Issues, https://github.com/Humanbound/humanbound-cli/issues
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: License :: OSI Approved :: Apache Software License
12
- Classifier: Operating System :: OS Independent
13
- Classifier: Environment :: Console
14
- Classifier: Framework :: Pytest
15
- Requires-Python: >=3.10
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: click>=8.1.0
19
- Requires-Dist: rich>=13.0.0
20
- Requires-Dist: requests>=2.32.0
21
- Requires-Dist: pyyaml>=6.0.0
22
- Provides-Extra: pytest
23
- Requires-Dist: pytest>=7.0.0; extra == "pytest"
24
- Provides-Extra: dev
25
- Requires-Dist: pytest>=7.0.0; extra == "dev"
26
- Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
27
-
28
- # Humanbound CLI (Beta)
1
+ # Humanbound CLI
29
2
 
30
3
  > CLI-first security testing for AI agents and chatbots. Adversarial attacks, behavioral QA, posture scoring, and guardrails export — from your terminal to your CI/CD pipeline.
31
4
 
32
5
  [![PyPI](https://img.shields.io/pypi/v/humanbound-cli)](https://pypi.org/project/humanbound-cli/)
33
6
  [![License](https://img.shields.io/badge/license-proprietary-blue)]()
7
+ [![Version](https://img.shields.io/badge/version-0.2.0-green)]()
34
8
 
35
9
  ```
36
10
  pip install humanbound-cli
@@ -113,7 +87,7 @@ hb test
113
87
  hb test -e ./bot-config.json
114
88
 
115
89
  # Choose test category and depth
116
- hb test -t owasp_multi_turn -l system
90
+ hb test -t humanbound/adversarial/owasp_multi_turn -l system
117
91
  ```
118
92
 
119
93
  ### 4. Review results
@@ -285,6 +259,8 @@ Providers are LLM configurations used for running security tests.
285
259
  | `projects use <id>` | Select project |
286
260
  | `projects current` | Show current project |
287
261
  | `projects show [id]` | Show project details |
262
+ | `projects update [id]` | Update project name/description |
263
+ | `projects delete [id]` | Delete project (with confirmation) |
288
264
 
289
265
  <details>
290
266
  <summary><code>init</code> — scan bot & create project</summary>
@@ -324,27 +300,15 @@ Testing Level:
324
300
  --testing-level, -l Depth of testing (default: unit)
325
301
  unit | system | acceptance
326
302
 
327
- Chat Endpoint (required):
328
- --chat-endpoint Chat completion URL of the bot to test
329
- --chat-header Header for chat endpoint (repeatable)
330
- --chat-payload JSON payload template for chat
331
-
332
- Init Endpoint (optional):
333
- --init-endpoint Thread initialization URL
334
- --init-header Header for init endpoint (repeatable)
335
- --init-payload JSON payload for init
336
-
337
- Auth Endpoint (optional):
338
- --auth-endpoint Auth/token endpoint URL
339
- --auth-header Header for auth endpoint (repeatable)
340
- --auth-payload JSON payload for auth
303
+ Endpoint Override (optional — only needed if no default integration):
304
+ -e, --endpoint Bot integration config JSON string or file path.
305
+ Same shape as 'hb init --endpoint'. Overrides default.
341
306
 
342
307
  Other:
343
308
  --provider-id Provider to use (default: first available)
344
309
  --name, -n Experiment name (auto-generated if omitted)
345
310
  --lang Language (default: english). Accepts codes: en, de, es...
346
311
  --adaptive Enable adaptive mode (evolutionary attack strategy)
347
- --streaming Enable streaming mode (requires wss:// endpoint)
348
312
  --no-auto-start Create without starting (manual mode)
349
313
  --wait, -w Wait for completion
350
314
  --fail-on SEVERITY Exit non-zero if findings >= severity
@@ -363,7 +327,8 @@ Other:
363
327
  | `experiments status <id> --watch` | Watch until completion |
364
328
  | `experiments wait <id>` | Wait with progressive backoff (30s -> 60s -> 120s -> 300s) |
365
329
  | `experiments logs <id>` | List experiment logs |
366
- | `experiments report <id>` | Download HTML report |
330
+ | `experiments terminate <id>` | Stop a running experiment |
331
+ | `experiments delete <id>` | Delete experiment (with confirmation) |
367
332
 
368
333
  `status` is also available as a top-level alias — without an ID it shows the most recent experiment:
369
334
 
@@ -371,14 +336,79 @@ Other:
371
336
  hb status [experiment_id] [--watch]
372
337
  ```
373
338
 
339
+ ### Findings
340
+
341
+ Track long-term security vulnerabilities across experiments.
342
+
343
+ | Command | Description |
344
+ |---------|-------------|
345
+ | `findings` | List findings (filterable by --status, --severity) |
346
+ | `findings update <id>` | Update finding status or severity |
347
+
348
+ Finding states: **open** → **stale** (30+ days unseen) → **fixed** (resolved). Findings can also **regress** (was fixed, reappeared).
349
+
350
+ ### Coverage
351
+
352
+ | Command | Description |
353
+ |---------|-------------|
354
+ | `coverage` | Test coverage summary |
355
+ | `coverage --gaps` | Include untested categories |
356
+
357
+ ### Campaigns
358
+
359
+ Continuous security assurance with automated campaign management (ASCAM).
360
+
361
+ | Command | Description |
362
+ |---------|-------------|
363
+ | `campaigns` | Show current campaign plan |
364
+ | `campaigns break` | Stop a running campaign |
365
+
366
+ ASCAM phases: Reconnaissance → Hardening → Red Teaming → Analysis → Monitoring
367
+
368
+ ### Upload Conversation Logs
369
+
370
+ Evaluate real production conversations against security judges.
371
+
372
+ | Command | Description |
373
+ |---------|-------------|
374
+ | `upload-logs <file>` | Upload JSON conversation logs |
375
+
376
+ Options: `--tag`, `--lang`
377
+
378
+ ### API Keys
379
+
380
+ | Command | Description |
381
+ |---------|-------------|
382
+ | `api-keys list` | List API keys |
383
+ | `api-keys create` | Create new key (--name required, --scopes: admin/write/read) |
384
+ | `api-keys update <id>` | Update key name, scopes, or active state |
385
+ | `api-keys revoke <id>` | Revoke (delete) an API key |
386
+
387
+ ### Members
388
+
389
+ | Command | Description |
390
+ |---------|-------------|
391
+ | `members list` | List organisation members |
392
+ | `members invite <email>` | Invite member (--role: admin/developer) |
393
+ | `members remove <id>` | Remove member |
394
+
374
395
  ### Results & Export
375
396
 
376
397
  ```bash
377
- # View experiment results (table, json, or csv)
378
- hb logs [experiment_id] [--format table] [--verdict pass|fail] [--page N] [--size N]
398
+ # View experiment results
399
+ hb logs [experiment_id] [--format table|json|html] [--verdict pass|fail] [--page N] [--size N]
400
+
401
+ # Export branded HTML report
402
+ hb logs <experiment_id> --format=html [-o report.html]
403
+
404
+ # Security posture
405
+ hb posture [--json] [--trends]
406
+
407
+ # Test coverage
408
+ hb coverage [--gaps] [--json]
379
409
 
380
- # Security posture score
381
- hb posture [--json]
410
+ # Findings
411
+ hb findings [--status open] [--severity high] [--json]
382
412
 
383
413
  # Export guardrails configuration
384
414
  hb guardrails [--vendor humanbound|openai] [--format json|yaml] [-o FILE]
@@ -406,7 +436,7 @@ hb switch abc123
406
436
  hb init -n "Support Bot" -e ./bot-config.json
407
437
 
408
438
  # Run adversarial test (uses project's default integration)
409
- hb test -t owasp_multi_turn -l unit
439
+ hb test -t humanbound/adversarial/owasp_multi_turn -l unit
410
440
 
411
441
  # Watch and review
412
442
  hb status --watch
@@ -494,5 +524,5 @@ hb login
494
524
 
495
525
  ## Links
496
526
 
497
- - [Documentation](https://docs.humanbound.io)
527
+ - [Documentation](https://docs.humanbound.ai)
498
528
  - [GitHub](https://github.com/Humanbound/humanbound-cli)
@@ -1,3 +1,3 @@
1
1
  """Humanbound CLI - command line interface for AI agent security testing."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.0"
@@ -387,12 +387,9 @@ class HumanboundClient:
387
387
  return True
388
388
 
389
389
  def _exchange_for_api_token(self) -> None:
390
- """Exchange Auth0 token for AIandMe API session token."""
391
- # Always use production API for auth (token audience must match)
392
- auth_base_url = get_auth0_audience()
393
-
390
+ """Exchange Auth0 token for API session token."""
394
391
  response = requests.get(
395
- f"{auth_base_url}/auth",
392
+ f"{self.base_url}/auth",
396
393
  headers={"Authorization": f"Bearer {self._auth0_token}"},
397
394
  timeout=DEFAULT_TIMEOUT,
398
395
  )
@@ -870,6 +867,125 @@ class HumanboundClient:
870
867
  """
871
868
  self.delete(f"providers/{provider_id}")
872
869
 
870
+ # -------------------------------------------------------------------------
871
+ # Findings Methods
872
+ # -------------------------------------------------------------------------
873
+
874
+ def list_findings(self, project_id: str, status: Optional[str] = None, severity: Optional[str] = None, page: int = 1, size: int = 50) -> dict:
875
+ """List findings for a project."""
876
+ params = {"page": page, "size": size}
877
+ if status:
878
+ params["status"] = status
879
+ if severity:
880
+ params["severity"] = severity
881
+ return self.get(f"projects/{project_id}/findings", include_project=True, params=params)
882
+
883
+ def update_finding(self, project_id: str, finding_id: str, data: dict) -> dict:
884
+ """Update a finding."""
885
+ return self.put(f"projects/{project_id}/findings/{finding_id}", data=data)
886
+
887
+ # -------------------------------------------------------------------------
888
+ # Experiment Extensions
889
+ # -------------------------------------------------------------------------
890
+
891
+ def terminate_experiment(self, experiment_id: str) -> dict:
892
+ """Terminate a running experiment."""
893
+ return self.post(f"experiments/{experiment_id}/terminate", include_project=True)
894
+
895
+ def delete_experiment(self, experiment_id: str) -> Any:
896
+ """Delete an experiment."""
897
+ return self.delete(f"experiments/{experiment_id}", include_project=True)
898
+
899
+ # -------------------------------------------------------------------------
900
+ # Project Extensions
901
+ # -------------------------------------------------------------------------
902
+
903
+ def update_project(self, project_id: str, data: dict) -> dict:
904
+ """Update a project."""
905
+ return self.put(f"projects/{project_id}", data=data)
906
+
907
+ def delete_project(self, project_id: str) -> Any:
908
+ """Delete a project."""
909
+ return self.delete(f"projects/{project_id}")
910
+
911
+ # -------------------------------------------------------------------------
912
+ # API Key Methods
913
+ # -------------------------------------------------------------------------
914
+
915
+ def list_api_keys(self, page: int = 1, limit: int = 50) -> Any:
916
+ """List API keys."""
917
+ return self.get("api-keys", params={"page": page, "limit": limit}, include_org=False)
918
+
919
+ def create_api_key(self, name: str, scopes: str = "admin") -> dict:
920
+ """Create a new API key."""
921
+ return self.post("api-keys", data={"name": name, "scopes": scopes}, include_org=False)
922
+
923
+ def delete_api_key(self, key_id: str) -> Any:
924
+ """Delete an API key."""
925
+ return self.delete(f"api-keys/{key_id}", include_org=False)
926
+
927
+ def update_api_key(self, key_id: str, data: dict) -> dict:
928
+ """Update an API key."""
929
+ return self.put(f"api-keys/{key_id}", data=data, include_org=False)
930
+
931
+ # -------------------------------------------------------------------------
932
+ # Member Methods
933
+ # -------------------------------------------------------------------------
934
+
935
+ def list_members(self) -> Any:
936
+ """List organisation members."""
937
+ return self.get("members")
938
+
939
+ def invite_member(self, email: str, access_level: str) -> dict:
940
+ """Invite a member to the organisation."""
941
+ return self.post("members", data={"email": email, "access_level": access_level})
942
+
943
+ def remove_member(self, member_id: str) -> Any:
944
+ """Remove a member from the organisation."""
945
+ return self.delete(f"members/{member_id}")
946
+
947
+ # -------------------------------------------------------------------------
948
+ # Coverage Methods
949
+ # -------------------------------------------------------------------------
950
+
951
+ def get_coverage(self, project_id: str, include_gaps: bool = False) -> dict:
952
+ """Get test coverage for a project."""
953
+ params = {"include_gaps": "true"} if include_gaps else {}
954
+ return self.get(f"projects/{project_id}/coverage", params=params)
955
+
956
+ # -------------------------------------------------------------------------
957
+ # Posture Trends Methods
958
+ # -------------------------------------------------------------------------
959
+
960
+ def get_posture_trends(self, project_id: str) -> Any:
961
+ """Get posture trend history for a project."""
962
+ return self.get(f"projects/{project_id}/posture/trends")
963
+
964
+ # -------------------------------------------------------------------------
965
+ # Campaign Methods
966
+ # -------------------------------------------------------------------------
967
+
968
+ def get_campaign_plan(self, project_id: str) -> dict:
969
+ """Get the current campaign plan for a project."""
970
+ return self.get(f"projects/{project_id}/plan")
971
+
972
+ def break_campaign(self, project_id: str, campaign_id: str) -> dict:
973
+ """Break/stop a running campaign."""
974
+ return self.post(f"projects/{project_id}/plan/break", data={"campaign_id": campaign_id})
975
+
976
+ # -------------------------------------------------------------------------
977
+ # Upload Conversations Methods
978
+ # -------------------------------------------------------------------------
979
+
980
+ def upload_conversations(self, project_id: str, conversations: list, tag: Optional[str] = None, lang: Optional[str] = None) -> dict:
981
+ """Upload conversation logs for evaluation."""
982
+ data = {"conversations": conversations}
983
+ if tag:
984
+ data["tag"] = tag
985
+ if lang:
986
+ data["lang"] = lang
987
+ return self.post(f"projects/{project_id}/datasets/conversations", data=data, include_project=True)
988
+
873
989
 
874
990
  # Import ValidationError to this module
875
991
  from .exceptions import ValidationError
@@ -0,0 +1,27 @@
1
+ """CLI command modules."""
2
+
3
+ from . import (
4
+ auth, orgs, projects, experiments, init, test, logs, posture,
5
+ guardrails, docs, providers, findings, api_keys, members,
6
+ coverage, campaigns, upload_logs,
7
+ )
8
+
9
+ __all__ = [
10
+ "auth",
11
+ "orgs",
12
+ "projects",
13
+ "experiments",
14
+ "init",
15
+ "test",
16
+ "logs",
17
+ "posture",
18
+ "guardrails",
19
+ "docs",
20
+ "providers",
21
+ "findings",
22
+ "api_keys",
23
+ "members",
24
+ "coverage",
25
+ "campaigns",
26
+ "upload_logs",
27
+ ]