janexai 0.1.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.
janexai-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: janexai
3
+ Version: 0.1.0
4
+ Summary: AI-powered code security and quality analysis CLI
5
+ Author-email: JanexAI Team <hello@janex.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://janex.ai
8
+ Project-URL: Documentation, https://docs.janex.ai
9
+ Project-URL: Repository, https://github.com/janexai/janex-cli
10
+ Project-URL: Issues, https://github.com/janexai/janex-cli/issues
11
+ Keywords: security,code-analysis,ai,llm,cli
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Security
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ Requires-Dist: typer>=0.9.0
27
+ Requires-Dist: rich>=13.0.0
28
+ Requires-Dist: requests>=2.28.0
29
+
30
+ # JanexAI CLI
31
+
32
+ AI-powered code security and quality analysis from your terminal.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install janexai
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ```bash
43
+ # Scan a public repository
44
+ janex scan https://github.com/user/repo
45
+
46
+ # Or use owner/repo format
47
+ janex scan user/repo
48
+
49
+ # Save report to file
50
+ janex scan user/repo -o report.json
51
+ ```
52
+
53
+ ## Authentication
54
+
55
+ For private repositories or higher rate limits, authenticate with your API token:
56
+
57
+ ```bash
58
+ janex login --token YOUR_API_TOKEN
59
+ ```
60
+
61
+ Get your token at [janex.ai/settings](https://janex.ai/settings)
62
+
63
+ ## Commands
64
+
65
+ ### `janex scan`
66
+
67
+ Scan a repository for security and quality issues.
68
+
69
+ ```bash
70
+ janex scan <repo> [OPTIONS]
71
+
72
+ Arguments:
73
+ repo GitHub repo URL or owner/repo format
74
+
75
+ Options:
76
+ -o, --output Save report to JSON file
77
+ --no-claude Skip Claude AI analysis (faster)
78
+ -v, --verbose Verbose output
79
+ ```
80
+
81
+ ### `janex login`
82
+
83
+ Authenticate with your API token.
84
+
85
+ ```bash
86
+ janex login --token YOUR_TOKEN
87
+ ```
88
+
89
+ ### `janex config`
90
+
91
+ Configure CLI settings.
92
+
93
+ ```bash
94
+ # Show current config
95
+ janex config --show
96
+
97
+ # Set custom API URL (for self-hosted)
98
+ janex config --api-url https://your-server.com
99
+ ```
100
+
101
+ ### `janex version`
102
+
103
+ Show CLI version.
104
+
105
+ ## Environment Variables
106
+
107
+ - `JANEX_API_TOKEN` - API token (alternative to `janex login`)
108
+ - `JANEX_API_URL` - Custom API URL (for self-hosted instances)
109
+
110
+ ## Example Output
111
+
112
+ ```
113
+ ╭──────────────── JanexAI ─────────────────╮
114
+ │ Scanning repository: vercel/next.js │
115
+ ╰──────────────────────────────────────────╯
116
+
117
+ ✓ Repository ingested (2,847 files)
118
+ ✓ Analysis complete!
119
+
120
+ Scores
121
+ ┏━━━━━━━━━━┳━━━━━━━━┓
122
+ ┃ Category ┃ Score ┃
123
+ ┡━━━━━━━━━━╇━━━━━━━━┩
124
+ │ Security │ 85/100 │
125
+ │ Quality │ 78/100 │
126
+ └──────────┴────────┘
127
+
128
+ Security Findings
129
+ ┏━━━━━━━━━━┳━━━━━━━┓
130
+ ┃ Severity ┃ Count ┃
131
+ ┡━━━━━━━━━━╇━━━━━━━┩
132
+ │ Medium │ 3 │
133
+ │ Low │ 12 │
134
+ └──────────┴───────┘
135
+
136
+ ✓ No critical security issues found
137
+
138
+ ╭─────────── Architecture Summary ───────────╮
139
+ │ Next.js app with App Router architecture. │
140
+ │ Uses React Server Components with proper │
141
+ │ data fetching patterns... │
142
+ ╰────────────────────────────────────────────╯
143
+ ```
144
+
145
+ ## License
146
+
147
+ MIT
@@ -0,0 +1,118 @@
1
+ # JanexAI CLI
2
+
3
+ AI-powered code security and quality analysis from your terminal.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install janexai
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Scan a public repository
15
+ janex scan https://github.com/user/repo
16
+
17
+ # Or use owner/repo format
18
+ janex scan user/repo
19
+
20
+ # Save report to file
21
+ janex scan user/repo -o report.json
22
+ ```
23
+
24
+ ## Authentication
25
+
26
+ For private repositories or higher rate limits, authenticate with your API token:
27
+
28
+ ```bash
29
+ janex login --token YOUR_API_TOKEN
30
+ ```
31
+
32
+ Get your token at [janex.ai/settings](https://janex.ai/settings)
33
+
34
+ ## Commands
35
+
36
+ ### `janex scan`
37
+
38
+ Scan a repository for security and quality issues.
39
+
40
+ ```bash
41
+ janex scan <repo> [OPTIONS]
42
+
43
+ Arguments:
44
+ repo GitHub repo URL or owner/repo format
45
+
46
+ Options:
47
+ -o, --output Save report to JSON file
48
+ --no-claude Skip Claude AI analysis (faster)
49
+ -v, --verbose Verbose output
50
+ ```
51
+
52
+ ### `janex login`
53
+
54
+ Authenticate with your API token.
55
+
56
+ ```bash
57
+ janex login --token YOUR_TOKEN
58
+ ```
59
+
60
+ ### `janex config`
61
+
62
+ Configure CLI settings.
63
+
64
+ ```bash
65
+ # Show current config
66
+ janex config --show
67
+
68
+ # Set custom API URL (for self-hosted)
69
+ janex config --api-url https://your-server.com
70
+ ```
71
+
72
+ ### `janex version`
73
+
74
+ Show CLI version.
75
+
76
+ ## Environment Variables
77
+
78
+ - `JANEX_API_TOKEN` - API token (alternative to `janex login`)
79
+ - `JANEX_API_URL` - Custom API URL (for self-hosted instances)
80
+
81
+ ## Example Output
82
+
83
+ ```
84
+ ╭──────────────── JanexAI ─────────────────╮
85
+ │ Scanning repository: vercel/next.js │
86
+ ╰──────────────────────────────────────────╯
87
+
88
+ ✓ Repository ingested (2,847 files)
89
+ ✓ Analysis complete!
90
+
91
+ Scores
92
+ ┏━━━━━━━━━━┳━━━━━━━━┓
93
+ ┃ Category ┃ Score ┃
94
+ ┡━━━━━━━━━━╇━━━━━━━━┩
95
+ │ Security │ 85/100 │
96
+ │ Quality │ 78/100 │
97
+ └──────────┴────────┘
98
+
99
+ Security Findings
100
+ ┏━━━━━━━━━━┳━━━━━━━┓
101
+ ┃ Severity ┃ Count ┃
102
+ ┡━━━━━━━━━━╇━━━━━━━┩
103
+ │ Medium │ 3 │
104
+ │ Low │ 12 │
105
+ └──────────┴───────┘
106
+
107
+ ✓ No critical security issues found
108
+
109
+ ╭─────────── Architecture Summary ───────────╮
110
+ │ Next.js app with App Router architecture. │
111
+ │ Uses React Server Components with proper │
112
+ │ data fetching patterns... │
113
+ ╰────────────────────────────────────────────╯
114
+ ```
115
+
116
+ ## License
117
+
118
+ MIT
@@ -0,0 +1,3 @@
1
+ """JanexAI CLI - AI-powered code security and quality analysis."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,402 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ JanexAI CLI - Scan repositories for security and quality issues.
4
+
5
+ Usage:
6
+ janex scan https://github.com/user/repo
7
+ janex scan owner/repo
8
+ """
9
+
10
+ import os
11
+ import re
12
+ import sys
13
+ import json
14
+ import time
15
+ from pathlib import Path
16
+
17
+ import typer
18
+ import requests
19
+ from rich.console import Console
20
+ from rich.progress import Progress, SpinnerColumn, TextColumn
21
+ from rich.panel import Panel
22
+ from rich.table import Table
23
+ from rich import print as rprint
24
+
25
+ from . import __version__
26
+
27
+ # API Configuration
28
+ DEFAULT_API_URL = "https://trust-layer-ai.onrender.com"
29
+ CONFIG_DIR = Path.home() / ".janex"
30
+ CONFIG_FILE = CONFIG_DIR / "config.json"
31
+
32
+ app = typer.Typer(
33
+ name="janex",
34
+ help="JanexAI - AI-powered code security and quality analysis",
35
+ add_completion=False,
36
+ )
37
+ console = Console()
38
+
39
+
40
+ def get_config() -> dict:
41
+ """Load config from ~/.janex/config.json"""
42
+ if CONFIG_FILE.exists():
43
+ try:
44
+ return json.loads(CONFIG_FILE.read_text())
45
+ except Exception:
46
+ return {}
47
+ return {}
48
+
49
+
50
+ def save_config(config: dict):
51
+ """Save config to ~/.janex/config.json with secure permissions."""
52
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True, mode=0o700)
53
+ CONFIG_FILE.write_text(json.dumps(config, indent=2))
54
+ # Restrict file permissions to owner only (Unix)
55
+ try:
56
+ CONFIG_FILE.chmod(0o600)
57
+ except Exception:
58
+ pass # Windows doesn't support chmod the same way
59
+
60
+
61
+ def get_api_url() -> str:
62
+ """Get API URL from config or environment."""
63
+ return os.getenv("JANEX_API_URL") or get_config().get("api_url") or DEFAULT_API_URL
64
+
65
+
66
+ def get_api_token() -> str | None:
67
+ """Get API token from config or environment."""
68
+ return os.getenv("JANEX_API_TOKEN") or get_config().get("api_token")
69
+
70
+
71
+ def parse_repo_url(repo_input: str) -> tuple[str, str]:
72
+ """Parse GitHub URL or owner/repo format into (owner, repo)."""
73
+ # Handle full GitHub URLs
74
+ github_patterns = [
75
+ r'https?://github\.com/([^/]+)/([^/]+?)(?:\.git)?/?$',
76
+ r'git@github\.com:([^/]+)/([^/]+?)(?:\.git)?$',
77
+ ]
78
+
79
+ for pattern in github_patterns:
80
+ match = re.match(pattern, repo_input)
81
+ if match:
82
+ return match.group(1), match.group(2)
83
+
84
+ # Handle owner/repo format
85
+ if '/' in repo_input and not repo_input.startswith('http'):
86
+ parts = repo_input.split('/')
87
+ if len(parts) == 2:
88
+ return parts[0], parts[1]
89
+
90
+ raise typer.BadParameter(
91
+ f"Invalid repository format: {repo_input}\n"
92
+ "Use: https://github.com/owner/repo or owner/repo"
93
+ )
94
+
95
+
96
+ def api_request(
97
+ method: str,
98
+ endpoint: str,
99
+ data: dict = None,
100
+ timeout: int = 300,
101
+ ) -> requests.Response:
102
+ """Make an authenticated API request."""
103
+ api_url = get_api_url()
104
+ token = get_api_token()
105
+
106
+ # Security: Enforce HTTPS for non-localhost URLs
107
+ if not api_url.startswith("https://") and "localhost" not in api_url and "127.0.0.1" not in api_url:
108
+ console.print("[red]Error:[/red] API URL must use HTTPS for security.")
109
+ console.print(f"Current URL: {api_url}")
110
+ raise typer.Exit(1)
111
+
112
+ headers = {"Content-Type": "application/json"}
113
+ if token:
114
+ headers["Authorization"] = f"Bearer {token}"
115
+
116
+ url = f"{api_url}/api{endpoint}"
117
+
118
+ try:
119
+ if method == "GET":
120
+ response = requests.get(url, headers=headers, timeout=timeout)
121
+ elif method == "POST":
122
+ response = requests.post(url, headers=headers, json=data, timeout=timeout)
123
+ else:
124
+ raise ValueError(f"Unsupported method: {method}")
125
+
126
+ return response
127
+ except requests.exceptions.SSLError as e:
128
+ console.print("[red]SSL Error:[/red] Could not verify server certificate.")
129
+ console.print("This could indicate a man-in-the-middle attack.")
130
+ raise typer.Exit(1)
131
+ except requests.exceptions.ConnectionError:
132
+ console.print(f"[red]Error:[/red] Could not connect to {api_url}")
133
+ console.print("Check your internet connection or API URL.")
134
+ raise typer.Exit(1)
135
+ except requests.exceptions.Timeout:
136
+ console.print("[red]Error:[/red] Request timed out")
137
+ raise typer.Exit(1)
138
+
139
+
140
+ @app.command()
141
+ def login(
142
+ token: str = typer.Option(None, "--token", "-t", help="API token (prefer interactive prompt for security)"),
143
+ ):
144
+ """
145
+ Login with your JanexAI API token.
146
+
147
+ Get your token at: https://janex.ai/settings
148
+
149
+ For better security, run without --token flag to enter interactively,
150
+ or use JANEX_API_TOKEN environment variable.
151
+ """
152
+ if token:
153
+ # Warn about command-line token visibility
154
+ console.print("[yellow]Warning:[/yellow] Token passed via command line may be visible in shell history.")
155
+ console.print("Consider using interactive login or JANEX_API_TOKEN env variable instead.\n")
156
+ else:
157
+ token = typer.prompt("Enter your API token", hide_input=True)
158
+
159
+ if not token or len(token) < 10:
160
+ console.print("[red]Error:[/red] Invalid token format")
161
+ raise typer.Exit(1)
162
+
163
+ # Save config with secure permissions
164
+ config = get_config()
165
+ config["api_token"] = token
166
+ save_config(config)
167
+
168
+ # Test the token
169
+ response = api_request("GET", "/health/")
170
+ if response.status_code == 200:
171
+ console.print("[green]✓[/green] Successfully logged in!")
172
+ console.print(f"Config saved to: {CONFIG_FILE}")
173
+ else:
174
+ console.print("[yellow]Token saved, but could not verify.[/yellow]")
175
+
176
+
177
+ @app.command()
178
+ def logout():
179
+ """Logout and remove stored credentials."""
180
+ config = get_config()
181
+ if "api_token" in config:
182
+ del config["api_token"]
183
+ save_config(config)
184
+ console.print("[green]✓[/green] Logged out")
185
+
186
+
187
+ @app.command()
188
+ def config(
189
+ api_url: str = typer.Option(None, "--api-url", help="Set custom API URL"),
190
+ show: bool = typer.Option(False, "--show", help="Show current config"),
191
+ ):
192
+ """Configure JanexAI CLI settings."""
193
+ cfg = get_config()
194
+
195
+ if show:
196
+ console.print(Panel(
197
+ f"API URL: {get_api_url()}\n"
198
+ f"Token: {'********' if get_api_token() else '(not set)'}",
199
+ title="Configuration",
200
+ ))
201
+ return
202
+
203
+ if api_url:
204
+ cfg["api_url"] = api_url
205
+ save_config(cfg)
206
+ console.print(f"[green]✓[/green] API URL set to: {api_url}")
207
+
208
+
209
+ @app.command()
210
+ def scan(
211
+ repo: str = typer.Argument(..., help="GitHub repo URL or owner/repo"),
212
+ output: str = typer.Option(None, "--output", "-o", help="Output file (JSON)"),
213
+ no_claude: bool = typer.Option(False, "--no-claude", help="Skip Claude analysis"),
214
+ watch: bool = typer.Option(False, "--watch", "-w", help="Watch and wait for results"),
215
+ verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
216
+ ):
217
+ """
218
+ Scan a GitHub repository for security and quality issues.
219
+
220
+ Examples:
221
+ janex scan https://github.com/user/repo
222
+ janex scan user/repo
223
+ janex scan user/repo -o report.json
224
+ """
225
+ try:
226
+ owner, repo_name = parse_repo_url(repo)
227
+ except typer.BadParameter as e:
228
+ console.print(f"[red]Error:[/red] {e}")
229
+ raise typer.Exit(1)
230
+
231
+ full_name = f"{owner}/{repo_name}"
232
+
233
+ console.print(Panel(
234
+ f"[bold]Scanning repository:[/bold] {full_name}",
235
+ title="JanexAI",
236
+ border_style="blue"
237
+ ))
238
+
239
+ try:
240
+ with Progress(
241
+ SpinnerColumn(),
242
+ TextColumn("[progress.description]{task.description}"),
243
+ console=console,
244
+ ) as progress:
245
+
246
+ # Step 1: Ingest repository
247
+ task = progress.add_task("Ingesting repository...", total=None)
248
+
249
+ response = api_request("POST", "/repositories/ingest/", {
250
+ "owner": owner,
251
+ "repo": repo_name,
252
+ }, timeout=120)
253
+
254
+ if response.status_code == 401:
255
+ console.print("\n[red]Error:[/red] Authentication required.")
256
+ console.print("Run [bold]janex login[/bold] to authenticate.")
257
+ raise typer.Exit(1)
258
+
259
+ if response.status_code not in (200, 201):
260
+ error = response.json().get("error", response.text)
261
+ console.print(f"\n[red]Error:[/red] {error}")
262
+ raise typer.Exit(1)
263
+
264
+ ingest_data = response.json()
265
+ repo_id = ingest_data.get("repository_id")
266
+
267
+ if not repo_id:
268
+ console.print("[red]Error:[/red] No repository ID returned")
269
+ raise typer.Exit(1)
270
+
271
+ progress.update(task, description=f"[green]✓[/green] Repository ingested ({ingest_data.get('files_count', 0)} files)")
272
+
273
+ if verbose:
274
+ console.print(f" Commit: {ingest_data.get('commit_sha', 'unknown')[:8]}")
275
+
276
+ # Step 2: Run analysis
277
+ progress.update(task, description="Running security & quality analysis...")
278
+
279
+ analyze_response = api_request("POST", f"/repositories/{repo_id}/analyze/", {
280
+ "use_claude": not no_claude,
281
+ }, timeout=600) # 10 min timeout for analysis
282
+
283
+ if analyze_response.status_code != 200:
284
+ error = analyze_response.json().get("error", analyze_response.text)
285
+ console.print(f"\n[red]Analysis Error:[/red] {error}")
286
+ raise typer.Exit(1)
287
+
288
+ report = analyze_response.json()
289
+
290
+ progress.update(task, description="[green]✓[/green] Analysis complete!")
291
+
292
+ # Output results
293
+ if output:
294
+ output_path = Path(output).resolve()
295
+ # Basic safety check - don't write to system directories
296
+ unsafe_prefixes = ['/etc', '/usr', '/bin', '/sbin', '/var', '/System', 'C:\\Windows']
297
+ if any(str(output_path).startswith(prefix) for prefix in unsafe_prefixes):
298
+ console.print(f"[red]Error:[/red] Cannot write to system directory: {output_path}")
299
+ raise typer.Exit(1)
300
+
301
+ with open(output_path, 'w') as f:
302
+ json.dump(report, f, indent=2, default=str)
303
+ console.print(f"\n[green]Report saved to:[/green] {output_path}")
304
+
305
+ # Display summary
306
+ display_summary(report)
307
+
308
+ except requests.exceptions.RequestException as e:
309
+ console.print(f"[red]Request Error:[/red] {e}")
310
+ raise typer.Exit(1)
311
+
312
+
313
+ def display_summary(report: dict):
314
+ """Display a summary of the scan results."""
315
+ console.print()
316
+
317
+ # Overall scores
318
+ security_score = report.get("security_score", 0)
319
+ quality_score = report.get("quality_score", 0)
320
+
321
+ # Score colors
322
+ def score_color(score):
323
+ if score >= 80:
324
+ return "green"
325
+ elif score >= 60:
326
+ return "yellow"
327
+ return "red"
328
+
329
+ scores_table = Table(title="Scores", show_header=True)
330
+ scores_table.add_column("Category", style="bold")
331
+ scores_table.add_column("Score", justify="right")
332
+
333
+ scores_table.add_row(
334
+ "Security",
335
+ f"[{score_color(security_score)}]{security_score}/100[/{score_color(security_score)}]"
336
+ )
337
+ scores_table.add_row(
338
+ "Quality",
339
+ f"[{score_color(quality_score)}]{quality_score}/100[/{score_color(quality_score)}]"
340
+ )
341
+
342
+ console.print(scores_table)
343
+ console.print()
344
+
345
+ # Security findings
346
+ security = report.get("security_summary", {})
347
+ high_count = security.get("high_severity_count", 0)
348
+ medium_count = security.get("medium_severity_count", 0)
349
+ low_count = security.get("low_severity_count", 0)
350
+
351
+ if high_count or medium_count or low_count:
352
+ security_table = Table(title="Security Findings", show_header=True)
353
+ security_table.add_column("Severity", style="bold")
354
+ security_table.add_column("Count", justify="right")
355
+
356
+ if high_count > 0:
357
+ security_table.add_row("[red]High[/red]", str(high_count))
358
+ if medium_count > 0:
359
+ security_table.add_row("[yellow]Medium[/yellow]", str(medium_count))
360
+ if low_count > 0:
361
+ security_table.add_row("[green]Low[/green]", str(low_count))
362
+
363
+ console.print(security_table)
364
+ else:
365
+ console.print("[green]✓ No security issues found[/green]")
366
+
367
+ console.print()
368
+
369
+ # Quality findings
370
+ quality = report.get("quality_summary", {})
371
+ quality_count = quality.get("total_findings", 0)
372
+
373
+ if quality_count:
374
+ console.print(f"[yellow]Quality issues:[/yellow] {quality_count}")
375
+ else:
376
+ console.print("[green]✓ No quality issues found[/green]")
377
+
378
+ console.print()
379
+
380
+ # Architecture summary
381
+ arch_summary = report.get("arch_summary")
382
+ if arch_summary:
383
+ console.print(Panel(
384
+ arch_summary[:600] + "..." if len(arch_summary) > 600 else arch_summary,
385
+ title="Architecture Summary",
386
+ border_style="blue"
387
+ ))
388
+
389
+
390
+ @app.command()
391
+ def version():
392
+ """Show version information."""
393
+ console.print(f"JanexAI CLI v{__version__}")
394
+
395
+
396
+ def main():
397
+ """Entry point for the CLI."""
398
+ app()
399
+
400
+
401
+ if __name__ == "__main__":
402
+ main()
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.4
2
+ Name: janexai
3
+ Version: 0.1.0
4
+ Summary: AI-powered code security and quality analysis CLI
5
+ Author-email: JanexAI Team <hello@janex.ai>
6
+ License: MIT
7
+ Project-URL: Homepage, https://janex.ai
8
+ Project-URL: Documentation, https://docs.janex.ai
9
+ Project-URL: Repository, https://github.com/janexai/janex-cli
10
+ Project-URL: Issues, https://github.com/janexai/janex-cli/issues
11
+ Keywords: security,code-analysis,ai,llm,cli
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Security
23
+ Classifier: Topic :: Software Development :: Quality Assurance
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ Requires-Dist: typer>=0.9.0
27
+ Requires-Dist: rich>=13.0.0
28
+ Requires-Dist: requests>=2.28.0
29
+
30
+ # JanexAI CLI
31
+
32
+ AI-powered code security and quality analysis from your terminal.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install janexai
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ```bash
43
+ # Scan a public repository
44
+ janex scan https://github.com/user/repo
45
+
46
+ # Or use owner/repo format
47
+ janex scan user/repo
48
+
49
+ # Save report to file
50
+ janex scan user/repo -o report.json
51
+ ```
52
+
53
+ ## Authentication
54
+
55
+ For private repositories or higher rate limits, authenticate with your API token:
56
+
57
+ ```bash
58
+ janex login --token YOUR_API_TOKEN
59
+ ```
60
+
61
+ Get your token at [janex.ai/settings](https://janex.ai/settings)
62
+
63
+ ## Commands
64
+
65
+ ### `janex scan`
66
+
67
+ Scan a repository for security and quality issues.
68
+
69
+ ```bash
70
+ janex scan <repo> [OPTIONS]
71
+
72
+ Arguments:
73
+ repo GitHub repo URL or owner/repo format
74
+
75
+ Options:
76
+ -o, --output Save report to JSON file
77
+ --no-claude Skip Claude AI analysis (faster)
78
+ -v, --verbose Verbose output
79
+ ```
80
+
81
+ ### `janex login`
82
+
83
+ Authenticate with your API token.
84
+
85
+ ```bash
86
+ janex login --token YOUR_TOKEN
87
+ ```
88
+
89
+ ### `janex config`
90
+
91
+ Configure CLI settings.
92
+
93
+ ```bash
94
+ # Show current config
95
+ janex config --show
96
+
97
+ # Set custom API URL (for self-hosted)
98
+ janex config --api-url https://your-server.com
99
+ ```
100
+
101
+ ### `janex version`
102
+
103
+ Show CLI version.
104
+
105
+ ## Environment Variables
106
+
107
+ - `JANEX_API_TOKEN` - API token (alternative to `janex login`)
108
+ - `JANEX_API_URL` - Custom API URL (for self-hosted instances)
109
+
110
+ ## Example Output
111
+
112
+ ```
113
+ ╭──────────────── JanexAI ─────────────────╮
114
+ │ Scanning repository: vercel/next.js │
115
+ ╰──────────────────────────────────────────╯
116
+
117
+ ✓ Repository ingested (2,847 files)
118
+ ✓ Analysis complete!
119
+
120
+ Scores
121
+ ┏━━━━━━━━━━┳━━━━━━━━┓
122
+ ┃ Category ┃ Score ┃
123
+ ┡━━━━━━━━━━╇━━━━━━━━┩
124
+ │ Security │ 85/100 │
125
+ │ Quality │ 78/100 │
126
+ └──────────┴────────┘
127
+
128
+ Security Findings
129
+ ┏━━━━━━━━━━┳━━━━━━━┓
130
+ ┃ Severity ┃ Count ┃
131
+ ┡━━━━━━━━━━╇━━━━━━━┩
132
+ │ Medium │ 3 │
133
+ │ Low │ 12 │
134
+ └──────────┴───────┘
135
+
136
+ ✓ No critical security issues found
137
+
138
+ ╭─────────── Architecture Summary ───────────╮
139
+ │ Next.js app with App Router architecture. │
140
+ │ Uses React Server Components with proper │
141
+ │ data fetching patterns... │
142
+ ╰────────────────────────────────────────────╯
143
+ ```
144
+
145
+ ## License
146
+
147
+ MIT
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ janex/__init__.py
4
+ janex/main.py
5
+ janexai.egg-info/PKG-INFO
6
+ janexai.egg-info/SOURCES.txt
7
+ janexai.egg-info/dependency_links.txt
8
+ janexai.egg-info/entry_points.txt
9
+ janexai.egg-info/requires.txt
10
+ janexai.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ janex = janex.main:main
@@ -0,0 +1,3 @@
1
+ typer>=0.9.0
2
+ rich>=13.0.0
3
+ requests>=2.28.0
@@ -0,0 +1 @@
1
+ janex
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "janexai"
7
+ version = "0.1.0"
8
+ description = "AI-powered code security and quality analysis CLI"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "JanexAI Team", email = "hello@janex.ai"}
14
+ ]
15
+ keywords = ["security", "code-analysis", "ai", "llm", "cli"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.9",
24
+ "Programming Language :: Python :: 3.10",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Programming Language :: Python :: 3.12",
27
+ "Topic :: Security",
28
+ "Topic :: Software Development :: Quality Assurance",
29
+ ]
30
+
31
+ dependencies = [
32
+ "typer>=0.9.0",
33
+ "rich>=13.0.0",
34
+ "requests>=2.28.0",
35
+ ]
36
+
37
+ [project.scripts]
38
+ janex = "janex.main:main"
39
+
40
+ [project.urls]
41
+ Homepage = "https://janex.ai"
42
+ Documentation = "https://docs.janex.ai"
43
+ Repository = "https://github.com/janexai/janex-cli"
44
+ Issues = "https://github.com/janexai/janex-cli/issues"
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["."]
48
+ include = ["janex*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+