maya-cli 0.1.1__py3-none-any.whl → 0.1.3__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.
maya_cli/cli.py CHANGED
@@ -1,16 +1,33 @@
1
1
  import os
2
+ import sys
2
3
  import click
3
4
  import logging
5
+ import importlib.util
6
+ from dotenv import load_dotenv, set_key
7
+ import openai
4
8
  from .project_generator import create_project_structure, PROJECT_STRUCTURE
9
+ from .refactor import process_directory
10
+ from maya_cli.scripts import optimize # This will trigger optimize_event_handler automatically
11
+
5
12
 
6
13
  # Setup logging
7
- logging.basicConfig(filename="maya_cli.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
14
+ LOG_FILE = "maya_cli.log"
15
+ logging.basicConfig(
16
+ filename=LOG_FILE,
17
+ level=logging.DEBUG,
18
+ format="%(asctime)s - %(levelname)s - %(message)s"
19
+ )
20
+
21
+ # Load environment variables from .env
22
+ load_dotenv()
23
+
8
24
 
9
25
  @click.group()
10
26
  def maya():
11
27
  """Maya CLI - AI Project Generator"""
12
28
  pass
13
29
 
30
+
14
31
  @click.command()
15
32
  @click.argument("project_name")
16
33
  def create(project_name):
@@ -26,12 +43,525 @@ def create(project_name):
26
43
  create_project_structure(base_path, PROJECT_STRUCTURE)
27
44
  click.echo(f"✅ AI project '{project_name}' created successfully!")
28
45
  logging.info(f"Project '{project_name}' created successfully at {base_path}")
29
-
46
+
30
47
  except Exception as e:
31
48
  logging.error(f"Error while creating project: {str(e)}")
32
49
  click.echo(f"❌ An error occurred: {str(e)}")
33
50
 
51
+ @click.command()
52
+ @click.argument("path", nargs=-1, required=True)
53
+ def check_best_practices(path):
54
+ """CLI Command: maya check-best-practices [folder] [sub-folder] ... [filename]"""
55
+ click.echo("🚀 Running Best Practices Check...")
56
+
57
+ base_path = os.getcwd()
58
+ target_path = os.path.join(base_path, *path)
59
+
60
+ if not os.path.exists(target_path):
61
+ click.echo(f"❌ Path '{target_path}' does not exist.")
62
+ return
63
+
64
+ if os.path.isdir(target_path):
65
+ process_directory(target_path)
66
+ elif os.path.isfile(target_path):
67
+ process_directory(os.path.dirname(target_path), os.path.basename(target_path))
68
+ else:
69
+ click.echo("❌ Invalid path provided.")
70
+ return
71
+
72
+ click.echo("✅ Best practices check completed!")
73
+
74
+
75
+ @click.command()
76
+ @click.argument("key")
77
+ @click.argument("value")
78
+ def set_env(key, value):
79
+ """Set an environment variable in .env file"""
80
+ env_file = ".env"
81
+
82
+ try:
83
+ if not os.path.exists(env_file):
84
+ with open(env_file, "w") as f:
85
+ f.write("# Maya CLI Environment Variables\n")
86
+ logging.info("Created new .env file.")
87
+
88
+ set_key(env_file, key, value)
89
+ click.echo(f"✅ Environment variable '{key}' set successfully!")
90
+ logging.info(f"Set environment variable: {key}={value}")
91
+
92
+ except Exception as e:
93
+ logging.error(f"Error setting environment variable {key}: {str(e)}")
94
+ click.echo(f"❌ Error setting environment variable: {str(e)}")
95
+
96
+ @click.command()
97
+ @click.argument("parent_folder", required=True)
98
+ @click.argument("sub_folder", required=True)
99
+ @click.argument("filename", required=True)
100
+ def optimize(parent_folder, sub_folder, filename):
101
+ """Optimize a file by importing optimize.py from maya_cli.scripts."""
102
+
103
+ # Construct the full file path
104
+ target_path = os.path.abspath(os.path.join(parent_folder, sub_folder, filename))
105
+
106
+ if not os.path.isfile(target_path):
107
+ click.echo(f"❌ Error: '{target_path}' is not a valid file.")
108
+ logging.error(f"Invalid file provided: {target_path}")
109
+ return
110
+
111
+ # Inject the import statement into the file
112
+ inject_import(target_path)
113
+
114
+ def inject_import(filepath):
115
+ """Inject import statement for optimize.py into the target file."""
116
+ try:
117
+ import_statement = "from maya_cli.scripts import optimize\n"
118
+
119
+ with open(filepath, "r+", encoding="utf-8") as f:
120
+ content = f.readlines()
121
+
122
+ # Check if the import already exists
123
+ if any(line.strip() == import_statement.strip() for line in content):
124
+ click.echo(f"✅ {filepath} already imports optimize.py.")
125
+ return
126
+
127
+ # Insert import at the top
128
+ content.insert(0, import_statement)
129
+ f.seek(0)
130
+ f.writelines(content)
131
+
132
+ click.echo(f"✅ Imported optimize.py into {filepath}")
133
+ logging.info(f"Imported optimize.py into {filepath}")
134
+
135
+ except Exception as e:
136
+ logging.error(f"Error injecting import into '{filepath}': {str(e)}")
137
+ click.echo(f"❌ Error injecting import into '{filepath}': {str(e)}")
138
+
139
+ import os
140
+ import json
141
+ import click
142
+ import logging
143
+ import openai
144
+
145
+ @click.command()
146
+ @click.argument("parent_folder", required=True)
147
+ @click.argument("sub_folder", required=True)
148
+ @click.argument("filename", required=True)
149
+ def is_secured(parent_folder, sub_folder, filename):
150
+ """Check and enforce API security measures: Authentication, Encryption, and Rate Limiting."""
151
+ click.echo("🔍 Running API Security Check...")
152
+
153
+ # Construct the full file path
154
+ target_path = os.path.abspath(os.path.join(parent_folder, sub_folder, filename))
155
+
156
+ if not os.path.isfile(target_path):
157
+ click.echo(f"❌ Error: '{target_path}' is not a valid file.")
158
+ logging.error(f"Invalid file provided: {target_path}")
159
+ return
160
+
161
+ try:
162
+ with open(target_path, "r", encoding="utf-8") as f:
163
+ code_content = f.read()
164
+
165
+ # Validate security using AI
166
+ validation_feedback = validate_security_with_ai(code_content)
167
+ security_issues = []
168
+
169
+ if not validation_feedback.get("authentication", False):
170
+ security_issues.append(f"❌ Missing API Authentication. Applying OAuth/API Key authentication.")
171
+ apply_api_authentication(target_path)
172
+
173
+ if not validation_feedback.get("encryption", False):
174
+ security_issues.append(f"❌ Missing Data Encryption. Implementing encryption protocols.")
175
+ apply_data_encryption(target_path)
176
+
177
+ if not validation_feedback.get("rate_limiting", False):
178
+ security_issues.append(f"❌ No Rate Limiting detected. Implementing rate limiting & quotas.")
179
+ apply_rate_limiting(target_path)
180
+
181
+ if security_issues:
182
+ for issue in security_issues:
183
+ click.echo(f"⚠️ {issue}")
184
+ click.echo("✅ Security measures have been enforced!")
185
+ else:
186
+ click.echo("✅ API usage is secure. No changes needed.")
187
+
188
+ except Exception as e:
189
+ logging.error(f"❌ Error processing {target_path}: {str(e)}")
190
+ click.echo(f"❌ Error processing {target_path}: {str(e)}")
191
+
192
+ logging.info("API Security Check Completed.")
193
+
194
+
195
+ def validate_security_with_ai(code):
196
+ """Use OpenAI to validate security measures in the given code."""
197
+ prompt = f"""
198
+ Analyze the following Python code for API security vulnerabilities.
199
+ Identify if the code implements:
200
+ 1. Secure API Authentication (OAuth or API Keys)
201
+ 2. Proper Data Encryption Protocols for sensitive data
202
+ 3. Rate Limiting and Quotas to prevent API abuse
203
+
204
+ Return a JSON response with keys: authentication, encryption, rate_limiting, each set to True or False.
205
+
206
+ Code:
207
+ ```
208
+ {code}
209
+ ```
210
+ """
211
+
212
+ try:
213
+ response = openai.ChatCompletion.create(
214
+ model="gpt-4",
215
+ messages=[{"role": "system", "content": prompt}],
216
+ )
217
+
218
+ result = response["choices"][0]["message"]["content"]
219
+ return json.loads(result)
220
+
221
+ except Exception as e:
222
+ logging.error(f"Error in AI validation: {str(e)}")
223
+ return {"authentication": False, "encryption": False, "rate_limiting": False}
224
+
225
+
226
+ def apply_api_authentication(filepath):
227
+ """Apply OAuth or API Key authentication to the specified file."""
228
+ logging.info(f"Applying OAuth/API Key Authentication to {filepath}.")
229
+ with open(filepath, "a", encoding="utf-8") as f:
230
+ f.write("\n# TODO: Implement OAuth/API Key Authentication\n")
231
+
232
+
233
+ def apply_data_encryption(filepath):
234
+ """Implement data encryption protocols in the specified file."""
235
+ logging.info(f"Applying Data Encryption Protocols to {filepath}.")
236
+ with open(filepath, "a", encoding="utf-8") as f:
237
+ f.write("\n# TODO: Implement Data Encryption\n")
238
+
239
+
240
+ def apply_rate_limiting(filepath):
241
+ """Implement API rate limiting and quotas in the specified file."""
242
+ logging.info(f"Applying Rate Limiting & Quotas to {filepath}.")
243
+ with open(filepath, "a", encoding="utf-8") as f:
244
+ f.write("\n# TODO: Enforce API Rate Limiting & Quotas\n")
245
+
246
+ @click.command()
247
+ @click.argument("parent_folder", required=True)
248
+ @click.argument("sub_folder", required=True)
249
+ @click.argument("filename", required=False)
250
+ def check_ethics(parent_folder, sub_folder, filename=None):
251
+ """Check code for efficiency, accuracy, and best practices."""
252
+ click.echo("\U0001F50D Running Code Ethics Check...")
253
+ ethics_issues = []
254
+
255
+ # Construct the full path
256
+ target_path = os.path.abspath(os.path.join(parent_folder, sub_folder))
257
+
258
+ if not os.path.isdir(target_path):
259
+ click.echo(f"❌ Error: '{target_path}' is not a valid directory.")
260
+ logging.error(f"Invalid directory provided: {target_path}")
261
+ return
262
+
263
+ # Determine files to check
264
+ if filename:
265
+ files_to_check = [os.path.join(target_path, filename)]
266
+ if not os.path.isfile(files_to_check[0]):
267
+ click.echo(f"❌ Error: '{files_to_check[0]}' is not a valid file.")
268
+ logging.error(f"Invalid file provided: {files_to_check[0]}")
269
+ return
270
+ else:
271
+ files_to_check = [
272
+ os.path.join(target_path, f) for f in os.listdir(target_path) if f.endswith(".py")
273
+ ]
274
+
275
+ for file in files_to_check:
276
+ try:
277
+ with open(file, "r", encoding="utf-8") as f:
278
+ code_content = f.read()
279
+
280
+ # Validate ethics using AI
281
+ validation_feedback = validate_ethics_with_ai(code_content)
282
+
283
+ if not validation_feedback.get("efficiency", False):
284
+ ethics_issues.append(f"{file}: Code may have performance inefficiencies.")
285
+
286
+ if not validation_feedback.get("accuracy", False):
287
+ ethics_issues.append(f"{file}: Code accuracy needs review for correctness.")
288
+
289
+ if not validation_feedback.get("best_practices", False):
290
+ ethics_issues.append(f"{file}: Code may not follow industry best practices.")
291
+
292
+ except Exception as e:
293
+ logging.error(f"❌ Error processing {file}: {str(e)}")
294
+ click.echo(f"❌ Error processing {file}: {str(e)}")
295
+
296
+ if ethics_issues:
297
+ for issue in ethics_issues:
298
+ click.echo(f"⚠️ {issue}")
299
+ click.echo("✅ Ethics Review Completed with Recommendations!")
300
+ else:
301
+ click.echo("✅ Code meets ethical standards. No issues detected.")
302
+
303
+ logging.info("Code Ethics Check Completed.")
304
+
305
+
306
+ def validate_ethics_with_ai(code):
307
+ """Use OpenAI to validate code ethics, efficiency, and best practices."""
308
+ prompt = f"""
309
+ Analyze the following Python code for ethical concerns in:
310
+ 1. Efficiency (performance optimization, unnecessary loops, redundant code)
311
+ 2. Accuracy (logical correctness, potential calculation errors)
312
+ 3. Best Practices (PEP8 compliance, maintainability, documentation)
313
+
314
+ Return a JSON response with keys: efficiency, accuracy, best_practices, each set to True or False.
315
+
316
+ Code:
317
+ ```
318
+ {code}
319
+ ```
320
+ """
321
+
322
+ try:
323
+ response = openai.ChatCompletion.create(
324
+ model="gpt-4",
325
+ messages=[{"role": "system", "content": prompt}],
326
+ )
327
+
328
+ result = response["choices"][0]["message"]["content"]
329
+ return json.loads(result)
330
+
331
+ except Exception as e:
332
+ logging.error(f"Error in AI validation: {str(e)}")
333
+ return {"efficiency": False, "accuracy": False, "best_practices": False}
334
+
335
+ @click.command()
336
+ @click.argument("parent_folder")
337
+ @click.argument("sub_folder")
338
+ @click.argument("filename")
339
+ def doc(parent_folder, sub_folder, filename):
340
+ """Generate README.md documentation for the given file."""
341
+ click.echo("📄 Generating Documentation...")
342
+
343
+ # Construct the full file path
344
+ target_path = os.path.join(parent_folder, sub_folder)
345
+ file_path = os.path.join(target_path, filename)
346
+
347
+ # Validate directory existence
348
+ if not os.path.isdir(target_path):
349
+ click.echo(f"❌ Error: The directory '{target_path}' does not exist.")
350
+ return
351
+
352
+ # Validate file existence
353
+ if not os.path.isfile(file_path):
354
+ click.echo(f"❌ Error: The file '{file_path}' does not exist in the specified directory.")
355
+ return
356
+
357
+ readme_path = os.path.join(target_path, "README.md")
358
+
359
+ try:
360
+ with open(file_path, "r", encoding="utf-8") as source_file:
361
+ code_content = source_file.read()
362
+
363
+ # Generate documentation (Placeholder function, replace with AI-based generation)
364
+ documentation = generate_documentation(code_content)
365
+
366
+ # Write to README.md
367
+ with open(readme_path, "w", encoding="utf-8") as readme_file:
368
+ readme_file.write(documentation)
369
+
370
+ click.echo(f"✅ Documentation created for {file_path} -> {readme_path}")
371
+
372
+ except Exception as e:
373
+ logging.error(f"❌ Error processing {file_path}: {str(e)}")
374
+ click.echo(f"❌ Error processing {file_path}: {str(e)}")
375
+
376
+ def generate_documentation(code):
377
+ """Generate structured documentation based on the given Python code."""
378
+ return f"# Auto-Generated Documentation\n\n```python\n{code}\n```"
379
+
380
+ @click.command()
381
+ @click.argument("parent_folder")
382
+ @click.argument("sub_folder")
383
+ @click.argument("filename", required=False)
384
+ def codex(parent_folder, sub_folder, filename=None):
385
+ """Provide in-depth analysis and recommendations for a file or all Python files in a directory."""
386
+ click.echo("📚 Creating Code Codex Report...")
387
+
388
+ # Construct the full target path
389
+ target_path = os.path.join(parent_folder, sub_folder)
390
+
391
+ # Validate directory existence
392
+ if not os.path.isdir(target_path):
393
+ click.echo(f"❌ Error: The directory '{target_path}' does not exist.")
394
+ return
395
+
396
+ # Determine files to analyze
397
+ if filename:
398
+ file_path = os.path.join(target_path, filename)
399
+ if not os.path.isfile(file_path):
400
+ click.echo(f"❌ Error: The file '{file_path}' does not exist in the specified directory.")
401
+ return
402
+ files_to_analyze = [file_path]
403
+ else:
404
+ files_to_analyze = [os.path.join(target_path, f) for f in os.listdir(target_path) if f.endswith(".py")]
405
+
406
+ if not files_to_analyze:
407
+ click.echo("⚠️ No Python files found in the specified directory.")
408
+ return
409
+
410
+ for file in files_to_analyze:
411
+ codex_report_path = os.path.join(".\\docs/", "CODEX_REPORT.md")
412
+
413
+ try:
414
+ with open(file, "r", encoding="utf-8") as source_file:
415
+ code_content = source_file.read()
416
+
417
+ # Generate codex report (Placeholder function, replace with AI-based analysis)
418
+ report = generate_codex_report(code_content)
419
+
420
+ # Write report to CODEX_REPORT.md
421
+ with open(codex_report_path, "w", encoding="utf-8") as report_file:
422
+ report_file.write(report)
423
+
424
+ click.echo(f"✅ Codex Report generated for {file} -> {codex_report_path}")
425
+
426
+ except Exception as e:
427
+ logging.error(f"❌ Error processing {file}: {str(e)}")
428
+ click.echo(f"❌ Error processing {file}: {str(e)}")
429
+
430
+ def generate_codex_report(code):
431
+ """Generate an in-depth analysis and recommendations based on the given Python code."""
432
+ return f"# Code Analysis & Recommendations\n\n```python\n{code}\n```\n\n## Recommendations:\n- Improve efficiency\n- Enhance readability\n- Optimize performance\n"
433
+
434
+ @click.command()
435
+ @click.argument("parent_folder")
436
+ @click.argument("sub_folder")
437
+ @click.argument("filename", required=False)
438
+ def regulate(parent_folder, sub_folder, filename=None):
439
+ """Ensure code compliance with GDPR, CCPA, AI Act, and ISO 42001 AI governance standards."""
440
+ click.echo("🔍 Running Compliance & Regulation Check...")
441
+
442
+ compliance_issues = []
443
+
444
+ # Construct the full target path
445
+ target_path = os.path.join(parent_folder, sub_folder)
446
+
447
+ # Validate directory existence
448
+ if not os.path.isdir(target_path):
449
+ click.echo(f"❌ Error: The directory '{target_path}' does not exist.")
450
+ return
451
+
452
+ # Determine files to check
453
+ if filename:
454
+ file_path = os.path.join(target_path, filename)
455
+ if not os.path.isfile(file_path):
456
+ click.echo(f"❌ Error: The file '{file_path}' does not exist in the specified directory.")
457
+ return
458
+ files_to_check = [file_path]
459
+ else:
460
+ files_to_check = [os.path.join(target_path, f) for f in os.listdir(target_path) if f.endswith(".py")]
461
+
462
+ if not files_to_check:
463
+ click.echo("⚠️ No Python files found in the specified directory.")
464
+ return
465
+
466
+ for file in files_to_check:
467
+ compliance_report_path = os.path.join("./configs/", "COMPLIANCE_REPORT.md")
468
+
469
+ try:
470
+ with open(file, "r", encoding="utf-8") as f:
471
+ code_content = f.read()
472
+
473
+ # Validate compliance (Placeholder function, replace with AI-based analysis)
474
+ compliance_feedback = validate_compliance_with_ai(code_content)
475
+
476
+ # Track issues and apply fixes
477
+ if not compliance_feedback.get("gdpr", False):
478
+ compliance_issues.append(f"{file}: GDPR compliance issues detected. Adjusting for data privacy.")
479
+ apply_gdpr_compliance(file)
480
+
481
+ if not compliance_feedback.get("ccpa", False):
482
+ compliance_issues.append(f"{file}: CCPA compliance issues detected. Ensuring consumer rights protection.")
483
+ apply_ccpa_compliance(file)
484
+
485
+ if not compliance_feedback.get("ai_act", False):
486
+ compliance_issues.append(f"{file}: AI Act risk classification missing. Implementing compliance measures.")
487
+ apply_ai_act_compliance(file)
488
+
489
+ if not compliance_feedback.get("iso_42001", False):
490
+ compliance_issues.append(f"{file}: ISO 42001 AI governance framework not followed. Adjusting AI management protocols.")
491
+ apply_iso_42001_compliance(file)
492
+
493
+ # Generate compliance report
494
+ with open(compliance_report_path, "w", encoding="utf-8") as report_file:
495
+ report_file.write(generate_compliance_report(file, compliance_feedback))
496
+
497
+ click.echo(f"✅ Compliance report generated for {file} -> {compliance_report_path}")
498
+
499
+ except Exception as e:
500
+ logging.error(f"❌ Error processing {file}: {str(e)}")
501
+ click.echo(f"❌ Error processing {file}: {str(e)}")
502
+
503
+ if compliance_issues:
504
+ for issue in compliance_issues:
505
+ click.echo(f"⚠️ {issue}")
506
+ click.echo("✅ Compliance measures have been enforced!")
507
+ else:
508
+ click.echo("✅ Code meets all compliance regulations. No changes needed.")
509
+
510
+ logging.info("Compliance & Regulation Check Completed.")
511
+
512
+ def validate_compliance_with_ai(code):
513
+ """Analyze code for compliance with GDPR, CCPA, AI Act, and ISO 42001."""
514
+ return {
515
+ "gdpr": True,
516
+ "ccpa": True,
517
+ "ai_act": False,
518
+ "iso_42001": False
519
+ } # Replace with AI-based compliance validation
520
+
521
+ def apply_gdpr_compliance(filepath):
522
+ logging.info(f"Applying GDPR compliance to {filepath}.")
523
+
524
+ def apply_ccpa_compliance(filepath):
525
+ logging.info(f"Applying CCPA compliance to {filepath}.")
526
+
527
+ def apply_ai_act_compliance(filepath):
528
+ logging.info(f"Applying AI Act compliance to {filepath}.")
529
+
530
+ def apply_iso_42001_compliance(filepath):
531
+ logging.info(f"Applying ISO 42001 AI governance framework to {filepath}.")
532
+
533
+ def generate_compliance_report(filepath, feedback):
534
+ """Generate a structured compliance report."""
535
+ return f"""
536
+ # Compliance Report for {os.path.basename(filepath)}
537
+
538
+ ## Compliance Status:
539
+ - **GDPR:** {"✅ Compliant" if feedback.get("gdpr") else "❌ Not Compliant"}
540
+ - **CCPA:** {"✅ Compliant" if feedback.get("ccpa") else "❌ Not Compliant"}
541
+ - **AI Act:** {"✅ Compliant" if feedback.get("ai_act") else "❌ Not Compliant"}
542
+ - **ISO 42001:** {"✅ Compliant" if feedback.get("iso_42001") else "❌ Not Compliant"}
543
+
544
+ ## Recommendations:
545
+ - { "Ensure data privacy measures are in place." if not feedback.get("gdpr") else "GDPR compliance verified." }
546
+ - { "Strengthen consumer rights protection." if not feedback.get("ccpa") else "CCPA compliance verified." }
547
+ - { "Classify AI system under the AI Act risk framework." if not feedback.get("ai_act") else "AI Act compliance verified." }
548
+ - { "Align with ISO 42001 AI governance framework." if not feedback.get("iso_42001") else "ISO 42001 compliance verified." }
549
+
550
+ ---
551
+
552
+ 🛠 *Generated by Compliance Checker*
553
+ """
554
+
555
+ # Add commands to Maya CLI
556
+ maya.add_command(is_secured)
557
+ maya.add_command(check_ethics)
558
+ maya.add_command(doc)
559
+ maya.add_command(codex)
560
+ maya.add_command(regulate)
34
561
  maya.add_command(create)
562
+ maya.add_command(check_best_practices)
563
+ maya.add_command(set_env)
564
+ maya.add_command(optimize)
35
565
 
36
566
  if __name__ == "__main__":
37
567
  maya()
@@ -1,5 +1,14 @@
1
- # project_generator.py
1
+ # project_generator.py
2
2
  import os
3
+ import logging
4
+
5
+ # Configure logging
6
+ LOG_FILE = "project_generator.log"
7
+ logging.basicConfig(
8
+ filename=LOG_FILE,
9
+ level=logging.DEBUG,
10
+ format="%(asctime)s - %(levelname)s - %(message)s"
11
+ )
3
12
 
4
13
  # Define the AI Project Structure
5
14
  PROJECT_STRUCTURE = {
@@ -10,19 +19,55 @@ PROJECT_STRUCTURE = {
10
19
  "tests": {},
11
20
  "docs": {},
12
21
  "scripts": {},
13
- "configs": {}
22
+ "configs": {},
23
+ "": {"main.py", "requirements.txt"},
14
24
  }
15
25
 
16
- # Function to create folders
17
26
  def create_project_structure(base_path, structure):
18
- for folder, subfolders in structure.items():
19
- folder_path = os.path.join(base_path, folder)
20
- os.makedirs(folder_path, exist_ok=True)
21
-
22
- # Create __init__.py for package folders
23
- init_file = os.path.join(folder_path, "__init__.py")
24
- with open(init_file, "w") as f:
25
- f.write(f"# {folder.replace('_', ' ').title()} package\n")
26
-
27
- if isinstance(subfolders, dict):
28
- create_project_structure(folder_path, subfolders)
27
+ """Creates the AI project directory structure with logging and error handling."""
28
+ try:
29
+ if not os.path.exists(base_path):
30
+ os.makedirs(base_path)
31
+ logging.info(f"Created base project directory: {base_path}")
32
+
33
+ for folder, subfolders in structure.items():
34
+ folder_path = os.path.join(base_path, folder)
35
+ try:
36
+ os.makedirs(folder_path, exist_ok=True)
37
+ logging.info(f"Created folder: {folder_path}")
38
+
39
+ # Create __init__.py for package folders
40
+ init_file = os.path.join(folder_path, "__init__.py")
41
+ with open(init_file, "w") as f:
42
+ f.write(f"# {folder.replace('_', ' ').title()} package\n")
43
+ logging.info(f"Created __init__.py in: {folder_path}")
44
+
45
+ except PermissionError:
46
+ logging.error(f"Permission denied: Unable to create {folder_path}")
47
+ except Exception as e:
48
+ logging.error(f"Error creating folder {folder_path}: {str(e)}")
49
+
50
+ if isinstance(subfolders, dict):
51
+ create_project_structure(folder_path, subfolders)
52
+
53
+ # Handle single files in the root project
54
+ if isinstance(subfolders, set):
55
+ for file in subfolders:
56
+ file_path = os.path.join(base_path, file)
57
+ try:
58
+ with open(file_path, "w") as f:
59
+ f.write(f"# {file} generated by project generator\n")
60
+ logging.info(f"Created file: {file_path}")
61
+ except PermissionError:
62
+ logging.error(f"Permission denied: Unable to create {file_path}")
63
+ except Exception as e:
64
+ logging.error(f"Error creating file {file_path}: {str(e)}")
65
+
66
+ except Exception as e:
67
+ logging.critical(f"Critical error in project generation: {str(e)}")
68
+
69
+ # Example Usage
70
+ if __name__ == "__main__":
71
+ BASE_PATH = "My_AI_Project"
72
+ create_project_structure(BASE_PATH, PROJECT_STRUCTURE)
73
+ print("✅ AI project structure generated. Check logs for details.")
maya_cli/refactor.py ADDED
@@ -0,0 +1,111 @@
1
+ import os
2
+ import click
3
+ import openai
4
+ import logging
5
+
6
+ # Setup logging
7
+ LOG_FILE = "maya_refactor.log"
8
+ logging.basicConfig(
9
+ filename=LOG_FILE,
10
+ level=logging.DEBUG,
11
+ format="%(asctime)s - %(levelname)s - %(message)s"
12
+ )
13
+
14
+ # OpenAI API Key (Ensure it's set as an environment variable)
15
+ openai.api_key = os.getenv("OPENAI_API_KEY")
16
+
17
+ def read_file(file_path):
18
+ """Reads the content of a file."""
19
+ try:
20
+ with open(file_path, "r", encoding="utf-8") as file:
21
+ content = file.read()
22
+ logging.info(f"Successfully read file: {file_path}")
23
+ return content
24
+ except FileNotFoundError:
25
+ error_msg = f"❌ Error: File not found - {file_path}"
26
+ except PermissionError:
27
+ error_msg = f"❌ Error: Permission denied - {file_path}"
28
+ except Exception as e:
29
+ error_msg = f"❌ Error reading {file_path}: {str(e)}"
30
+
31
+ logging.error(error_msg)
32
+ click.echo(error_msg)
33
+ return None
34
+
35
+ def write_file(file_path, content):
36
+ """Writes content back to the file."""
37
+ try:
38
+ with open(file_path, "w", encoding="utf-8") as file:
39
+ file.write(content)
40
+ success_msg = f"✅ Refactored and updated: {file_path}"
41
+ logging.info(success_msg)
42
+ click.echo(success_msg)
43
+ except PermissionError:
44
+ error_msg = f"❌ Error: Permission denied - {file_path}"
45
+ except Exception as e:
46
+ error_msg = f"❌ Error writing {file_path}: {str(e)}"
47
+
48
+ logging.error(error_msg)
49
+ click.echo(error_msg)
50
+
51
+ def refactor_code_with_openai(code):
52
+ """Sends code to OpenAI for best-practices refactoring."""
53
+ prompt = f"""
54
+ Refactor the following Python code following best practices for AI API development:
55
+ - Clean code structure
56
+ - Improve readability & maintainability
57
+ - Optimize performance & scalability
58
+ - Ensure proper exception handling
59
+ - Secure API keys and authentication
60
+
61
+ Code:
62
+ \"\"\"{code}\"\"\"
63
+
64
+ Optimized Code:
65
+ """
66
+
67
+ try:
68
+ response = openai.ChatCompletion.create(
69
+ model="gpt-4",
70
+ messages=[
71
+ {"role": "system", "content": "You are an expert AI code reviewer."},
72
+ {"role": "user", "content": prompt}
73
+ ]
74
+ )
75
+ optimized_code = response["choices"][0]["message"]["content"].strip()
76
+ logging.debug(f"OpenAI API response received successfully.")
77
+ return optimized_code
78
+ except openai.OpenAIError as e: # Corrected
79
+ error_msg = f"❌ OpenAI API Error: {str(e)}"
80
+ except Exception as e:
81
+ error_msg = f"❌ Unexpected Error: {str(e)}"
82
+
83
+ logging.error(error_msg)
84
+ click.echo(error_msg)
85
+ return code # Return original code if API call fails
86
+
87
+
88
+ def process_directory(directory, filename=None):
89
+ """Scans the given directory and refactors specified files."""
90
+ if not os.path.exists(directory):
91
+ click.echo(f"❌ Error: Directory '{directory}' not found.")
92
+ logging.error(f"Directory '{directory}' does not exist.")
93
+ return
94
+
95
+ for root, _, files in os.walk(directory):
96
+ for file in files:
97
+ if filename and file != filename:
98
+ continue # Skip files that don't match
99
+
100
+ file_path = os.path.join(root, file)
101
+ if file.endswith(".py"): # Only process Python files
102
+ click.echo(f"🔍 Checking: {file_path}")
103
+ logging.info(f"Processing file: {file_path}")
104
+
105
+ code = read_file(file_path)
106
+ if code:
107
+ refactored_code = refactor_code_with_openai(code)
108
+ write_file(file_path, refactored_code)
109
+
110
+ click.echo("✅ Best practices check completed!")
111
+ logging.info("Best practices check completed successfully.")
@@ -0,0 +1 @@
1
+ # __init__
@@ -0,0 +1,151 @@
1
+ import os
2
+ import json
3
+ import asyncio
4
+ import logging
5
+ import functools
6
+ import threading
7
+ from datetime import datetime, timedelta
8
+ from collections import defaultdict
9
+ from dotenv import load_dotenv
10
+ import openai
11
+ import aiohttp
12
+
13
+ # Load environment variables
14
+ load_dotenv()
15
+
16
+ # Setup logging
17
+ LOG_FILE = "maya_optimize.log"
18
+ logging.basicConfig(
19
+ filename=LOG_FILE,
20
+ level=logging.DEBUG,
21
+ format="%(asctime)s - %(levelname)s - %(message)s"
22
+ )
23
+
24
+ # Cache storage
25
+ CACHE_FILE = "maya_cache.json"
26
+ cache = {}
27
+
28
+ # Batch requests queue
29
+ BATCH_REQUESTS = defaultdict(list)
30
+ BATCH_SIZE = 5
31
+ BATCH_TIME_LIMIT = 10 # seconds
32
+
33
+ # Load API key
34
+ openai.api_key = os.getenv("OPENAI_API_KEY")
35
+
36
+
37
+ # 🔄 **Load Cache from File**
38
+ def load_cache():
39
+ global cache
40
+ if os.path.exists(CACHE_FILE):
41
+ try:
42
+ with open(CACHE_FILE, "r", encoding="utf-8") as f:
43
+ cache = json.load(f)
44
+ logging.info("Cache loaded successfully.")
45
+ except Exception as e:
46
+ logging.error(f"Failed to load cache: {str(e)}")
47
+
48
+
49
+ # 💾 **Save Cache to File**
50
+ def save_cache():
51
+ try:
52
+ with open(CACHE_FILE, "w", encoding="utf-8") as f:
53
+ json.dump(cache, f, indent=4) # Added indentation for readability
54
+ logging.info("Cache saved successfully.")
55
+ except Exception as e:
56
+ logging.error(f"Failed to save cache: {str(e)}")
57
+
58
+
59
+ # 🚀 **Cache Wrapper for API Calls**
60
+ def cache_results(ttl=300):
61
+ def decorator(func):
62
+ @functools.wraps(func)
63
+ def wrapper(*args, **kwargs):
64
+ key = f"{func.__name__}:{args}:{kwargs}"
65
+ now = datetime.utcnow()
66
+
67
+ # Check cache
68
+ if key in cache and now - datetime.fromisoformat(cache[key]["timestamp"]) < timedelta(seconds=ttl):
69
+ logging.info(f"Cache hit for {key}")
70
+ return cache[key]["result"]
71
+
72
+ # Execute function & store result
73
+ result = func(*args, **kwargs)
74
+ cache[key] = {"timestamp": now.isoformat(), "result": result}
75
+ save_cache() # Save cache immediately after update
76
+ return result
77
+
78
+ return wrapper
79
+
80
+ return decorator
81
+
82
+
83
+ # ⚡ **Async API Call Optimization**
84
+ async def async_openai_request(prompt):
85
+ url = "https://api.openai.com/v1/chat/completions"
86
+ headers = {
87
+ "Authorization": f"Bearer {openai.api_key}",
88
+ "Content-Type": "application/json",
89
+ }
90
+ data = {
91
+ "model": "gpt-4",
92
+ "messages": [{"role": "user", "content": prompt}],
93
+ }
94
+
95
+ try:
96
+ start_time = datetime.utcnow()
97
+ async with aiohttp.ClientSession() as session:
98
+ async with session.post(url, headers=headers, json=data, timeout=10) as response:
99
+ response_data = await response.json()
100
+
101
+ end_time = datetime.utcnow()
102
+ logging.info(f"OpenAI request completed in {(end_time - start_time).total_seconds()} seconds.")
103
+ return response_data
104
+
105
+ except asyncio.TimeoutError:
106
+ logging.error("OpenAI request timed out.")
107
+ return {"error": "Request timed out"}
108
+ except Exception as e:
109
+ logging.error(f"OpenAI request failed: {str(e)}")
110
+ return {"error": "Request failed"}
111
+
112
+
113
+ # 🚀 **Batch Processing API Calls**
114
+ async def process_batch_requests():
115
+ while True:
116
+ if BATCH_REQUESTS:
117
+ for key, prompts in list(BATCH_REQUESTS.items()):
118
+ if len(prompts) >= BATCH_SIZE:
119
+ logging.info(f"Processing batch of {len(prompts)} requests.")
120
+ batch_response = await asyncio.gather(
121
+ *[async_openai_request(prompt) for prompt in prompts]
122
+ )
123
+ for i, response in enumerate(batch_response):
124
+ BATCH_REQUESTS[key][i] = response
125
+ del BATCH_REQUESTS[key]
126
+
127
+ await asyncio.sleep(BATCH_TIME_LIMIT)
128
+
129
+
130
+ # 🔍 **Fine-Tuning Models (Placeholder)**
131
+ def fine_tune_model():
132
+ """Future placeholder for fine-tuning AI models based on performance metrics."""
133
+ logging.info("Fine-tuning models is not yet implemented.")
134
+
135
+
136
+ # 🛠 **Optimization Event Listener (Runs in Background)**
137
+ def optimize_event_handler():
138
+ logging.info("Optimization event listener started.")
139
+
140
+ def run_event_loop():
141
+ loop = asyncio.new_event_loop()
142
+ asyncio.set_event_loop(loop)
143
+ loop.run_until_complete(process_batch_requests())
144
+
145
+ # Run the event loop in a background thread
146
+ threading.Thread(target=run_event_loop, daemon=True).start()
147
+
148
+
149
+ # 🔥 **Auto-Run When Imported**
150
+ load_cache()
151
+ optimize_event_handler() # Now runs in the background instead of blocking the main thread
@@ -0,0 +1,157 @@
1
+ Metadata-Version: 2.2
2
+ Name: maya-cli
3
+ Version: 0.1.3
4
+ Summary: Maya CLI - AI Project Generator
5
+ Home-page: https://github.com/anointingmayami/Maya.ai
6
+ Author: King Anointing Joseph Mayami
7
+ Author-email: anointingmayami@gmail.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.7
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: click
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: home-page
20
+ Dynamic: requires-dist
21
+ Dynamic: requires-python
22
+ Dynamic: summary
23
+
24
+ # Maya CLI - Developer Documentation
25
+
26
+ ## Overview
27
+ Maya CLI is a command-line interface (CLI) designed to assist in AI project generation, optimization, security enforcement, and best practices validation. This documentation provides a guide on how to use each CLI command effectively.
28
+
29
+ ## Installation
30
+ Before using Maya CLI, ensure that the required dependencies are installed:
31
+ ```sh
32
+ pip install -r requirements.txt
33
+ ```
34
+
35
+ ## Commands
36
+ ### 1. Create a New AI Project
37
+ #### Command:
38
+ ```sh
39
+ maya create <project_name>
40
+ ```
41
+ #### Description:
42
+ Creates a new AI project structure.
43
+
44
+ #### Example:
45
+ ```sh
46
+ maya create my_ai_project
47
+ ```
48
+
49
+ ### 2. Check Best Practices
50
+ #### Command:
51
+ ```sh
52
+ maya check_best_practices [folder] [filename]
53
+ ```
54
+ #### Description:
55
+ Validates Python code against best practices.
56
+
57
+ #### Example:
58
+ ```sh
59
+ maya check_best_practices api my_script.py
60
+ ```
61
+
62
+ ### 3. Set Environment Variable
63
+ #### Command:
64
+ ```sh
65
+ maya set_env <key> <value>
66
+ ```
67
+ #### Description:
68
+ Sets a key-value pair in the `.env` file.
69
+
70
+ #### Example:
71
+ ```sh
72
+ maya set_env OPENAI_API_KEY my_api_key
73
+ ```
74
+
75
+ ### 4. Optimize AI Scripts
76
+ #### Command:
77
+ ```sh
78
+ maya optimize [target]
79
+ ```
80
+ #### Description:
81
+ Optimizes AI scripts with caching and async processing.
82
+
83
+ #### Example:
84
+ ```sh
85
+ maya optimize my_project
86
+ ```
87
+
88
+ ### 5. Enforce API Security
89
+ #### Command:
90
+ ```sh
91
+ maya isSecured <target> [filename]
92
+ ```
93
+ #### Description:
94
+ Checks and enforces API security measures including authentication, encryption, and rate limiting.
95
+
96
+ #### Example:
97
+ ```sh
98
+ maya isSecured api my_api.py
99
+ ```
100
+
101
+ ### 6. Check Code Ethics
102
+ #### Command:
103
+ ```sh
104
+ maya check_ethics <target> [filename]
105
+ ```
106
+ #### Description:
107
+ Validates code efficiency, accuracy, and best practices.
108
+
109
+ #### Example:
110
+ ```sh
111
+ maya check_ethics my_project
112
+ ```
113
+
114
+ ### 7. Generate Documentation
115
+ #### Command:
116
+ ```sh
117
+ maya doc <target> <filename>
118
+ ```
119
+ #### Description:
120
+ Generates a `README.md` documentation for the given file.
121
+
122
+ #### Example:
123
+ ```sh
124
+ maya doc api my_script.py
125
+ ```
126
+
127
+ ### 8. Generate Codex Report
128
+ #### Command:
129
+ ```sh
130
+ maya codex <target> <filename>
131
+ ```
132
+ #### Description:
133
+ Provides an in-depth analysis and recommendations for the given file.
134
+
135
+ #### Example:
136
+ ```sh
137
+ maya codex ai_model model.py
138
+ ```
139
+
140
+ ### 9. Enforce Compliance & Regulation
141
+ #### Command:
142
+ ```sh
143
+ maya regulate <target> [filename]
144
+ ```
145
+ #### Description:
146
+ Ensures compliance with GDPR, CCPA, AI Act, and ISO 42001 AI governance standards.
147
+
148
+ #### Example:
149
+ ```sh
150
+ maya regulate my_project
151
+ ```
152
+
153
+ ## Logging
154
+ Maya CLI logs all operations in `maya_cli.log`. Check this file for debugging and issue tracking.
155
+
156
+ ## Contact
157
+ For support or feature requests, reach out to the development team via GitHub or email.
@@ -0,0 +1,11 @@
1
+ maya_cli/__init__.py,sha256=d7ktJFCti7GbZZJJHwTLpLy9EyI3lJmkqtL3YnR-cm8,69
2
+ maya_cli/cli.py,sha256=jwOLoXsmz9Af41-tyukTmGMORjBoz8hJ9QikxdgbIFs,21928
3
+ maya_cli/project_generator.py,sha256=AB9uV_lBe-KPywMJ3uDH9YPSTRHXFP7qzqpPdxDB5GY,2967
4
+ maya_cli/refactor.py,sha256=ipi3iabQOcyQyJn20PErpgi-Hb4cb8f8p7zW0HO22_s,3890
5
+ maya_cli/scripts/__init__.py,sha256=yY3Tbs-t4HSl4I0Ev0RcHMnHU7SwljlWRveiRJkeCB8,10
6
+ maya_cli/scripts/optimize.py,sha256=UqDIHyyYPXZkhAb4GSvjbN0IvwXM2aFnpSh4k0Jzobo,4820
7
+ maya_cli-0.1.3.dist-info/METADATA,sha256=mPsFwPZ9C399qTlHxcHC7TpSoHNn6hr-_46XlAjBaes,3469
8
+ maya_cli-0.1.3.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
9
+ maya_cli-0.1.3.dist-info/entry_points.txt,sha256=K4mI6r7-idKvOmz7zpMpK6HaEnraRoRt4nSW1jTfCgE,43
10
+ maya_cli-0.1.3.dist-info/top_level.txt,sha256=nZzw8c5hxqres4pU9UUFCTjwBSHUDNjqCTM7yOFnnrE,9
11
+ maya_cli-0.1.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,116 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: maya-cli
3
- Version: 0.1.1
4
- Summary: Maya CLI - AI Project Generator
5
- Home-page: https://github.com/anointingmayami/Maya.ai
6
- Author: King Anointing Joseph Mayami
7
- Author-email: anointingmayami@gmail.com
8
- Classifier: Programming Language :: Python :: 3
9
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
10
- Classifier: Operating System :: OS Independent
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- Requires-Dist: click
14
- Dynamic: author
15
- Dynamic: author-email
16
- Dynamic: classifier
17
- Dynamic: description
18
- Dynamic: description-content-type
19
- Dynamic: home-page
20
- Dynamic: requires-dist
21
- Dynamic: requires-python
22
- Dynamic: summary
23
-
24
- # Maya.ai - AI Architectural Framework
25
-
26
- Maya.ai is an AI architectural framework designed to ensure ethical, optimized, and compliant AI integration in business and research applications. The framework provides guidance on AI ethics, compliance, business strategy, and AI-driven education while fostering innovation.
27
-
28
- ## 🌟 Features
29
- - Ensures structured AI project development
30
- - Promotes ethical and compliant AI integration
31
- - Provides a scalable framework for AI research and business applications
32
- - Includes Maya CLI for quick AI project setup
33
-
34
- ## 🛠 Maya CLI - AI Project Generator
35
- Maya CLI is one of the core features of Maya.ai, designed to generate structured AI project templates. It helps AI developers quickly set up their projects with predefined folders and files, ensuring organization and scalability.
36
-
37
- ### 📦 Installation Guide (For Dummies)
38
-
39
- #### Step 1: Install Python
40
- Maya CLI requires Python. To install Python:
41
- - Download the latest version of Python from [python.org](https://www.python.org/downloads/)
42
- - Run the installer and ensure "Add Python to PATH" is checked
43
- - Verify installation by running:
44
- ```sh
45
- python --version
46
- ```
47
-
48
- #### Step 2: Install Virtual Environment (Optional but Recommended)
49
- Using a virtual environment helps manage dependencies. Install it using:
50
- ```sh
51
- pip install virtualenv
52
- ```
53
- To create and activate a virtual environment:
54
- ```sh
55
- virtualenv venv
56
- source venv/bin/activate # On macOS/Linux
57
- venv\Scripts\activate # On Windows
58
- ```
59
-
60
- #### Step 3: Install Maya CLI
61
- Maya CLI is available on PyPI. Install it using pip:
62
- ```sh
63
- pip install maya-cli
64
- ```
65
-
66
- ### 🚀 Usage
67
- Once installed, use the following command to create a new AI project:
68
- ```sh
69
- maya create <project_name>
70
- ```
71
- Example:
72
- ```sh
73
- maya create my_ai_project
74
- ```
75
- This will generate the following structure:
76
- ```
77
- my_ai_project/
78
- │── data_source/
79
- │ ├── ingestion/
80
- │ ├── processing/
81
- │ ├── storage/
82
- │── knowledge_base/
83
- │ ├── models/
84
- │ ├── training/
85
- │ ├── evaluation/
86
- │── ai_governance/
87
- │ ├── compliance/
88
- │ ├── fairness/
89
- │ ├── monitoring/
90
- │── api/
91
- │ ├── endpoints/
92
- │ ├── authentication/
93
- │── tests/
94
- │── docs/
95
- │── scripts/
96
- │── configs/
97
- ```
98
-
99
- ### 🛠 API Documentation
100
- #### CLI Commands
101
- ##### `maya create <project_name>`
102
- Creates a new AI project structure with organized folders.
103
-
104
- #### `project_generator.py`
105
- ##### `create_project_structure(base_path, structure)`
106
- Recursively creates folders based on the defined project structure.
107
-
108
- ## 📜 License
109
- This project is licensed under the MIT License.
110
-
111
- ## 🤝 Contributing
112
- Contributions are welcome! Feel free to open an issue or submit a pull request.
113
-
114
- ## 📞 Support
115
- For any issues, contact the developers via GitHub or raise an issue in the repository.
116
-
@@ -1,8 +0,0 @@
1
- maya_cli/__init__.py,sha256=d7ktJFCti7GbZZJJHwTLpLy9EyI3lJmkqtL3YnR-cm8,69
2
- maya_cli/cli.py,sha256=EiIL10GcFQCdyiwyJZjOXrJ6klVQLzKYpLiG10Ph7xE,1253
3
- maya_cli/project_generator.py,sha256=-p7MAqnfzZthO6vKLtesRoTmUn-ZyvOBY1tcmayuPPo,1036
4
- maya_cli-0.1.1.dist-info/METADATA,sha256=faJGMaXqOJy65km7IMIq3AErtZn4znJdbO5iGYEq0C4,4025
5
- maya_cli-0.1.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
6
- maya_cli-0.1.1.dist-info/entry_points.txt,sha256=K4mI6r7-idKvOmz7zpMpK6HaEnraRoRt4nSW1jTfCgE,43
7
- maya_cli-0.1.1.dist-info/top_level.txt,sha256=nZzw8c5hxqres4pU9UUFCTjwBSHUDNjqCTM7yOFnnrE,9
8
- maya_cli-0.1.1.dist-info/RECORD,,