@voodocs/cli 2.2.0 → 2.2.1

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 (51) hide show
  1. package/CHANGELOG.md +215 -38
  2. package/LICENSE +1 -1
  3. package/PRIVACY.md +10 -10
  4. package/README.md +39 -35
  5. package/USAGE.md +50 -27
  6. package/examples/.cursorrules +9 -9
  7. package/examples/instructions/.claude/instructions.md +77 -65
  8. package/examples/instructions/.cursorrules +9 -9
  9. package/examples/instructions/.windsurfrules +9 -9
  10. package/examples/instructions/VOODOCS_INSTRUCTIONS.md +74 -62
  11. package/examples/math_example.py +1 -1
  12. package/examples/phase2_test.py +1 -1
  13. package/examples/test_function_invariants.py +1 -1
  14. package/lib/cli/__init__.py +3 -3
  15. package/lib/cli/benchmark.py +3 -3
  16. package/lib/cli/context.py +1 -1
  17. package/lib/cli/fix.py +1 -1
  18. package/lib/cli/generate.py +1 -1
  19. package/lib/cli/init.py +10 -10
  20. package/lib/cli/instruct.py +1 -1
  21. package/lib/cli/validate.py +3 -3
  22. package/lib/darkarts/annotations/DARKARTS_SYMBOLS.md +110 -95
  23. package/lib/darkarts/annotations/TRANSFORMATION_EXAMPLES.md +29 -27
  24. package/lib/darkarts/annotations/parser.py +1 -1
  25. package/lib/darkarts/cli_darkarts.py +5 -5
  26. package/lib/darkarts/context/ai_instructions.py +12 -12
  27. package/lib/darkarts/context/ai_integrations.py +16 -16
  28. package/lib/darkarts/context/commands.py +4 -4
  29. package/lib/darkarts/context/errors.py +1 -1
  30. package/lib/darkarts/context/models.py +1 -1
  31. package/lib/darkarts/context/ui.py +4 -4
  32. package/lib/darkarts/context/yaml_utils.py +3 -3
  33. package/lib/darkarts/core/loader.py +1 -1
  34. package/lib/darkarts/documentation/__init__.py +10 -0
  35. package/lib/darkarts/documentation/categorizer.py +137 -0
  36. package/lib/darkarts/documentation/consolidator.py +303 -0
  37. package/lib/darkarts/exceptions.py +3 -3
  38. package/lib/darkarts/plugins/voodocs/ai_native_plugin.py +1 -1
  39. package/lib/darkarts/plugins/voodocs/annotation_validator.py +2 -2
  40. package/lib/darkarts/plugins/voodocs/documentation_generator.py +3 -3
  41. package/lib/darkarts/plugins/voodocs/html_exporter.py +4 -4
  42. package/lib/darkarts/plugins/voodocs/instruction_generator.py +10 -10
  43. package/lib/darkarts/plugins/voodocs/pdf_exporter.py +1 -1
  44. package/lib/darkarts/plugins/voodocs/test_generator.py +1 -1
  45. package/lib/darkarts/telemetry.py +5 -5
  46. package/lib/darkarts/validation/README.md +6 -3
  47. package/package.json +2 -1
  48. package/requirements.txt +2 -2
  49. package/templates/ci/github-actions.yml +64 -64
  50. package/templates/ci/pre-commit-hook.sh +4 -4
  51. package/voodocs_cli.py +1 -1
@@ -6,7 +6,7 @@
6
6
  šŸ”’{read-only:detect,write:explicit-user-command}
7
7
  ⚔{O(n²):detect-with-analysis,O(k):generate|k=ai-count}
8
8
 
9
- AI-specific integration templates for VooDocs Context System.
9
+ AI-specific integration templates for Voodocs Context System.
10
10
 
11
11
  This module provides native integration with different AI assistants:
12
12
  - Claude Code (skills)
@@ -23,7 +23,7 @@ from pathlib import Path
23
23
 
24
24
  def generate_claude_skill(project_name: str, project_purpose: str) -> Dict[str, str]:
25
25
  """
26
- Generate Claude Code skill for VooDocs context system.
26
+ Generate Claude Code skill for Voodocs context system.
27
27
 
28
28
  Args:
29
29
  project_name: Name of the project
@@ -34,15 +34,15 @@ def generate_claude_skill(project_name: str, project_purpose: str) -> Dict[str,
34
34
  """
35
35
  skill_md = f"""---
36
36
  name: voodocs-context
37
- description: Access and query the VooDocs context system for project understanding, invariants, and architecture
37
+ description: Access and query the Voodocs context system for project understanding, invariants, and architecture
38
38
  ---
39
39
 
40
- # VooDocs Context System Skill
40
+ # Voodocs Context System Skill
41
41
 
42
42
  ## Project: {project_name}
43
43
  {project_purpose}
44
44
 
45
- This skill provides access to the VooDocs context system for understanding project architecture, invariants, and assumptions.
45
+ This skill provides access to the Voodocs context system for understanding project architecture, invariants, and assumptions.
46
46
 
47
47
  ## Available Commands
48
48
 
@@ -152,7 +152,7 @@ voodocs context check
152
152
 
153
153
  def generate_cursor_rules(project_name: str, project_purpose: str) -> Dict[str, str]:
154
154
  """
155
- Generate Cursor rules for VooDocs context system.
155
+ Generate Cursor rules for Voodocs context system.
156
156
 
157
157
  Args:
158
158
  project_name: Name of the project
@@ -162,12 +162,12 @@ def generate_cursor_rules(project_name: str, project_purpose: str) -> Dict[str,
162
162
  Dictionary mapping file paths to content
163
163
  """
164
164
 
165
- main_rule = f"""# VooDocs Context System
165
+ main_rule = f"""# Voodocs Context System
166
166
 
167
167
  ## Project: {project_name}
168
168
  {project_purpose}
169
169
 
170
- This project uses the VooDocs Context System (v0.2.0+) for documentation and validation.
170
+ This project uses the Voodocs Context System (v0.2.0+) for documentation and validation.
171
171
 
172
172
  ## Context File
173
173
  - **Location**: `.voodocs.context`
@@ -283,7 +283,7 @@ voodocs context query "module-name" --section architecture
283
283
 
284
284
  def generate_copilot_instructions(project_name: str, project_purpose: str) -> Dict[str, str]:
285
285
  """
286
- Generate GitHub Copilot instructions for VooDocs context system.
286
+ Generate GitHub Copilot instructions for Voodocs context system.
287
287
 
288
288
  Args:
289
289
  project_name: Name of the project
@@ -298,9 +298,9 @@ def generate_copilot_instructions(project_name: str, project_purpose: str) -> Di
298
298
  ## Project Overview
299
299
  {project_purpose}
300
300
 
301
- ## VooDocs Context System
301
+ ## Voodocs Context System
302
302
 
303
- This project uses VooDocs Context System (v0.2.0+) for documentation and validation.
303
+ This project uses Voodocs Context System (v0.2.0+) for documentation and validation.
304
304
 
305
305
  ### Context File
306
306
  - **Location**: `.voodocs.context` (YAML format)
@@ -400,7 +400,7 @@ voodocs context diagram --type modules
400
400
 
401
401
  def generate_windsurf_rules(project_name: str, project_purpose: str) -> Dict[str, str]:
402
402
  """
403
- Generate Windsurf rules for VooDocs context system.
403
+ Generate Windsurf rules for Voodocs context system.
404
404
 
405
405
  Args:
406
406
  project_name: Name of the project
@@ -415,9 +415,9 @@ def generate_windsurf_rules(project_name: str, project_purpose: str) -> Dict[str
415
415
  ## Project
416
416
  {project_purpose}
417
417
 
418
- ## VooDocs Context System
418
+ ## Voodocs Context System
419
419
 
420
- This project uses VooDocs (v0.2.0+) for context management.
420
+ This project uses Voodocs (v0.2.0+) for context management.
421
421
 
422
422
  ### Context Commands
423
423
 
@@ -478,7 +478,7 @@ invariants: ["rules"]
478
478
 
479
479
  def generate_cline_rules(project_name: str, project_purpose: str) -> Dict[str, str]:
480
480
  """
481
- Generate Cline rules for VooDocs context system.
481
+ Generate Cline rules for Voodocs context system.
482
482
 
483
483
  Args:
484
484
  project_name: Name of the project
@@ -493,7 +493,7 @@ def generate_cline_rules(project_name: str, project_purpose: str) -> Dict[str, s
493
493
  ## Project
494
494
  {project_purpose}
495
495
 
496
- ## VooDocs Context System
496
+ ## Voodocs Context System
497
497
 
498
498
  Context file: `.voodocs.context` (YAML)
499
499
 
@@ -210,7 +210,7 @@ def cmd_context_init(force: bool = False) -> int:
210
210
  Exit code (0 for success, 1 for error)
211
211
  """
212
212
  try:
213
- print_header("VooDocs Context Initialization")
213
+ print_header("Voodocs Context Initialization")
214
214
 
215
215
  # Check if context file already exists
216
216
  context_path = get_context_file_path()
@@ -224,7 +224,7 @@ def cmd_context_init(force: bool = False) -> int:
224
224
  if not confirm(f"Overwrite existing context file at {context_path}?", default=False):
225
225
  raise UserInterruptError("Initialization")
226
226
 
227
- step("Initializing VooDocs context...")
227
+ step("Initializing Voodocs context...")
228
228
  print()
229
229
 
230
230
  # Detect project information
@@ -375,7 +375,7 @@ def cmd_context_init(force: bool = False) -> int:
375
375
 
376
376
  print()
377
377
  print("šŸ¤– AI integration complete!")
378
- print(f" Your {ai_type} assistant will now understand the VooDocs context system.")
378
+ print(f" Your {ai_type} assistant will now understand the Voodocs context system.")
379
379
 
380
380
  except Exception as e:
381
381
  print(f"āš ļø Warning: Failed to generate AI integration: {e}")
@@ -1368,7 +1368,7 @@ def cmd_context_generate(source_dir: Optional[str] = None, update_existing: bool
1368
1368
  return 1
1369
1369
  except ImportError as e:
1370
1370
  error(f"Failed to import annotation parser: {e}")
1371
- warning("Make sure VooDocs is properly installed")
1371
+ warning("Make sure Voodocs is properly installed")
1372
1372
  return 1
1373
1373
  except Exception as e:
1374
1374
  error(f"Failed to generate context: {e}")
@@ -52,7 +52,7 @@ class GitNotAvailableError(ConfigurationError):
52
52
  def __init__(self):
53
53
  super().__init__(
54
54
  f"Git is not available\n\n"
55
- f"šŸ’” Some VooDocs features require Git. Please install Git:\n"
55
+ f"šŸ’” Some Voodocs features require Git. Please install Git:\n"
56
56
  f" https://git-scm.com/downloads"
57
57
  )
58
58
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  Context System Data Models
10
10
 
11
- This module defines the data structures for the VooDocs context system.
11
+ This module defines the data structures for the Voodocs context system.
12
12
  """
13
13
 
14
14
  from dataclasses import dataclass, field, asdict
@@ -119,8 +119,8 @@ def step(message: str) -> None:
119
119
  message: Step message to display
120
120
 
121
121
  Example:
122
- >>> step("Initializing VooDocs context...")
123
- ā–¶ļø Initializing VooDocs context...
122
+ >>> step("Initializing Voodocs context...")
123
+ ā–¶ļø Initializing Voodocs context...
124
124
  """
125
125
  print(f"{Colors.CYAN}ā–¶ļø {message}{Colors.RESET}")
126
126
 
@@ -243,10 +243,10 @@ def print_header(title: str) -> None:
243
243
  title: Header title
244
244
 
245
245
  Example:
246
- >>> print_header("VooDocs Context System")
246
+ >>> print_header("Voodocs Context System")
247
247
 
248
248
  ═══════════════════════════════════════════════════════════════
249
- VooDocs Context System
249
+ Voodocs Context System
250
250
  ═══════════════════════════════════════════════════════════════
251
251
  """
252
252
  width = 80
@@ -56,7 +56,7 @@ def write_context_yaml(context: ContextFile, file_path: Path) -> None:
56
56
  # Create file with header comment
57
57
  with open(file_path, 'w', encoding='utf-8') as f:
58
58
  # Write header
59
- f.write("# VooDocs Context File\n")
59
+ f.write("# Voodocs Context File\n")
60
60
  f.write("# This file contains structured project context for AI assistants and developers.\n")
61
61
  f.write("# Format: YAML (DSL for machines, use 'voodocs context view' for human-readable Markdown)\n")
62
62
  f.write("# Version: {}\n".format(context.versioning.context_version))
@@ -333,14 +333,14 @@ def add_to_gitignore(project_root: Path) -> bool:
333
333
  # Ensure there's a newline before our section
334
334
  if not content.endswith('\n'):
335
335
  f.write('\n')
336
- f.write('\n# VooDocs Context File (contains internal project details)\n')
336
+ f.write('\n# Voodocs Context File (contains internal project details)\n')
337
337
  f.write(f'{context_entry}\n')
338
338
 
339
339
  return True
340
340
  else:
341
341
  # Create .gitignore with entry
342
342
  with open(gitignore_path, 'w', encoding='utf-8') as f:
343
- f.write('# VooDocs Context File (contains internal project details)\n')
343
+ f.write('# Voodocs Context File (contains internal project details)\n')
344
344
  f.write(f'{context_entry}\n')
345
345
 
346
346
  return True
@@ -199,7 +199,7 @@ class PluginLoader:
199
199
  plugin = self.load_from_module("darkarts.plugins.voodocs", "VooDocsPlugin")
200
200
  plugins.append(plugin)
201
201
  except PluginError:
202
- pass # VooDocs plugin not yet implemented
202
+ pass # Voodocs plugin not yet implemented
203
203
 
204
204
  return plugins
205
205
 
@@ -0,0 +1,10 @@
1
+ """
2
+ Documentation Generation Module
3
+
4
+ Provides consolidated, human-readable documentation generation.
5
+ """
6
+
7
+ from .consolidator import DocumentationConsolidator, DocumentedItem
8
+ from .categorizer import AnnotationCategorizer
9
+
10
+ __all__ = ['DocumentationConsolidator', 'DocumentedItem', 'AnnotationCategorizer']
@@ -0,0 +1,137 @@
1
+ """
2
+ Annotation Categorizer
3
+
4
+ Extracts categorization metadata from @darkarts annotations.
5
+ """
6
+
7
+ from typing import Dict, Set, Any, List
8
+ from pathlib import Path
9
+
10
+
11
+ class AnnotationCategorizer:
12
+ """Categorizes code based on @darkarts annotations and file paths."""
13
+
14
+ # Type detection patterns
15
+ TYPE_PATTERNS = {
16
+ 'component': ['component', 'tsx', 'jsx', 'ui', 'view'],
17
+ 'function': ['function', 'util', 'helper'],
18
+ 'module': ['module', 'service', 'manager'],
19
+ 'api': ['api', 'route', 'endpoint', 'handler'],
20
+ 'data': ['schema', 'model', 'type', 'interface'],
21
+ }
22
+
23
+ # Domain keywords
24
+ DOMAIN_KEYWORDS = {
25
+ 'authentication': ['auth', 'login', 'signup', 'session', 'token'],
26
+ 'billing': ['billing', 'subscription', 'payment', 'invoice', 'stripe'],
27
+ 'admin': ['admin', 'dashboard', 'management'],
28
+ 'user_management': ['user', 'account', 'profile'],
29
+ 'analytics': ['analytics', 'tracking', 'metrics', 'stats'],
30
+ 'marketplace': ['marketplace', 'listing', 'product'],
31
+ 'api': ['api', 'endpoint', 'route'],
32
+ }
33
+
34
+ # Layer detection
35
+ LAYER_PATTERNS = {
36
+ 'frontend': ['component', 'ui', 'view', 'page', 'tsx', 'jsx', 'client'],
37
+ 'backend': ['api', 'server', 'route', 'handler', 'controller'],
38
+ 'database': ['schema', 'model', 'db', 'database', 'query'],
39
+ }
40
+
41
+ @staticmethod
42
+ def detect_type(file_path: str, annotations: Dict[str, Any]) -> str:
43
+ """Detect the type of code item."""
44
+ path_lower = file_path.lower()
45
+
46
+ # Check file path for type hints
47
+ for item_type, patterns in AnnotationCategorizer.TYPE_PATTERNS.items():
48
+ if any(pattern in path_lower for pattern in patterns):
49
+ return item_type
50
+
51
+ # Check annotations
52
+ if 'module_purpose' in annotations or '⊢' in str(annotations):
53
+ return 'module'
54
+
55
+ return 'other'
56
+
57
+ @staticmethod
58
+ def detect_domains(file_path: str, annotations: Dict[str, Any]) -> Set[str]:
59
+ """Detect which domains this code belongs to."""
60
+ domains = set()
61
+ path_lower = file_path.lower()
62
+
63
+ # Check file path
64
+ for domain, keywords in AnnotationCategorizer.DOMAIN_KEYWORDS.items():
65
+ if any(keyword in path_lower for keyword in keywords):
66
+ domains.add(domain)
67
+
68
+ # Check annotation content
69
+ annotation_text = str(annotations).lower()
70
+ for domain, keywords in AnnotationCategorizer.DOMAIN_KEYWORDS.items():
71
+ if any(keyword in annotation_text for keyword in keywords):
72
+ domains.add(domain)
73
+
74
+ return domains
75
+
76
+ @staticmethod
77
+ def detect_concerns(annotations: Dict[str, Any]) -> Set[str]:
78
+ """Detect cross-cutting concerns."""
79
+ concerns = set()
80
+
81
+ # Check for security
82
+ if 'security' in annotations or 'šŸ”’' in str(annotations):
83
+ concerns.add('security')
84
+
85
+ # Check for business logic
86
+ if 'business_logic' in annotations:
87
+ concerns.add('business_logic')
88
+
89
+ # Check for performance
90
+ if 'complexity' in annotations or '⚔' in str(annotations):
91
+ concerns.add('performance')
92
+
93
+ # Check for integrations (external dependencies)
94
+ dependencies = annotations.get('dependencies', [])
95
+ if isinstance(dependencies, list):
96
+ external_deps = [d for d in dependencies if not str(d).startswith('.')]
97
+ if external_deps:
98
+ concerns.add('integrations')
99
+
100
+ # Check for error handling
101
+ if 'error_handling' in annotations or 'exceptions' in str(annotations).lower():
102
+ concerns.add('error_handling')
103
+
104
+ return concerns
105
+
106
+ @staticmethod
107
+ def detect_layers(file_path: str, annotations: Dict[str, Any]) -> Set[str]:
108
+ """Detect which architectural layers this code belongs to."""
109
+ layers = set()
110
+ path_lower = file_path.lower()
111
+
112
+ for layer, patterns in AnnotationCategorizer.LAYER_PATTERNS.items():
113
+ if any(pattern in path_lower for pattern in patterns):
114
+ layers.add(layer)
115
+
116
+ return layers
117
+
118
+ @staticmethod
119
+ def extract_name(file_path: str) -> str:
120
+ """Extract a human-readable name from file path."""
121
+ path = Path(file_path)
122
+ name = path.stem
123
+
124
+ # Remove common suffixes
125
+ suffixes_to_remove = [
126
+ '.test', '.spec', '.component', '.service',
127
+ '.controller', '.model', '.schema'
128
+ ]
129
+ for suffix in suffixes_to_remove:
130
+ if name.endswith(suffix):
131
+ name = name[:-len(suffix)]
132
+
133
+ # Convert kebab-case and snake_case to Title Case
134
+ name = name.replace('-', ' ').replace('_', ' ')
135
+ name = ' '.join(word.capitalize() for word in name.split())
136
+
137
+ return name