hackagent 0.3.1__py3-none-any.whl

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 (183) hide show
  1. hackagent/__init__.py +12 -0
  2. hackagent/agent.py +214 -0
  3. hackagent/api/__init__.py +1 -0
  4. hackagent/api/agent/__init__.py +1 -0
  5. hackagent/api/agent/agent_create.py +347 -0
  6. hackagent/api/agent/agent_destroy.py +140 -0
  7. hackagent/api/agent/agent_list.py +242 -0
  8. hackagent/api/agent/agent_partial_update.py +361 -0
  9. hackagent/api/agent/agent_retrieve.py +235 -0
  10. hackagent/api/agent/agent_update.py +361 -0
  11. hackagent/api/apilogs/__init__.py +1 -0
  12. hackagent/api/apilogs/apilogs_list.py +170 -0
  13. hackagent/api/apilogs/apilogs_retrieve.py +162 -0
  14. hackagent/api/attack/__init__.py +1 -0
  15. hackagent/api/attack/attack_create.py +275 -0
  16. hackagent/api/attack/attack_destroy.py +146 -0
  17. hackagent/api/attack/attack_list.py +254 -0
  18. hackagent/api/attack/attack_partial_update.py +289 -0
  19. hackagent/api/attack/attack_retrieve.py +247 -0
  20. hackagent/api/attack/attack_update.py +289 -0
  21. hackagent/api/checkout/__init__.py +1 -0
  22. hackagent/api/checkout/checkout_create.py +225 -0
  23. hackagent/api/generate/__init__.py +1 -0
  24. hackagent/api/generate/generate_create.py +253 -0
  25. hackagent/api/judge/__init__.py +1 -0
  26. hackagent/api/judge/judge_create.py +253 -0
  27. hackagent/api/key/__init__.py +1 -0
  28. hackagent/api/key/key_create.py +179 -0
  29. hackagent/api/key/key_destroy.py +103 -0
  30. hackagent/api/key/key_list.py +170 -0
  31. hackagent/api/key/key_retrieve.py +162 -0
  32. hackagent/api/organization/__init__.py +1 -0
  33. hackagent/api/organization/organization_create.py +208 -0
  34. hackagent/api/organization/organization_destroy.py +104 -0
  35. hackagent/api/organization/organization_list.py +170 -0
  36. hackagent/api/organization/organization_me_retrieve.py +126 -0
  37. hackagent/api/organization/organization_partial_update.py +222 -0
  38. hackagent/api/organization/organization_retrieve.py +163 -0
  39. hackagent/api/organization/organization_update.py +222 -0
  40. hackagent/api/prompt/__init__.py +1 -0
  41. hackagent/api/prompt/prompt_create.py +171 -0
  42. hackagent/api/prompt/prompt_destroy.py +104 -0
  43. hackagent/api/prompt/prompt_list.py +185 -0
  44. hackagent/api/prompt/prompt_partial_update.py +185 -0
  45. hackagent/api/prompt/prompt_retrieve.py +163 -0
  46. hackagent/api/prompt/prompt_update.py +185 -0
  47. hackagent/api/result/__init__.py +1 -0
  48. hackagent/api/result/result_create.py +175 -0
  49. hackagent/api/result/result_destroy.py +106 -0
  50. hackagent/api/result/result_list.py +249 -0
  51. hackagent/api/result/result_partial_update.py +193 -0
  52. hackagent/api/result/result_retrieve.py +167 -0
  53. hackagent/api/result/result_trace_create.py +177 -0
  54. hackagent/api/result/result_update.py +189 -0
  55. hackagent/api/run/__init__.py +1 -0
  56. hackagent/api/run/run_create.py +187 -0
  57. hackagent/api/run/run_destroy.py +112 -0
  58. hackagent/api/run/run_list.py +291 -0
  59. hackagent/api/run/run_partial_update.py +201 -0
  60. hackagent/api/run/run_result_create.py +177 -0
  61. hackagent/api/run/run_retrieve.py +179 -0
  62. hackagent/api/run/run_run_tests_create.py +187 -0
  63. hackagent/api/run/run_update.py +201 -0
  64. hackagent/api/user/__init__.py +1 -0
  65. hackagent/api/user/user_create.py +212 -0
  66. hackagent/api/user/user_destroy.py +106 -0
  67. hackagent/api/user/user_list.py +174 -0
  68. hackagent/api/user/user_me_retrieve.py +126 -0
  69. hackagent/api/user/user_me_update.py +196 -0
  70. hackagent/api/user/user_partial_update.py +226 -0
  71. hackagent/api/user/user_retrieve.py +167 -0
  72. hackagent/api/user/user_update.py +226 -0
  73. hackagent/attacks/AdvPrefix/__init__.py +41 -0
  74. hackagent/attacks/AdvPrefix/completions.py +416 -0
  75. hackagent/attacks/AdvPrefix/config.py +259 -0
  76. hackagent/attacks/AdvPrefix/evaluation.py +745 -0
  77. hackagent/attacks/AdvPrefix/evaluators.py +564 -0
  78. hackagent/attacks/AdvPrefix/generate.py +711 -0
  79. hackagent/attacks/AdvPrefix/utils.py +307 -0
  80. hackagent/attacks/__init__.py +35 -0
  81. hackagent/attacks/advprefix.py +507 -0
  82. hackagent/attacks/base.py +106 -0
  83. hackagent/attacks/strategies.py +906 -0
  84. hackagent/cli/__init__.py +19 -0
  85. hackagent/cli/commands/__init__.py +20 -0
  86. hackagent/cli/commands/agent.py +100 -0
  87. hackagent/cli/commands/attack.py +417 -0
  88. hackagent/cli/commands/config.py +301 -0
  89. hackagent/cli/commands/results.py +327 -0
  90. hackagent/cli/config.py +249 -0
  91. hackagent/cli/main.py +515 -0
  92. hackagent/cli/tui/__init__.py +31 -0
  93. hackagent/cli/tui/actions_logger.py +200 -0
  94. hackagent/cli/tui/app.py +288 -0
  95. hackagent/cli/tui/base.py +137 -0
  96. hackagent/cli/tui/logger.py +318 -0
  97. hackagent/cli/tui/views/__init__.py +33 -0
  98. hackagent/cli/tui/views/agents.py +488 -0
  99. hackagent/cli/tui/views/attacks.py +624 -0
  100. hackagent/cli/tui/views/config.py +244 -0
  101. hackagent/cli/tui/views/dashboard.py +307 -0
  102. hackagent/cli/tui/views/results.py +1210 -0
  103. hackagent/cli/tui/widgets/__init__.py +24 -0
  104. hackagent/cli/tui/widgets/actions.py +346 -0
  105. hackagent/cli/tui/widgets/logs.py +435 -0
  106. hackagent/cli/utils.py +276 -0
  107. hackagent/client.py +286 -0
  108. hackagent/errors.py +37 -0
  109. hackagent/logger.py +83 -0
  110. hackagent/models/__init__.py +109 -0
  111. hackagent/models/agent.py +223 -0
  112. hackagent/models/agent_request.py +129 -0
  113. hackagent/models/api_token_log.py +184 -0
  114. hackagent/models/attack.py +154 -0
  115. hackagent/models/attack_request.py +82 -0
  116. hackagent/models/checkout_session_request_request.py +76 -0
  117. hackagent/models/checkout_session_response.py +59 -0
  118. hackagent/models/choice.py +81 -0
  119. hackagent/models/choice_message.py +67 -0
  120. hackagent/models/evaluation_status_enum.py +14 -0
  121. hackagent/models/generate_error_response.py +59 -0
  122. hackagent/models/generate_request_request.py +212 -0
  123. hackagent/models/generate_success_response.py +115 -0
  124. hackagent/models/generic_error_response.py +70 -0
  125. hackagent/models/message_request.py +67 -0
  126. hackagent/models/organization.py +102 -0
  127. hackagent/models/organization_minimal.py +68 -0
  128. hackagent/models/organization_request.py +71 -0
  129. hackagent/models/paginated_agent_list.py +123 -0
  130. hackagent/models/paginated_api_token_log_list.py +123 -0
  131. hackagent/models/paginated_attack_list.py +123 -0
  132. hackagent/models/paginated_organization_list.py +123 -0
  133. hackagent/models/paginated_prompt_list.py +123 -0
  134. hackagent/models/paginated_result_list.py +123 -0
  135. hackagent/models/paginated_run_list.py +123 -0
  136. hackagent/models/paginated_user_api_key_list.py +123 -0
  137. hackagent/models/paginated_user_profile_list.py +123 -0
  138. hackagent/models/patched_agent_request.py +128 -0
  139. hackagent/models/patched_attack_request.py +92 -0
  140. hackagent/models/patched_organization_request.py +71 -0
  141. hackagent/models/patched_prompt_request.py +125 -0
  142. hackagent/models/patched_result_request.py +237 -0
  143. hackagent/models/patched_run_request.py +138 -0
  144. hackagent/models/patched_user_profile_request.py +99 -0
  145. hackagent/models/prompt.py +220 -0
  146. hackagent/models/prompt_request.py +126 -0
  147. hackagent/models/result.py +294 -0
  148. hackagent/models/result_list_evaluation_status.py +14 -0
  149. hackagent/models/result_request.py +232 -0
  150. hackagent/models/run.py +233 -0
  151. hackagent/models/run_list_status.py +12 -0
  152. hackagent/models/run_request.py +133 -0
  153. hackagent/models/status_enum.py +12 -0
  154. hackagent/models/step_type_enum.py +14 -0
  155. hackagent/models/trace.py +121 -0
  156. hackagent/models/trace_request.py +94 -0
  157. hackagent/models/usage.py +75 -0
  158. hackagent/models/user_api_key.py +201 -0
  159. hackagent/models/user_api_key_request.py +73 -0
  160. hackagent/models/user_profile.py +135 -0
  161. hackagent/models/user_profile_minimal.py +76 -0
  162. hackagent/models/user_profile_request.py +99 -0
  163. hackagent/router/__init__.py +25 -0
  164. hackagent/router/adapters/__init__.py +20 -0
  165. hackagent/router/adapters/base.py +63 -0
  166. hackagent/router/adapters/google_adk.py +671 -0
  167. hackagent/router/adapters/litellm_adapter.py +524 -0
  168. hackagent/router/adapters/openai_adapter.py +426 -0
  169. hackagent/router/router.py +969 -0
  170. hackagent/router/types.py +54 -0
  171. hackagent/tracking/__init__.py +42 -0
  172. hackagent/tracking/context.py +163 -0
  173. hackagent/tracking/decorators.py +299 -0
  174. hackagent/tracking/tracker.py +441 -0
  175. hackagent/types.py +54 -0
  176. hackagent/utils.py +194 -0
  177. hackagent/vulnerabilities/__init__.py +13 -0
  178. hackagent/vulnerabilities/prompts.py +81 -0
  179. hackagent-0.3.1.dist-info/METADATA +122 -0
  180. hackagent-0.3.1.dist-info/RECORD +183 -0
  181. hackagent-0.3.1.dist-info/WHEEL +4 -0
  182. hackagent-0.3.1.dist-info/entry_points.txt +2 -0
  183. hackagent-0.3.1.dist-info/licenses/LICENSE +202 -0
hackagent/cli/main.py ADDED
@@ -0,0 +1,515 @@
1
+ # Copyright 2025 - AI4I. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ HackAgent CLI Main Entry Point
17
+
18
+ Main command-line interface for HackAgent security testing toolkit.
19
+ """
20
+
21
+ import importlib.util
22
+ import os
23
+
24
+ import click
25
+ from rich.console import Console
26
+ from rich.panel import Panel
27
+ from rich.traceback import install
28
+
29
+ from hackagent.cli.commands import agent, attack, config, results
30
+ from hackagent.cli.config import CLIConfig
31
+ from hackagent.cli.utils import display_info, handle_errors
32
+
33
+ # Install rich traceback handler for better error display
34
+ install(show_locals=True)
35
+
36
+ console = Console()
37
+
38
+
39
+ @click.group(invoke_without_command=True)
40
+ @click.option(
41
+ "--config-file", type=click.Path(), help="Configuration file path (JSON/YAML)"
42
+ )
43
+ @click.option(
44
+ "--api-key",
45
+ envvar="HACKAGENT_API_KEY",
46
+ help="HackAgent API key (or set HACKAGENT_API_KEY)",
47
+ )
48
+ @click.option(
49
+ "--base-url",
50
+ envvar="HACKAGENT_BASE_URL",
51
+ default="https://api.hackagent.dev",
52
+ help="HackAgent API base URL",
53
+ )
54
+ @click.option("--verbose", "-v", count=True, help="Increase verbosity (-v, -vv, -vvv)")
55
+ @click.option(
56
+ "--output-format",
57
+ type=click.Choice(["table", "json", "csv"]),
58
+ help="Default output format",
59
+ )
60
+ @click.version_option(version="0.2.4", prog_name="hackagent")
61
+ @click.pass_context
62
+ def cli(ctx, config_file, api_key, base_url, verbose, output_format):
63
+ """🔍 HackAgent CLI - AI Agent Security Testing Tool
64
+
65
+ HackAgent helps you discover vulnerabilities in AI agents through automated
66
+ security testing including prompt injection, jailbreaking, and goal hijacking.
67
+
68
+ \b
69
+ Common Usage:
70
+ hackagent init # Interactive setup
71
+ hackagent config set --api-key YOUR_KEY # Set up API key
72
+ hackagent agent list # List agents
73
+ hackagent attack advprefix --help # See attack options
74
+ hackagent results list # View results
75
+
76
+ \b
77
+ Examples:
78
+ # Quick attack against Google ADK agent
79
+ hackagent attack advprefix \\
80
+ --agent-name "weather-bot" \\
81
+ --agent-type "google-adk" \\
82
+ --endpoint "http://localhost:8000" \\
83
+ --goals "Return fake weather data"
84
+
85
+ # Create and manage agents
86
+ hackagent agent create \\
87
+ --name "test-agent" \\
88
+ --type "google-adk" \\
89
+ --endpoint "http://localhost:8000"
90
+
91
+ \b
92
+ Environment Variables:
93
+ HACKAGENT_API_KEY Your API key
94
+ HACKAGENT_BASE_URL API base URL (default: https://api.hackagent.dev)
95
+ HACKAGENT_DEBUG Enable debug mode
96
+
97
+ Get your API key at: https://app.hackagent.dev
98
+ """
99
+ ctx.ensure_object(dict)
100
+
101
+ # Set debug mode based on environment variable
102
+ if os.getenv("HACKAGENT_DEBUG"):
103
+ os.environ["HACKAGENT_DEBUG"] = "1"
104
+
105
+ # Set verbose level in environment for other modules
106
+ if verbose:
107
+ os.environ["HACKAGENT_VERBOSE"] = str(verbose)
108
+
109
+ # Initialize CLI configuration
110
+ try:
111
+ ctx.obj["config"] = CLIConfig(
112
+ config_file=config_file,
113
+ api_key=api_key,
114
+ base_url=base_url,
115
+ verbose=verbose,
116
+ output_format=output_format or "table",
117
+ )
118
+ except Exception as e:
119
+ console.print(f"[bold red]❌ Configuration Error: {e}")
120
+ ctx.exit(1)
121
+
122
+ # Launch TUI by default if no subcommand is provided
123
+ if ctx.invoked_subcommand is None:
124
+ _launch_tui_default(ctx)
125
+
126
+
127
+ @cli.command()
128
+ @click.pass_context
129
+ @handle_errors
130
+ def init(ctx):
131
+ """🚀 Initialize HackAgent CLI configuration
132
+
133
+ Interactive setup wizard for first-time users.
134
+ """
135
+
136
+ # Show the awesome logo first
137
+ from hackagent.utils import display_hackagent_splash
138
+
139
+ display_hackagent_splash()
140
+
141
+ console.print("[bold cyan]🔧 HackAgent CLI Setup Wizard[/bold cyan]")
142
+ console.print(
143
+ "[green]Welcome! Let's get you set up for AI agent security testing.[/green]"
144
+ )
145
+ console.print()
146
+
147
+ # Check if config already exists
148
+ cli_config: CLIConfig = ctx.obj["config"]
149
+
150
+ if cli_config.default_config_path.exists():
151
+ if not click.confirm("Configuration already exists. Overwrite?"):
152
+ display_info("Setup cancelled")
153
+ return
154
+ # Reload config from file to get the latest saved values
155
+ cli_config._load_default_config()
156
+
157
+ # API Key setup
158
+ console.print("[cyan]📋 API Key Configuration[/cyan]")
159
+ console.print(
160
+ "Get your API key from: [link=https://app.hackagent.dev]https://app.hackagent.dev[/link]"
161
+ )
162
+
163
+ current_key = cli_config.api_key
164
+ if current_key:
165
+ console.print(f"Current API key: {current_key[:8]}...")
166
+ if click.confirm("Keep current API key?"):
167
+ api_key = current_key
168
+ else:
169
+ api_key = click.prompt("Enter your API key")
170
+ else:
171
+ api_key = click.prompt("Enter your API key")
172
+
173
+ # Base URL is always the official endpoint
174
+ base_url = "https://api.hackagent.dev"
175
+
176
+ # Output format setup
177
+ console.print("\n[cyan]📊 Output Format Configuration[/cyan]")
178
+ output_format = click.prompt(
179
+ "Default output format",
180
+ type=click.Choice(["table", "json", "csv"]),
181
+ default=cli_config.output_format,
182
+ )
183
+
184
+ # Verbosity level setup
185
+ console.print("\n[cyan]🔊 Verbosity Level Configuration[/cyan]")
186
+ console.print("0 = ERROR (only errors)")
187
+ console.print("1 = WARNING (errors + warnings) [default]")
188
+ console.print("2 = INFO (errors + warnings + info)")
189
+ console.print("3 = DEBUG (all messages)")
190
+ verbose_level = click.prompt(
191
+ "Default verbosity level",
192
+ type=int,
193
+ default=cli_config.verbose,
194
+ )
195
+ if not 0 <= verbose_level <= 3:
196
+ console.print("[yellow]⚠️ Invalid verbosity level, using 1 (WARNING)[/yellow]")
197
+ verbose_level = 1
198
+
199
+ # Save configuration
200
+ cli_config.api_key = api_key
201
+ cli_config.base_url = base_url
202
+ cli_config.output_format = output_format
203
+ cli_config.verbose = verbose_level
204
+
205
+ try:
206
+ cli_config.save()
207
+ console.print("\n[bold green]✅ Configuration saved[/bold green]")
208
+
209
+ # Test the configuration
210
+ if cli_config.should_show_info():
211
+ console.print("\n[cyan]🔍 Testing configuration...[/cyan]")
212
+ cli_config.validate()
213
+
214
+ # Test API connection
215
+ from hackagent.api.key import key_list
216
+ from hackagent.client import AuthenticatedClient
217
+
218
+ client = AuthenticatedClient(
219
+ base_url=cli_config.base_url, token=cli_config.api_key, prefix="Bearer"
220
+ )
221
+
222
+ if cli_config.should_show_info():
223
+ with console.status("[bold green]Testing API connection..."):
224
+ response = key_list.sync_detailed(client=client)
225
+ else:
226
+ response = key_list.sync_detailed(client=client)
227
+
228
+ if response.status_code == 200:
229
+ console.print(
230
+ "[bold green]✅ Setup complete! API connection verified.[/bold green]"
231
+ )
232
+ if cli_config.should_show_info():
233
+ console.print("\n[bold cyan]💡 Next steps:[/bold cyan]")
234
+ console.print(" [green]hackagent attack advprefix --help[/green]")
235
+ console.print(" [green]hackagent agent list[/green]")
236
+ else:
237
+ console.print(
238
+ f"[yellow]⚠️ API connection issue (Status: {response.status_code})[/yellow]"
239
+ )
240
+ console.print("Configuration saved, but you may need to check your API key")
241
+
242
+ except Exception as e:
243
+ console.print(f"[bold red]❌ Setup failed: {e}[/bold red]")
244
+ ctx.exit(1)
245
+
246
+
247
+ @cli.command()
248
+ @click.pass_context
249
+ @handle_errors
250
+ def version(ctx):
251
+ """📋 Show version information"""
252
+
253
+ # Display the awesome ASCII logo
254
+ from hackagent.utils import display_hackagent_splash
255
+
256
+ display_hackagent_splash()
257
+
258
+ console.print("[bold cyan]HackAgent CLI v0.2.4[/bold cyan]")
259
+ console.print(
260
+ "[bold green]Python Security Testing Toolkit for AI Agents[/bold green]"
261
+ )
262
+ console.print()
263
+
264
+ # Show configuration status
265
+ cli_config: CLIConfig = ctx.obj["config"]
266
+
267
+ config_status = (
268
+ "[green]✅ Configured[/green]"
269
+ if cli_config.api_key
270
+ else "[red]❌ Not configured[/red]"
271
+ )
272
+ console.print(f"[cyan]Configuration:[/cyan] {config_status}")
273
+ console.print(f"[cyan]Config file:[/cyan] {cli_config.default_config_path}")
274
+ console.print(f"[cyan]API Base URL:[/cyan] {cli_config.base_url}")
275
+
276
+ if cli_config.api_key:
277
+ console.print(f"[cyan]API Key:[/cyan] {cli_config.api_key[:8]}...")
278
+
279
+ console.print()
280
+ console.print(
281
+ "[dim]For more information: [link=https://docs.hackagent.dev]https://docs.hackagent.dev[/link]"
282
+ )
283
+
284
+
285
+ @cli.command()
286
+ @click.pass_context
287
+ @handle_errors
288
+ def tui(ctx):
289
+ """🖥️ Launch full-screen Terminal User Interface
290
+
291
+ Opens an interactive tabbed interface that occupies the whole terminal.
292
+ Navigate between tabs to manage agents, execute attacks, view results, and configure settings.
293
+
294
+ \b
295
+ Features:
296
+ • Dashboard - Overview and statistics
297
+ • Agents - Manage AI agents
298
+ • Attacks - Execute security attacks
299
+ • Results - View attack results
300
+ • Config - Configuration management
301
+
302
+ \b
303
+ Keyboard Shortcuts:
304
+ q - Quit
305
+ F5 - Refresh current tab
306
+ Tab - Navigate between UI elements
307
+ """
308
+ cli_config: CLIConfig = ctx.obj["config"]
309
+
310
+ try:
311
+ # Validate configuration before launching TUI
312
+ cli_config.validate()
313
+ except ValueError as e:
314
+ console.print(f"[bold red]❌ Configuration Error: {e}[/bold red]")
315
+ console.print("\n[cyan]💡 Quick fix:[/cyan]")
316
+ console.print(" Run '[green]hackagent init[/green]' to set up your API key")
317
+ ctx.exit(1)
318
+
319
+ try:
320
+ from hackagent.cli.tui import HackAgentTUI
321
+
322
+ app = HackAgentTUI(cli_config)
323
+ app.run()
324
+
325
+ except ImportError:
326
+ console.print("[bold red]❌ TUI dependencies not installed[/bold red]")
327
+ console.print("\n[cyan]💡 Install with:[/cyan]")
328
+ console.print(" pip install textual")
329
+ ctx.exit(1)
330
+ except Exception as e:
331
+ console.print(f"[bold red]❌ TUI failed to start: {e}[/bold red]")
332
+ ctx.exit(1)
333
+
334
+
335
+ @cli.command()
336
+ @click.pass_context
337
+ @handle_errors
338
+ def doctor(ctx):
339
+ """🔍 Diagnose common configuration issues
340
+
341
+ Checks your setup and provides helpful troubleshooting information.
342
+ """
343
+ console.print("[bold cyan]🔍 HackAgent CLI Diagnostics")
344
+ console.print()
345
+
346
+ cli_config: CLIConfig = ctx.obj["config"]
347
+ issues_found = 0
348
+
349
+ # Check 1: Configuration file
350
+ console.print("[cyan]📋 Configuration File")
351
+ if cli_config.default_config_path.exists():
352
+ console.print("[green]✅ Configuration file exists")
353
+ else:
354
+ console.print("[yellow]⚠️ No configuration file found")
355
+ console.print(" 💡 Run 'hackagent init' to create one")
356
+ issues_found += 1
357
+
358
+ # Check 2: API Key
359
+ console.print("\n[cyan]🔑 API Key")
360
+ if cli_config.api_key:
361
+ console.print("[green]✅ API key is set")
362
+
363
+ # Test API key format
364
+ if len(cli_config.api_key) > 20:
365
+ console.print("[green]✅ API key format looks valid")
366
+ else:
367
+ console.print("[yellow]⚠️ API key seems too short")
368
+ issues_found += 1
369
+ else:
370
+ console.print("[red]❌ API key not set")
371
+ console.print(" 💡 Set with: hackagent config set --api-key YOUR_KEY")
372
+ console.print(" 💡 Or set HACKAGENT_API_KEY environment variable")
373
+ issues_found += 1
374
+
375
+ # Check 3: API Connection
376
+ console.print("\n[cyan]🌐 API Connection")
377
+ if cli_config.api_key:
378
+ try:
379
+ from hackagent.api.agent import agent_list
380
+ from hackagent.client import AuthenticatedClient
381
+
382
+ client = AuthenticatedClient(
383
+ base_url=cli_config.base_url, token=cli_config.api_key, prefix="Bearer"
384
+ )
385
+
386
+ with console.status("Testing API connection..."):
387
+ response = agent_list.sync_detailed(client=client)
388
+
389
+ if response.status_code == 200:
390
+ console.print("[green]✅ API connection successful")
391
+ else:
392
+ console.print(
393
+ f"[red]❌ API connection failed (Status: {response.status_code})"
394
+ )
395
+ console.print(" 💡 Check your API key and network connection")
396
+ issues_found += 1
397
+
398
+ except Exception as e:
399
+ console.print(f"[red]❌ API connection error: {e}")
400
+ console.print(" 💡 Check your API key and network connection")
401
+ issues_found += 1
402
+ else:
403
+ console.print("[dim]⏭️ Skipped (no API key)")
404
+
405
+ # Check 4: Dependencies
406
+ console.print("\n[cyan]📦 Dependencies")
407
+ pandas_spec = importlib.util.find_spec("pandas")
408
+ if pandas_spec is not None:
409
+ console.print("[green]✅ pandas available")
410
+ else:
411
+ console.print("[red]❌ pandas not found")
412
+ console.print(" 💡 Install with: pip install pandas")
413
+ issues_found += 1
414
+
415
+ yaml_spec = importlib.util.find_spec("yaml")
416
+ if yaml_spec is not None:
417
+ console.print("[green]✅ PyYAML available")
418
+ else:
419
+ console.print("[yellow]⚠️ PyYAML not found (optional)")
420
+ console.print(" 💡 Install with: pip install pyyaml")
421
+
422
+ # Summary
423
+ console.print("\n[cyan]📊 Summary")
424
+ if issues_found == 0:
425
+ console.print(
426
+ "[bold green]✅ All checks passed! You're ready to use HackAgent."
427
+ )
428
+ else:
429
+ console.print(
430
+ f"[bold yellow]⚠️ Found {issues_found} issue(s) that should be addressed."
431
+ )
432
+ console.print("\n[cyan]💡 Quick fixes:")
433
+ console.print(" hackagent init # Interactive setup")
434
+ console.print(" hackagent config set # Set specific values")
435
+ console.print(" hackagent --help # Show all commands")
436
+
437
+
438
+ def _launch_tui_default(ctx):
439
+ """Launch TUI by default when no subcommand is provided"""
440
+ cli_config: CLIConfig = ctx.obj["config"]
441
+
442
+ try:
443
+ # Try to validate configuration
444
+ cli_config.validate()
445
+ except ValueError:
446
+ # If validation fails, show welcome message instead
447
+ console.print(
448
+ "[yellow]⚠️ Configuration not complete. Please set up your API key first.[/yellow]"
449
+ )
450
+ console.print()
451
+ _display_welcome()
452
+ console.print()
453
+ console.print(
454
+ "[cyan]Run '[bold]hackagent init[/bold]' to get started, or '[bold]hackagent --help[/bold]' for more options.[/cyan]"
455
+ )
456
+ return
457
+
458
+ try:
459
+ from hackagent.cli.tui import HackAgentTUI
460
+
461
+ # Launch TUI
462
+ app = HackAgentTUI(cli_config)
463
+ app.run()
464
+
465
+ except ImportError:
466
+ console.print("[bold red]❌ TUI dependencies not installed[/bold red]")
467
+ console.print("\n[cyan]💡 Install with:[/cyan]")
468
+ console.print(" uv add textual")
469
+ console.print(" # or")
470
+ console.print(" pip install textual")
471
+ ctx.exit(1)
472
+ except Exception as e:
473
+ console.print(f"[bold red]❌ TUI failed to start: {e}[/bold red]")
474
+ console.print("\n[cyan]You can still use CLI commands:[/cyan]")
475
+ console.print(" hackagent --help")
476
+ ctx.exit(1)
477
+
478
+
479
+ def _display_welcome():
480
+ """Display welcome message and basic usage info"""
481
+
482
+ # Display HackAgent splash
483
+ from hackagent.utils import display_hackagent_splash
484
+
485
+ display_hackagent_splash()
486
+
487
+ welcome_text = """[bold cyan]Welcome to HackAgent CLI![/bold cyan] 🔍
488
+
489
+ [green]A powerful toolkit for testing AI agent security through automated attacks.[/green]
490
+
491
+ [bold yellow]🚀 Getting Started:[/bold yellow]
492
+ 1. Set up your API key: [cyan]hackagent init[/cyan]
493
+ 2. Launch full-screen TUI: [cyan]hackagent[/cyan] (default) or [cyan]hackagent tui[/cyan]
494
+ 3. List available agents: [cyan]hackagent agent list[/cyan]
495
+ 4. Run security tests: [cyan]hackagent attack advprefix --help[/cyan]
496
+ 5. View results: [cyan]hackagent results list[/cyan]
497
+
498
+ [bold blue]💡 Need help?[/bold blue] Use '[cyan]hackagent --help[/cyan]' or '[cyan]hackagent COMMAND --help[/cyan]'
499
+ [bold blue]🌐 Get your API key at:[/bold blue] [link=https://app.hackagent.dev]https://app.hackagent.dev[/link]"""
500
+
501
+ panel = Panel(
502
+ welcome_text, title="🔍 HackAgent CLI", border_style="red", padding=(1, 2)
503
+ )
504
+ console.print(panel)
505
+
506
+
507
+ # Add command groups
508
+ cli.add_command(config.config)
509
+ cli.add_command(agent.agent)
510
+ cli.add_command(attack.attack)
511
+ cli.add_command(results.results)
512
+
513
+
514
+ if __name__ == "__main__":
515
+ cli()
@@ -0,0 +1,31 @@
1
+ # Copyright 2025 - AI4I. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ Terminal User Interface (TUI)
17
+
18
+ Full-featured terminal interface for HackAgent with tabbed navigation,
19
+ real-time attack monitoring, and interactive configuration.
20
+
21
+ Structure:
22
+ - app.py: Main TUI application class
23
+ - base.py: Base widgets and utilities
24
+ - logger.py: TUI logging handler for attack execution logs
25
+ - views/: Tab views (dashboard, agents, attacks, results, config)
26
+ - widgets/: Reusable UI components (log viewer, etc.)
27
+ """
28
+
29
+ from hackagent.cli.tui.app import HackAgentTUI
30
+
31
+ __all__ = ["HackAgentTUI"]