humanbound 2.0.2__tar.gz → 2.0.4__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 (113) hide show
  1. {humanbound-2.0.2 → humanbound-2.0.4}/PKG-INFO +13 -6
  2. {humanbound-2.0.2 → humanbound-2.0.4}/README.md +10 -4
  3. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound.egg-info/PKG-INFO +13 -6
  4. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound.egg-info/SOURCES.txt +4 -5
  5. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound.egg-info/requires.txt +2 -1
  6. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/client.py +11 -1
  7. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/__init__.py +0 -4
  8. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/api_keys.py +5 -0
  9. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/assessments.py +3 -0
  10. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/auth.py +3 -0
  11. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/campaigns.py +3 -0
  12. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/connect.py +53 -246
  13. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/experiments.py +8 -0
  14. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/findings.py +20 -2
  15. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/firewall.py +2 -0
  16. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/guardrails.py +2 -0
  17. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/logs.py +4 -0
  18. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/members.py +4 -0
  19. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/monitor.py +2 -0
  20. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/orgs.py +6 -0
  21. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/posture.py +17 -0
  22. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/projects.py +8 -0
  23. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/providers.py +5 -0
  24. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/redteam.py +2 -0
  25. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/report.py +2 -0
  26. humanbound-2.0.4/humanbound_cli/commands/telemetry.py +62 -0
  27. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/test.py +111 -43
  28. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/webhooks.py +8 -0
  29. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/config.py +19 -0
  30. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/presenter.py +0 -7
  31. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/runner.py +1 -1
  32. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/schemas.py +2 -8
  33. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/main.py +15 -2
  34. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/mcp_server.py +4 -8
  35. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/report.py +1 -1
  36. humanbound-2.0.4/humanbound_cli/telemetry/__init__.py +86 -0
  37. humanbound-2.0.4/humanbound_cli/telemetry/client.py +176 -0
  38. humanbound-2.0.4/humanbound_cli/telemetry/consent.py +140 -0
  39. {humanbound-2.0.2 → humanbound-2.0.4}/pyproject.toml +6 -3
  40. humanbound-2.0.2/humanbound_cli/commands/scan.py +0 -3
  41. humanbound-2.0.2/humanbound_cli/commands/sentinel.py +0 -1039
  42. humanbound-2.0.2/humanbound_cli/commands/upload_logs.py +0 -126
  43. humanbound-2.0.2/humanbound_cli/connectors/__init__.py +0 -3
  44. humanbound-2.0.2/humanbound_cli/connectors/microsoft.py +0 -1691
  45. {humanbound-2.0.2 → humanbound-2.0.4}/LICENSE +0 -0
  46. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/__init__.py +0 -0
  47. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/bot.py +0 -0
  48. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/callbacks.py +0 -0
  49. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/orchestrators.py +0 -0
  50. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/py.typed +0 -0
  51. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/runner.py +0 -0
  52. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound/schemas.py +0 -0
  53. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound.egg-info/dependency_links.txt +0 -0
  54. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound.egg-info/entry_points.txt +0 -0
  55. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound.egg-info/top_level.txt +0 -0
  56. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/__init__.py +0 -0
  57. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/adapters/__init__.py +0 -0
  58. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/adapters/promptfoo.py +0 -0
  59. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/adapters/pyrit.py +0 -0
  60. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/_report_helper.py +0 -0
  61. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/completion.py +0 -0
  62. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/config_cmd.py +0 -0
  63. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/docs.py +0 -0
  64. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/commands/mcp.py +0 -0
  65. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/__init__.py +0 -0
  66. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/bot.py +0 -0
  67. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/callbacks.py +0 -0
  68. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/compliance.py +0 -0
  69. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/__init__.py +0 -0
  70. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/azureopenai.py +0 -0
  71. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/claude.py +0 -0
  72. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/gemini.py +0 -0
  73. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/grok.py +0 -0
  74. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/ollama.py +0 -0
  75. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/llm/openai.py +0 -0
  76. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/local_runner.py +0 -0
  77. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/__init__.py +0 -0
  78. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/base.py +0 -0
  79. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/behavioral_qa/__init__.py +0 -0
  80. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/behavioral_qa/config.py +0 -0
  81. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/behavioral_qa/generator.py +0 -0
  82. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/behavioral_qa/judge.py +0 -0
  83. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/behavioral_qa/orchestrator.py +0 -0
  84. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_agentic/__init__.py +0 -0
  85. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_agentic/config.py +0 -0
  86. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_agentic/generator.py +0 -0
  87. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_agentic/judge.py +0 -0
  88. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_agentic/orchestrator.py +0 -0
  89. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_single_turn/__init__.py +0 -0
  90. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_single_turn/config.py +0 -0
  91. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_single_turn/generator.py +0 -0
  92. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_single_turn/judge.py +0 -0
  93. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/orchestrators/owasp_single_turn/orchestrator.py +0 -0
  94. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/platform_runner.py +0 -0
  95. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/engine/scope.py +0 -0
  96. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/exceptions.py +0 -0
  97. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/extractors/__init__.py +0 -0
  98. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/extractors/openapi.py +0 -0
  99. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/extractors/repo.py +0 -0
  100. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/py.typed +0 -0
  101. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/pytest_plugin/__init__.py +0 -0
  102. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/pytest_plugin/fixtures.py +0 -0
  103. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/pytest_plugin/report.py +0 -0
  104. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/report_builder.py +0 -0
  105. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/compliance/banking.yaml +0 -0
  106. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/compliance/ecommerce.yaml +0 -0
  107. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/compliance/eu-ai-act.yaml +0 -0
  108. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/compliance/healthcare.yaml +0 -0
  109. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/compliance/insurance.yaml +0 -0
  110. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/compliance/legal.yaml +0 -0
  111. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/logo.svg +0 -0
  112. {humanbound-2.0.2 → humanbound-2.0.4}/humanbound_cli/templates/report_base.html +0 -0
  113. {humanbound-2.0.2 → humanbound-2.0.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: humanbound
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: Humanbound — open-source AI agent red-team engine, SDK, and CLI.
5
5
  Author-email: Humanbound <hello@humanbound.ai>
6
6
  Maintainer-email: Demetris Gerogiannis <hello@humanbound.ai>, Kostas Siabanis <hello@humanbound.ai>
@@ -34,8 +34,8 @@ Requires-Dist: rich>=13.0.0
34
34
  Requires-Dist: requests>=2.32.0
35
35
  Requires-Dist: pyyaml>=6.0.0
36
36
  Requires-Dist: pydantic>=2.0
37
- Requires-Dist: msal>=1.31.0
38
37
  Requires-Dist: pyperclip>=1.8.0
38
+ Requires-Dist: posthog>=3.0
39
39
  Provides-Extra: engine
40
40
  Requires-Dist: openai>=1.0.0; extra == "engine"
41
41
  Requires-Dist: anthropic>=0.20.0; extra == "engine"
@@ -58,6 +58,7 @@ Requires-Dist: mypy>=1.11; extra == "dev"
58
58
  Requires-Dist: build>=1.2; extra == "dev"
59
59
  Requires-Dist: twine>=5.0; extra == "dev"
60
60
  Requires-Dist: pre-commit>=3.8; extra == "dev"
61
+ Requires-Dist: mkdocs>=1.6; extra == "dev"
61
62
  Dynamic: license-file
62
63
 
63
64
  <p align="center">
@@ -166,8 +167,9 @@ integration, and API reference all live on
166
167
  ## What's shipping in 2.0
167
168
 
168
169
  - **Clean name**: `humanbound` is the new PyPI install. The old
169
- `humanbound-cli` is a transitional stub that will be yanked after
170
- 2026-06-20.
170
+ `humanbound-cli` package is a discontinued transitional stub (final
171
+ release 1.2.2 depends on `humanbound>=2.0.2`); please install
172
+ `humanbound` directly.
171
173
  - **Public SDK namespace** alongside the CLI — use the CLI or drive the
172
174
  engine from Python. Both share the same implementation, so they can't
173
175
  drift.
@@ -187,6 +189,12 @@ loop, release process, and CLA requirement (see [CLA.md](./CLA.md)).
187
189
  - 🔒 [Report a security issue](./SECURITY.md) — **not via public Issues**
188
190
  - 💬 [Join Discord](https://discord.gg/gQyXjVBF)
189
191
 
192
+ ## Telemetry
193
+
194
+ The `hb` CLI sends anonymous usage data to help us improve it.
195
+ Disable with `hb telemetry disable`, `HB_TELEMETRY_DISABLED=1`, or
196
+ `DO_NOT_TRACK=1`. Full disclosure: [PRIVACY.md](./PRIVACY.md).
197
+
190
198
  ## License
191
199
 
192
200
  [Apache-2.0](./LICENSE). Free to use in any context — commercial or
@@ -194,5 +202,4 @@ open-source — with attribution. See [TRADEMARK.md](./TRADEMARK.md) for the
194
202
  trademark policy. The code is open; the name is not.
195
203
 
196
204
  The sibling project [`humanbound-firewall`](https://github.com/humanbound/humanbound-firewall)
197
- is dual-licensed (AGPL-3.0 + commercial) different product, different
198
- license strategy.
205
+ is also Apache-2.0 same license, different product.
@@ -104,8 +104,9 @@ integration, and API reference all live on
104
104
  ## What's shipping in 2.0
105
105
 
106
106
  - **Clean name**: `humanbound` is the new PyPI install. The old
107
- `humanbound-cli` is a transitional stub that will be yanked after
108
- 2026-06-20.
107
+ `humanbound-cli` package is a discontinued transitional stub (final
108
+ release 1.2.2 depends on `humanbound>=2.0.2`); please install
109
+ `humanbound` directly.
109
110
  - **Public SDK namespace** alongside the CLI — use the CLI or drive the
110
111
  engine from Python. Both share the same implementation, so they can't
111
112
  drift.
@@ -125,6 +126,12 @@ loop, release process, and CLA requirement (see [CLA.md](./CLA.md)).
125
126
  - 🔒 [Report a security issue](./SECURITY.md) — **not via public Issues**
126
127
  - 💬 [Join Discord](https://discord.gg/gQyXjVBF)
127
128
 
129
+ ## Telemetry
130
+
131
+ The `hb` CLI sends anonymous usage data to help us improve it.
132
+ Disable with `hb telemetry disable`, `HB_TELEMETRY_DISABLED=1`, or
133
+ `DO_NOT_TRACK=1`. Full disclosure: [PRIVACY.md](./PRIVACY.md).
134
+
128
135
  ## License
129
136
 
130
137
  [Apache-2.0](./LICENSE). Free to use in any context — commercial or
@@ -132,5 +139,4 @@ open-source — with attribution. See [TRADEMARK.md](./TRADEMARK.md) for the
132
139
  trademark policy. The code is open; the name is not.
133
140
 
134
141
  The sibling project [`humanbound-firewall`](https://github.com/humanbound/humanbound-firewall)
135
- is dual-licensed (AGPL-3.0 + commercial) different product, different
136
- license strategy.
142
+ is also Apache-2.0 same license, different product.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: humanbound
3
- Version: 2.0.2
3
+ Version: 2.0.4
4
4
  Summary: Humanbound — open-source AI agent red-team engine, SDK, and CLI.
5
5
  Author-email: Humanbound <hello@humanbound.ai>
6
6
  Maintainer-email: Demetris Gerogiannis <hello@humanbound.ai>, Kostas Siabanis <hello@humanbound.ai>
@@ -34,8 +34,8 @@ Requires-Dist: rich>=13.0.0
34
34
  Requires-Dist: requests>=2.32.0
35
35
  Requires-Dist: pyyaml>=6.0.0
36
36
  Requires-Dist: pydantic>=2.0
37
- Requires-Dist: msal>=1.31.0
38
37
  Requires-Dist: pyperclip>=1.8.0
38
+ Requires-Dist: posthog>=3.0
39
39
  Provides-Extra: engine
40
40
  Requires-Dist: openai>=1.0.0; extra == "engine"
41
41
  Requires-Dist: anthropic>=0.20.0; extra == "engine"
@@ -58,6 +58,7 @@ Requires-Dist: mypy>=1.11; extra == "dev"
58
58
  Requires-Dist: build>=1.2; extra == "dev"
59
59
  Requires-Dist: twine>=5.0; extra == "dev"
60
60
  Requires-Dist: pre-commit>=3.8; extra == "dev"
61
+ Requires-Dist: mkdocs>=1.6; extra == "dev"
61
62
  Dynamic: license-file
62
63
 
63
64
  <p align="center">
@@ -166,8 +167,9 @@ integration, and API reference all live on
166
167
  ## What's shipping in 2.0
167
168
 
168
169
  - **Clean name**: `humanbound` is the new PyPI install. The old
169
- `humanbound-cli` is a transitional stub that will be yanked after
170
- 2026-06-20.
170
+ `humanbound-cli` package is a discontinued transitional stub (final
171
+ release 1.2.2 depends on `humanbound>=2.0.2`); please install
172
+ `humanbound` directly.
171
173
  - **Public SDK namespace** alongside the CLI — use the CLI or drive the
172
174
  engine from Python. Both share the same implementation, so they can't
173
175
  drift.
@@ -187,6 +189,12 @@ loop, release process, and CLA requirement (see [CLA.md](./CLA.md)).
187
189
  - 🔒 [Report a security issue](./SECURITY.md) — **not via public Issues**
188
190
  - 💬 [Join Discord](https://discord.gg/gQyXjVBF)
189
191
 
192
+ ## Telemetry
193
+
194
+ The `hb` CLI sends anonymous usage data to help us improve it.
195
+ Disable with `hb telemetry disable`, `HB_TELEMETRY_DISABLED=1`, or
196
+ `DO_NOT_TRACK=1`. Full disclosure: [PRIVACY.md](./PRIVACY.md).
197
+
190
198
  ## License
191
199
 
192
200
  [Apache-2.0](./LICENSE). Free to use in any context — commercial or
@@ -194,5 +202,4 @@ open-source — with attribution. See [TRADEMARK.md](./TRADEMARK.md) for the
194
202
  trademark policy. The code is open; the name is not.
195
203
 
196
204
  The sibling project [`humanbound-firewall`](https://github.com/humanbound/humanbound-firewall)
197
- is dual-licensed (AGPL-3.0 + commercial) different product, different
198
- license strategy.
205
+ is also Apache-2.0 same license, different product.
@@ -50,13 +50,9 @@ humanbound_cli/commands/projects.py
50
50
  humanbound_cli/commands/providers.py
51
51
  humanbound_cli/commands/redteam.py
52
52
  humanbound_cli/commands/report.py
53
- humanbound_cli/commands/scan.py
54
- humanbound_cli/commands/sentinel.py
53
+ humanbound_cli/commands/telemetry.py
55
54
  humanbound_cli/commands/test.py
56
- humanbound_cli/commands/upload_logs.py
57
55
  humanbound_cli/commands/webhooks.py
58
- humanbound_cli/connectors/__init__.py
59
- humanbound_cli/connectors/microsoft.py
60
56
  humanbound_cli/engine/__init__.py
61
57
  humanbound_cli/engine/bot.py
62
58
  humanbound_cli/engine/callbacks.py
@@ -97,6 +93,9 @@ humanbound_cli/extractors/repo.py
97
93
  humanbound_cli/pytest_plugin/__init__.py
98
94
  humanbound_cli/pytest_plugin/fixtures.py
99
95
  humanbound_cli/pytest_plugin/report.py
96
+ humanbound_cli/telemetry/__init__.py
97
+ humanbound_cli/telemetry/client.py
98
+ humanbound_cli/telemetry/consent.py
100
99
  humanbound_cli/templates/logo.svg
101
100
  humanbound_cli/templates/report_base.html
102
101
  humanbound_cli/templates/compliance/banking.yaml
@@ -3,8 +3,8 @@ rich>=13.0.0
3
3
  requests>=2.32.0
4
4
  pyyaml>=6.0.0
5
5
  pydantic>=2.0
6
- msal>=1.31.0
7
6
  pyperclip>=1.8.0
7
+ posthog>=3.0
8
8
 
9
9
  [dev]
10
10
  pytest>=7.0.0
@@ -15,6 +15,7 @@ mypy>=1.11
15
15
  build>=1.2
16
16
  twine>=5.0
17
17
  pre-commit>=3.8
18
+ mkdocs>=1.6
18
19
 
19
20
  [engine]
20
21
  openai>=1.0.0
@@ -436,11 +436,21 @@ class HumanboundClient:
436
436
  return True
437
437
 
438
438
  def logout(self, silent: bool = False) -> None:
439
- """Clear stored credentials and logout.
439
+ """Revoke the server session (if any) and clear stored credentials.
440
440
 
441
441
  Args:
442
442
  silent: If True, don't print success message (used for cleanup).
443
443
  """
444
+ if self._api_token:
445
+ try:
446
+ requests.get(
447
+ f"{self.base_url}/logout",
448
+ headers={"Authorization": f"Bearer {self._api_token}"},
449
+ timeout=DEFAULT_TIMEOUT,
450
+ )
451
+ except (requests.ConnectionError, requests.Timeout):
452
+ pass
453
+
444
454
  self._auth0_token = None
445
455
  self._api_token = None
446
456
  self._token_expires_at = None
@@ -23,9 +23,7 @@ from . import (
23
23
  projects,
24
24
  providers,
25
25
  report,
26
- sentinel,
27
26
  test,
28
- upload_logs,
29
27
  webhooks,
30
28
  )
31
29
 
@@ -50,8 +48,6 @@ __all__ = [
50
48
  "api_keys",
51
49
  "members",
52
50
  "campaigns",
53
- "upload_logs",
54
- "sentinel",
55
51
  "completion",
56
52
  "connect",
57
53
  "report",
@@ -10,6 +10,7 @@ from rich.panel import Panel
10
10
  from rich.prompt import Confirm
11
11
  from rich.table import Table
12
12
 
13
+ from .. import telemetry
13
14
  from ..client import HumanboundClient
14
15
  from ..exceptions import APIError, NotAuthenticatedError
15
16
 
@@ -38,6 +39,7 @@ def _list_keys(as_json: bool):
38
39
  client = HumanboundClient()
39
40
 
40
41
  if not client.is_authenticated():
42
+ telemetry.fire_gated_command_hit()
41
43
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
42
44
  raise SystemExit(1)
43
45
 
@@ -106,6 +108,7 @@ def create_key(name: str, scopes: str):
106
108
  client = HumanboundClient()
107
109
 
108
110
  if not client.is_authenticated():
111
+ telemetry.fire_gated_command_hit()
109
112
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
110
113
  raise SystemExit(1)
111
114
 
@@ -152,6 +155,7 @@ def update_key(key_id: str, name: str, scopes: str, active):
152
155
  client = HumanboundClient()
153
156
 
154
157
  if not client.is_authenticated():
158
+ telemetry.fire_gated_command_hit()
155
159
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
156
160
  raise SystemExit(1)
157
161
 
@@ -198,6 +202,7 @@ def revoke_key(key_id: str, force: bool):
198
202
  client = HumanboundClient()
199
203
 
200
204
  if not client.is_authenticated():
205
+ telemetry.fire_gated_command_hit()
201
206
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
202
207
  raise SystemExit(1)
203
208
 
@@ -9,6 +9,7 @@ from rich.console import Console
9
9
  from rich.panel import Panel
10
10
  from rich.table import Table
11
11
 
12
+ from .. import telemetry
12
13
  from ..client import HumanboundClient
13
14
  from ..exceptions import APIError, NotAuthenticatedError
14
15
 
@@ -53,6 +54,7 @@ def assessments_group(ctx, page, size, as_json):
53
54
  client = HumanboundClient()
54
55
 
55
56
  if not client.is_authenticated():
57
+ telemetry.fire_gated_command_hit()
56
58
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
57
59
  raise SystemExit(1)
58
60
 
@@ -132,6 +134,7 @@ def show_assessment(assessment_id: str, as_json: bool):
132
134
  client = HumanboundClient()
133
135
 
134
136
  if not client.is_authenticated():
137
+ telemetry.fire_gated_command_hit()
135
138
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
136
139
  raise SystemExit(1)
137
140
 
@@ -6,6 +6,7 @@ import click
6
6
  from rich.console import Console
7
7
  from rich.panel import Panel
8
8
 
9
+ from .. import telemetry
9
10
  from ..client import HumanboundClient
10
11
  from ..config import DEFAULT_BASE_URL
11
12
  from ..exceptions import AuthenticationError
@@ -44,6 +45,8 @@ def login(base_url: str, port: int, force: bool):
44
45
  console.print("Starting authentication...")
45
46
  client.login(callback_port=port)
46
47
 
48
+ telemetry.identify_from_credentials()
49
+
47
50
  # Auto-select default organisation and resolve name
48
51
  org_display = "not set"
49
52
  if client.default_organisation_id:
@@ -10,6 +10,7 @@ from rich.panel import Panel
10
10
  from rich.prompt import Confirm
11
11
  from rich.table import Table
12
12
 
13
+ from .. import telemetry
13
14
  from ..client import HumanboundClient
14
15
  from ..exceptions import APIError, NotAuthenticatedError
15
16
 
@@ -40,6 +41,7 @@ def campaigns_group(ctx, as_json):
40
41
  client = HumanboundClient()
41
42
 
42
43
  if not client.is_authenticated():
44
+ telemetry.fire_gated_command_hit()
43
45
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
44
46
  raise SystemExit(1)
45
47
 
@@ -136,6 +138,7 @@ def terminate_campaign(force: bool):
136
138
  client = HumanboundClient()
137
139
 
138
140
  if not client.is_authenticated():
141
+ telemetry.fire_gated_command_hit()
139
142
  console.print("[red]Not authenticated.[/red] Run 'hb login' first.")
140
143
  raise SystemExit(1)
141
144