@voodocs/cli 2.1.3 → 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.
- package/CHANGELOG.md +215 -38
- package/LICENSE +1 -1
- package/PRIVACY.md +10 -10
- package/README.md +39 -35
- package/USAGE.md +50 -27
- package/examples/.cursorrules +9 -9
- package/examples/instructions/.claude/instructions.md +77 -65
- package/examples/instructions/.cursorrules +9 -9
- package/examples/instructions/.windsurfrules +9 -9
- package/examples/instructions/VOODOCS_INSTRUCTIONS.md +74 -62
- package/examples/math_example.py +1 -1
- package/examples/phase2_test.py +1 -1
- package/examples/test_function_invariants.py +1 -1
- package/lib/cli/__init__.py +3 -3
- package/lib/cli/benchmark.py +3 -3
- package/lib/cli/context.py +1 -1
- package/lib/cli/fix.py +1 -1
- package/lib/cli/generate.py +60 -1
- package/lib/cli/init.py +10 -10
- package/lib/cli/instruct.py +1 -1
- package/lib/cli/validate.py +3 -3
- package/lib/darkarts/annotations/DARKARTS_SYMBOLS.md +110 -95
- package/lib/darkarts/annotations/TRANSFORMATION_EXAMPLES.md +29 -27
- package/lib/darkarts/annotations/parser.py +1 -1
- package/lib/darkarts/cli_darkarts.py +5 -5
- package/lib/darkarts/context/ai_instructions.py +12 -12
- package/lib/darkarts/context/ai_integrations.py +16 -16
- package/lib/darkarts/context/commands.py +4 -4
- package/lib/darkarts/context/errors.py +1 -1
- package/lib/darkarts/context/models.py +1 -1
- package/lib/darkarts/context/ui.py +4 -4
- package/lib/darkarts/context/yaml_utils.py +3 -3
- package/lib/darkarts/core/loader.py +1 -1
- package/lib/darkarts/documentation/__init__.py +10 -0
- package/lib/darkarts/documentation/categorizer.py +137 -0
- package/lib/darkarts/documentation/consolidator.py +303 -0
- package/lib/darkarts/exceptions.py +3 -3
- package/lib/darkarts/plugins/voodocs/ai_native_plugin.py +1 -1
- package/lib/darkarts/plugins/voodocs/annotation_validator.py +2 -2
- package/lib/darkarts/plugins/voodocs/documentation_generator.py +3 -3
- package/lib/darkarts/plugins/voodocs/html_exporter.py +4 -4
- package/lib/darkarts/plugins/voodocs/instruction_generator.py +10 -10
- package/lib/darkarts/plugins/voodocs/pdf_exporter.py +1 -1
- package/lib/darkarts/plugins/voodocs/test_generator.py +1 -1
- package/lib/darkarts/telemetry.py +5 -5
- package/lib/darkarts/validation/README.md +6 -3
- package/package.json +2 -1
- package/requirements.txt +2 -2
- package/templates/ci/github-actions.yml +64 -64
- package/templates/ci/pre-commit-hook.sh +4 -4
- package/voodocs_cli.py +1 -1
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Documentation Consolidator
|
|
3
|
+
|
|
4
|
+
Generates human-readable consolidated documentation from @darkarts annotations.
|
|
5
|
+
Organizes content by multiple categorization schemes for better readability.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, List, Set, Any
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class DocumentedItem:
|
|
15
|
+
"""Represents a single documented code item."""
|
|
16
|
+
name: str
|
|
17
|
+
file_path: str
|
|
18
|
+
item_type: str # component, function, module, api, etc.
|
|
19
|
+
content: str
|
|
20
|
+
annotations: Dict[str, Any] = field(default_factory=dict)
|
|
21
|
+
|
|
22
|
+
# Categorization metadata
|
|
23
|
+
domains: Set[str] = field(default_factory=set) # auth, billing, admin, etc.
|
|
24
|
+
concerns: Set[str] = field(default_factory=set) # business_logic, security, etc.
|
|
25
|
+
layers: Set[str] = field(default_factory=set) # frontend, backend, database
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class DocumentationConsolidator:
|
|
29
|
+
"""Consolidates scattered documentation into organized, readable documents."""
|
|
30
|
+
|
|
31
|
+
def __init__(self, project_name: str = "Project"):
|
|
32
|
+
self.project_name = project_name
|
|
33
|
+
self.items: List[DocumentedItem] = []
|
|
34
|
+
|
|
35
|
+
def add_item(self, item: DocumentedItem):
|
|
36
|
+
"""Add a documented item to the consolidator."""
|
|
37
|
+
self.items.append(item)
|
|
38
|
+
|
|
39
|
+
def categorize_items(self):
|
|
40
|
+
"""Automatically categorize all items."""
|
|
41
|
+
for item in self.items:
|
|
42
|
+
self._categorize_by_type(item)
|
|
43
|
+
self._categorize_by_path(item)
|
|
44
|
+
self._categorize_by_annotations(item)
|
|
45
|
+
|
|
46
|
+
def _categorize_by_type(self, item: DocumentedItem):
|
|
47
|
+
"""Categorize by code type."""
|
|
48
|
+
# Determine layer from file extension and path
|
|
49
|
+
path_lower = item.file_path.lower()
|
|
50
|
+
|
|
51
|
+
if any(x in path_lower for x in ['component', 'ui', 'view', '.tsx', '.jsx']):
|
|
52
|
+
item.layers.add('frontend')
|
|
53
|
+
if any(x in path_lower for x in ['api', 'server', 'backend', 'route']):
|
|
54
|
+
item.layers.add('backend')
|
|
55
|
+
if any(x in path_lower for x in ['schema', 'model', 'database', 'db']):
|
|
56
|
+
item.layers.add('database')
|
|
57
|
+
|
|
58
|
+
def _categorize_by_path(self, item: DocumentedItem):
|
|
59
|
+
"""Categorize by file path patterns."""
|
|
60
|
+
path_parts = Path(item.file_path).parts
|
|
61
|
+
|
|
62
|
+
# Extract domain from path
|
|
63
|
+
domain_keywords = {
|
|
64
|
+
'auth': 'authentication',
|
|
65
|
+
'billing': 'billing',
|
|
66
|
+
'subscription': 'billing',
|
|
67
|
+
'admin': 'admin',
|
|
68
|
+
'user': 'user_management',
|
|
69
|
+
'account': 'user_management',
|
|
70
|
+
'api': 'api',
|
|
71
|
+
'payment': 'billing',
|
|
72
|
+
'analytics': 'analytics',
|
|
73
|
+
'marketplace': 'marketplace',
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for part in path_parts:
|
|
77
|
+
part_lower = part.lower()
|
|
78
|
+
for keyword, domain in domain_keywords.items():
|
|
79
|
+
if keyword in part_lower:
|
|
80
|
+
item.domains.add(domain)
|
|
81
|
+
|
|
82
|
+
def _categorize_by_annotations(self, item: DocumentedItem):
|
|
83
|
+
"""Categorize by @darkarts annotation content."""
|
|
84
|
+
annotations = item.annotations
|
|
85
|
+
|
|
86
|
+
# Check for security concerns
|
|
87
|
+
if 'security' in annotations or '🔒' in str(annotations):
|
|
88
|
+
item.concerns.add('security')
|
|
89
|
+
|
|
90
|
+
# Check for business logic
|
|
91
|
+
if 'business_logic' in annotations:
|
|
92
|
+
item.concerns.add('business_logic')
|
|
93
|
+
|
|
94
|
+
# Check for performance
|
|
95
|
+
if 'complexity' in annotations or '⚡' in str(annotations):
|
|
96
|
+
item.concerns.add('performance')
|
|
97
|
+
|
|
98
|
+
# Check for integrations
|
|
99
|
+
dependencies = annotations.get('dependencies', [])
|
|
100
|
+
if any(dep for dep in dependencies if not dep.startswith('.')):
|
|
101
|
+
item.concerns.add('integrations')
|
|
102
|
+
|
|
103
|
+
def generate_by_type(self) -> Dict[str, str]:
|
|
104
|
+
"""Generate documentation organized by type."""
|
|
105
|
+
categories = {
|
|
106
|
+
'component': [],
|
|
107
|
+
'function': [],
|
|
108
|
+
'module': [],
|
|
109
|
+
'api': [],
|
|
110
|
+
'data': [],
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for item in self.items:
|
|
114
|
+
item_type = item.item_type.lower()
|
|
115
|
+
if item_type in categories:
|
|
116
|
+
categories[item_type].append(item)
|
|
117
|
+
else:
|
|
118
|
+
categories.setdefault('other', []).append(item)
|
|
119
|
+
|
|
120
|
+
docs = {}
|
|
121
|
+
for category, items in categories.items():
|
|
122
|
+
if items:
|
|
123
|
+
docs[f'by-type/{category.upper()}.md'] = self._generate_category_doc(
|
|
124
|
+
f"{category.title()}s",
|
|
125
|
+
items,
|
|
126
|
+
f"All {category}s in the project"
|
|
127
|
+
)
|
|
128
|
+
return docs
|
|
129
|
+
|
|
130
|
+
def generate_by_domain(self) -> Dict[str, str]:
|
|
131
|
+
"""Generate documentation organized by domain."""
|
|
132
|
+
domain_items = {}
|
|
133
|
+
|
|
134
|
+
for item in self.items:
|
|
135
|
+
for domain in item.domains:
|
|
136
|
+
domain_items.setdefault(domain, []).append(item)
|
|
137
|
+
|
|
138
|
+
docs = {}
|
|
139
|
+
for domain, items in domain_items.items():
|
|
140
|
+
docs[f'by-domain/{domain.upper()}.md'] = self._generate_category_doc(
|
|
141
|
+
domain.replace('_', ' ').title(),
|
|
142
|
+
items,
|
|
143
|
+
f"All code related to {domain.replace('_', ' ')}"
|
|
144
|
+
)
|
|
145
|
+
return docs
|
|
146
|
+
|
|
147
|
+
def generate_by_concern(self) -> Dict[str, str]:
|
|
148
|
+
"""Generate documentation organized by concern."""
|
|
149
|
+
concern_items = {}
|
|
150
|
+
|
|
151
|
+
for item in self.items:
|
|
152
|
+
for concern in item.concerns:
|
|
153
|
+
concern_items.setdefault(concern, []).append(item)
|
|
154
|
+
|
|
155
|
+
docs = {}
|
|
156
|
+
for concern, items in concern_items.items():
|
|
157
|
+
docs[f'by-concern/{concern.upper()}.md'] = self._generate_category_doc(
|
|
158
|
+
concern.replace('_', ' ').title(),
|
|
159
|
+
items,
|
|
160
|
+
f"Code with {concern.replace('_', ' ')} considerations"
|
|
161
|
+
)
|
|
162
|
+
return docs
|
|
163
|
+
|
|
164
|
+
def generate_by_layer(self) -> Dict[str, str]:
|
|
165
|
+
"""Generate documentation organized by layer."""
|
|
166
|
+
layer_items = {}
|
|
167
|
+
|
|
168
|
+
for item in self.items:
|
|
169
|
+
for layer in item.layers:
|
|
170
|
+
layer_items.setdefault(layer, []).append(item)
|
|
171
|
+
|
|
172
|
+
docs = {}
|
|
173
|
+
for layer, items in layer_items.items():
|
|
174
|
+
docs[f'by-layer/{layer.upper()}.md'] = self._generate_category_doc(
|
|
175
|
+
f"{layer.title()} Layer",
|
|
176
|
+
items,
|
|
177
|
+
f"All {layer} code"
|
|
178
|
+
)
|
|
179
|
+
return docs
|
|
180
|
+
|
|
181
|
+
def generate_master_readme(self, all_docs: Dict[str, str]) -> str:
|
|
182
|
+
"""Generate master README with overview and navigation."""
|
|
183
|
+
sections = []
|
|
184
|
+
|
|
185
|
+
# Header
|
|
186
|
+
sections.append(f"# {self.project_name} Documentation\n")
|
|
187
|
+
sections.append(f"*Generated by Voodocs from @darkarts annotations*\n")
|
|
188
|
+
sections.append(f"**Total Items Documented:** {len(self.items)}\n")
|
|
189
|
+
sections.append("---\n")
|
|
190
|
+
|
|
191
|
+
# Quick Navigation
|
|
192
|
+
sections.append("## 📚 Documentation Categories\n")
|
|
193
|
+
sections.append("### By Type")
|
|
194
|
+
for doc_path in sorted(all_docs.keys()):
|
|
195
|
+
if doc_path.startswith('by-type/'):
|
|
196
|
+
name = doc_path.replace('by-type/', '').replace('.md', '')
|
|
197
|
+
sections.append(f"- [{name}]({doc_path})")
|
|
198
|
+
sections.append("")
|
|
199
|
+
|
|
200
|
+
sections.append("### By Domain")
|
|
201
|
+
for doc_path in sorted(all_docs.keys()):
|
|
202
|
+
if doc_path.startswith('by-domain/'):
|
|
203
|
+
name = doc_path.replace('by-domain/', '').replace('.md', '')
|
|
204
|
+
sections.append(f"- [{name}]({doc_path})")
|
|
205
|
+
sections.append("")
|
|
206
|
+
|
|
207
|
+
sections.append("### By Concern")
|
|
208
|
+
for doc_path in sorted(all_docs.keys()):
|
|
209
|
+
if doc_path.startswith('by-concern/'):
|
|
210
|
+
name = doc_path.replace('by-concern/', '').replace('.md', '')
|
|
211
|
+
sections.append(f"- [{name}]({doc_path})")
|
|
212
|
+
sections.append("")
|
|
213
|
+
|
|
214
|
+
sections.append("### By Layer")
|
|
215
|
+
for doc_path in sorted(all_docs.keys()):
|
|
216
|
+
if doc_path.startswith('by-layer/'):
|
|
217
|
+
name = doc_path.replace('by-layer/', '').replace('.md', '')
|
|
218
|
+
sections.append(f"- [{name}]({doc_path})")
|
|
219
|
+
sections.append("")
|
|
220
|
+
|
|
221
|
+
sections.append("---\n")
|
|
222
|
+
|
|
223
|
+
# Statistics
|
|
224
|
+
sections.append("## 📊 Project Statistics\n")
|
|
225
|
+
|
|
226
|
+
type_counts = {}
|
|
227
|
+
for item in self.items:
|
|
228
|
+
type_counts[item.item_type] = type_counts.get(item.item_type, 0) + 1
|
|
229
|
+
sections.append("### By Type")
|
|
230
|
+
for item_type, count in sorted(type_counts.items()):
|
|
231
|
+
sections.append(f"- **{item_type.title()}**: {count}")
|
|
232
|
+
sections.append("")
|
|
233
|
+
|
|
234
|
+
# Domain distribution
|
|
235
|
+
domain_counts = {}
|
|
236
|
+
for item in self.items:
|
|
237
|
+
for domain in item.domains:
|
|
238
|
+
domain_counts[domain] = domain_counts.get(domain, 0) + 1
|
|
239
|
+
if domain_counts:
|
|
240
|
+
sections.append("### By Domain")
|
|
241
|
+
for domain, count in sorted(domain_counts.items(), key=lambda x: x[1], reverse=True):
|
|
242
|
+
sections.append(f"- **{domain.replace('_', ' ').title()}**: {count}")
|
|
243
|
+
sections.append("")
|
|
244
|
+
|
|
245
|
+
sections.append("---\n")
|
|
246
|
+
|
|
247
|
+
# Index
|
|
248
|
+
sections.append("## 🔍 Complete Index\n")
|
|
249
|
+
for item in sorted(self.items, key=lambda x: x.name):
|
|
250
|
+
sections.append(f"- **{item.name}** ({item.item_type}) - `{item.file_path}`")
|
|
251
|
+
|
|
252
|
+
return "\n".join(sections)
|
|
253
|
+
|
|
254
|
+
def _generate_category_doc(self, title: str, items: List[DocumentedItem], description: str) -> str:
|
|
255
|
+
"""Generate documentation for a specific category."""
|
|
256
|
+
sections = []
|
|
257
|
+
|
|
258
|
+
sections.append(f"# {title}\n")
|
|
259
|
+
sections.append(f"*{description}*\n")
|
|
260
|
+
sections.append(f"**Items in this category:** {len(items)}\n")
|
|
261
|
+
sections.append("---\n")
|
|
262
|
+
|
|
263
|
+
# Table of contents
|
|
264
|
+
sections.append("## Table of Contents\n")
|
|
265
|
+
for item in sorted(items, key=lambda x: x.name):
|
|
266
|
+
sections.append(f"- [{item.name}](#{item.name.lower().replace(' ', '-')})")
|
|
267
|
+
sections.append("\n---\n")
|
|
268
|
+
|
|
269
|
+
# Items
|
|
270
|
+
for item in sorted(items, key=lambda x: x.name):
|
|
271
|
+
sections.append(f"## {item.name}\n")
|
|
272
|
+
sections.append(f"**Type:** {item.item_type} ")
|
|
273
|
+
sections.append(f"**File:** `{item.file_path}`\n")
|
|
274
|
+
|
|
275
|
+
if item.domains:
|
|
276
|
+
sections.append(f"**Domains:** {', '.join(sorted(item.domains))} ")
|
|
277
|
+
if item.concerns:
|
|
278
|
+
sections.append(f"**Concerns:** {', '.join(sorted(item.concerns))} ")
|
|
279
|
+
if item.layers:
|
|
280
|
+
sections.append(f"**Layers:** {', '.join(sorted(item.layers))} ")
|
|
281
|
+
sections.append("")
|
|
282
|
+
|
|
283
|
+
sections.append(item.content)
|
|
284
|
+
sections.append("\n---\n")
|
|
285
|
+
|
|
286
|
+
return "\n".join(sections)
|
|
287
|
+
|
|
288
|
+
def generate_all(self) -> Dict[str, str]:
|
|
289
|
+
"""Generate all consolidated documentation."""
|
|
290
|
+
# Categorize all items first
|
|
291
|
+
self.categorize_items()
|
|
292
|
+
|
|
293
|
+
# Generate all category docs
|
|
294
|
+
all_docs = {}
|
|
295
|
+
all_docs.update(self.generate_by_type())
|
|
296
|
+
all_docs.update(self.generate_by_domain())
|
|
297
|
+
all_docs.update(self.generate_by_concern())
|
|
298
|
+
all_docs.update(self.generate_by_layer())
|
|
299
|
+
|
|
300
|
+
# Generate master README
|
|
301
|
+
all_docs['README.md'] = self.generate_master_readme(all_docs)
|
|
302
|
+
|
|
303
|
+
return all_docs
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
🔒{pure-exceptions,¬io,¬side-effects,¬exec}
|
|
7
7
|
⚡{O(1):exception-creation}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs Custom Exceptions
|
|
10
10
|
|
|
11
11
|
Structured exception hierarchy for error handling with:
|
|
12
|
-
- Base exception (VooDocsError for all
|
|
12
|
+
- Base exception (VooDocsError for all Voodocs errors)
|
|
13
13
|
- Parser errors (ParserError, ParserNotBuiltError, AnnotationError)
|
|
14
14
|
- Validation errors (InvalidAnnotationError, ValidationError)
|
|
15
15
|
- Generator errors (GeneratorError)
|
|
@@ -20,7 +20,7 @@ Structured exception hierarchy for error handling with:
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class VooDocsError(Exception):
|
|
23
|
-
"""Base exception for all
|
|
23
|
+
"""Base exception for all Voodocs errors."""
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
26
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{read-only:source,write:docs-output,¬network,¬arbitrary-exec}
|
|
7
7
|
⚡{O(n)|n=source-lines,ast-parsing:linear}
|
|
8
8
|
|
|
9
|
-
AI-Native
|
|
9
|
+
AI-Native Voodocs Plugin for DarkArts
|
|
10
10
|
|
|
11
11
|
Enhanced documentation plugin supporting:
|
|
12
12
|
- @voodocs annotation parsing (AI-native documentation)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{read-only:annotations,¬file-io,¬network,¬exec}
|
|
7
7
|
⚡{O(n)|n=annotations,validation:linear}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs Annotation Validator
|
|
10
10
|
|
|
11
11
|
Quality assurance for @voodocs annotations with:
|
|
12
12
|
- Syntax validation (correct format and structure)
|
|
@@ -40,7 +40,7 @@ class ValidationIssue:
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
class AnnotationValidator:
|
|
43
|
-
"""Validates
|
|
43
|
+
"""Validates Voodocs annotations."""
|
|
44
44
|
|
|
45
45
|
VALID_FIELDS = {
|
|
46
46
|
"module_purpose", "dependencies", "assumptions", "security_model",
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{read-only:annotations,write:docs-dir,¬network,¬exec}
|
|
7
7
|
⚡{O(n)|n=annotations,translation:linear}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs Documentation Generator
|
|
10
10
|
|
|
11
11
|
Translates @voodocs annotations (DarkArts language) into human-readable documentation with:
|
|
12
12
|
- Mathematical symbol translation (∀, ∃, ∈, → natural language)
|
|
@@ -588,8 +588,8 @@ class DocumentationGenerator:
|
|
|
588
588
|
color = "green" if coverage >= 80 else "yellow" if coverage >= 50 else "red"
|
|
589
589
|
badges.append(f"")
|
|
590
590
|
|
|
591
|
-
#
|
|
592
|
-
badges.append("")
|
|
593
593
|
|
|
594
594
|
# Language badge
|
|
595
595
|
lang = parsed.language.value if hasattr(parsed.language, 'value') else str(parsed.language)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{read:markdown-files,write:html-files,¬network,¬exec}
|
|
7
7
|
⚡{O(n)|n=markdown-length,conversion:linear}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs HTML Exporter
|
|
10
10
|
|
|
11
11
|
Markdown to HTML conversion with styling:
|
|
12
12
|
- Markdown parsing (markdown library or fallback)
|
|
@@ -102,7 +102,7 @@ class HTMLExporter:
|
|
|
102
102
|
<head>
|
|
103
103
|
<meta charset="UTF-8">
|
|
104
104
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
105
|
-
<title>{title} -
|
|
105
|
+
<title>{title} - Voodocs Documentation</title>
|
|
106
106
|
<style>
|
|
107
107
|
{self.css}
|
|
108
108
|
</style>
|
|
@@ -111,13 +111,13 @@ class HTMLExporter:
|
|
|
111
111
|
<div class="container">
|
|
112
112
|
<header>
|
|
113
113
|
<h1 class="voodocs-title">{title}</h1>
|
|
114
|
-
<p class="voodocs-subtitle">Generated by
|
|
114
|
+
<p class="voodocs-subtitle">Generated by Voodocs</p>
|
|
115
115
|
</header>
|
|
116
116
|
<main>
|
|
117
117
|
{content}
|
|
118
118
|
</main>
|
|
119
119
|
<footer>
|
|
120
|
-
<p>Documentation generated with <a href="https://voodocs.dev">
|
|
120
|
+
<p>Documentation generated with <a href="https://voodocs.dev">Voodocs</a></p>
|
|
121
121
|
</footer>
|
|
122
122
|
</div>
|
|
123
123
|
</body>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{write:config-files}
|
|
7
7
|
⚡{O(n):instruction-generation|template-based}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs AI Instruction Generator
|
|
10
10
|
|
|
11
11
|
Generates instruction files that teach AI coding assistants (Cursor, Claude Code, etc.)
|
|
12
12
|
how to use @voodocs annotations while writing code.
|
|
@@ -18,7 +18,7 @@ import json
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class InstructionGenerator:
|
|
21
|
-
"""Generates AI assistant instruction files for
|
|
21
|
+
"""Generates AI assistant instruction files for Voodocs."""
|
|
22
22
|
|
|
23
23
|
# Supported AI assistants
|
|
24
24
|
ASSISTANTS = {
|
|
@@ -126,10 +126,10 @@ class InstructionGenerator:
|
|
|
126
126
|
|
|
127
127
|
def _generate_header(self) -> str:
|
|
128
128
|
"""Generate instruction header."""
|
|
129
|
-
return f"""#
|
|
129
|
+
return f"""# Voodocs Instructions for {self.assistant_info['name']}
|
|
130
130
|
|
|
131
131
|
**Project**: {self.project_name}
|
|
132
|
-
**Generated**: Automatically by
|
|
132
|
+
**Generated**: Automatically by Voodocs
|
|
133
133
|
**Purpose**: Guide AI assistants to document code using @voodocs annotations
|
|
134
134
|
|
|
135
135
|
---"""
|
|
@@ -138,7 +138,7 @@ class InstructionGenerator:
|
|
|
138
138
|
"""Generate overview section."""
|
|
139
139
|
return """## Overview
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
Voodocs is an AI-native documentation system that allows you to document code in **DarkArts language** - a mathematical and logical notation that AI naturally understands. Your annotations will be automatically translated into human-readable documentation, property-based tests, and API specifications.
|
|
142
142
|
|
|
143
143
|
**Key Benefits:**
|
|
144
144
|
- Document in AI's native language (mathematical notation)
|
|
@@ -154,7 +154,7 @@ As an AI coding assistant, you should add `@voodocs` annotations to **every sign
|
|
|
154
154
|
"""Generate core principles section."""
|
|
155
155
|
return """## Core Principles
|
|
156
156
|
|
|
157
|
-
When writing code with
|
|
157
|
+
When writing code with Voodocs annotations, follow these principles:
|
|
158
158
|
|
|
159
159
|
1. **Annotate as you code** - Add `@voodocs` annotations immediately when creating functions/classes
|
|
160
160
|
2. **Be precise** - Use mathematical notation for exact specifications
|
|
@@ -310,7 +310,7 @@ DarkArts is a mathematical notation language for precise specifications. Use the
|
|
|
310
310
|
| `ℤ` | Integers (..., -1, 0, 1, ...) | `x ∈ ℤ` |
|
|
311
311
|
| `ℝ` | Real numbers | `x ∈ ℝ` |
|
|
312
312
|
|
|
313
|
-
**Tip**: You can use plain English too!
|
|
313
|
+
**Tip**: You can use plain English too! Voodocs understands both mathematical notation and natural language. Mix them for clarity."""
|
|
314
314
|
|
|
315
315
|
def _generate_examples(self, language: str) -> str:
|
|
316
316
|
"""Generate example annotations."""
|
|
@@ -554,7 +554,7 @@ complexity: "O(1)"
|
|
|
554
554
|
\"\"\"
|
|
555
555
|
```
|
|
556
556
|
|
|
557
|
-
|
|
557
|
+
Voodocs generates:
|
|
558
558
|
|
|
559
559
|
```python
|
|
560
560
|
# Generated test
|
|
@@ -611,7 +611,7 @@ complexity: "O(n log n)"
|
|
|
611
611
|
|
|
612
612
|
**Also Good:**
|
|
613
613
|
```python
|
|
614
|
-
complexity: "O(n)" #
|
|
614
|
+
complexity: "O(n)" # Voodocs infers space as O(1)
|
|
615
615
|
```
|
|
616
616
|
|
|
617
617
|
### 4. Document Security Implications
|
|
@@ -678,7 +678,7 @@ side_effects: ["Does stuff"] # Too vague
|
|
|
678
678
|
|
|
679
679
|
By documenting in DarkArts language, you're not just writing comments - you're creating a **formal specification** that generates tests, documentation, and API specs automatically.
|
|
680
680
|
|
|
681
|
-
**Generated by
|
|
681
|
+
**Generated by Voodocs** - AI-native documentation for modern development."""
|
|
682
682
|
|
|
683
683
|
def detect_assistant(self) -> Optional[str]:
|
|
684
684
|
"""
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{read:markdown-files,write:pdf-files,¬network,¬exec}
|
|
7
7
|
⚡{O(n)|n=markdown-length,pdf-rendering:depends-on-lib}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs PDF Exporter
|
|
10
10
|
|
|
11
11
|
Markdown to PDF conversion with print-ready formatting:
|
|
12
12
|
- WeasyPrint support (HTML → PDF with CSS)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{read-only:annotations,write:test-files,¬network,¬exec}
|
|
7
7
|
⚡{O(n)|n=functions,codegen:linear}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs Test Generator
|
|
10
10
|
|
|
11
11
|
Automatic test generation from @voodocs annotations with:
|
|
12
12
|
- Precondition tests (validate inputs match declared constraints)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
🔒{⚠️NETWORK:supabase-api,write:config-dir,¬sensitive-data,anonymous-only}
|
|
7
7
|
⚡{O(1):event-creation,network:async-non-blocking}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Voodocs Telemetry Client
|
|
10
10
|
|
|
11
11
|
Privacy-respecting anonymous usage analytics with:
|
|
12
12
|
- Anonymous session IDs (UUID-based, no PII)
|
|
@@ -32,11 +32,11 @@ import urllib.error
|
|
|
32
32
|
SUPABASE_URL = os.getenv("VOODOCS_SUPABASE_URL", "https://sjatkayudkbkmipubhfy.supabase.co")
|
|
33
33
|
SUPABASE_ANON_KEY = os.getenv("VOODOCS_SUPABASE_ANON_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNqYXRrYXl1ZGtia21pcHViaGZ5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjYxNjE0MTMsImV4cCI6MjA4MTczNzQxM30.Wj3dbokjKPsmWTgbPw77aPnCoZCsE5hrFfIH-R_ErzI")
|
|
34
34
|
|
|
35
|
-
#
|
|
35
|
+
# Voodocs version
|
|
36
36
|
VERSION = "0.1.2"
|
|
37
37
|
|
|
38
38
|
class TelemetryClient:
|
|
39
|
-
"""Anonymous telemetry client for
|
|
39
|
+
"""Anonymous telemetry client for Voodocs CLI."""
|
|
40
40
|
|
|
41
41
|
def __init__(self):
|
|
42
42
|
self.session_id = self._get_or_create_session_id()
|
|
@@ -90,9 +90,9 @@ class TelemetryClient:
|
|
|
90
90
|
|
|
91
91
|
if not notice_file.exists():
|
|
92
92
|
print("\n" + "="*70)
|
|
93
|
-
print("📊
|
|
93
|
+
print("📊 Voodocs Telemetry")
|
|
94
94
|
print("="*70)
|
|
95
|
-
print("
|
|
95
|
+
print("Voodocs collects anonymous usage data to improve the product.")
|
|
96
96
|
print("No personal information is collected.")
|
|
97
97
|
print()
|
|
98
98
|
print("To disable telemetry:")
|
|
@@ -7,14 +7,15 @@ This module provides validation tools for @darkarts annotations.
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
9
|
The validation module ensures that @darkarts annotations are accurate and up-to-date by:
|
|
10
|
+
|
|
10
11
|
- **Semantic Validation**: Verifying dependencies match actual imports
|
|
11
|
-
- **Performance Validation**: Checking complexity claims match code structure
|
|
12
|
+
- **Performance Validation**: Checking complexity claims match code structure
|
|
12
13
|
- **Benchmarking**: Measuring actual performance to validate claims
|
|
13
14
|
- **Auto-fix**: Automatically correcting validation issues
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
17
|
-
The validation module is part of the
|
|
18
|
+
The validation module is part of the Voodocs package:
|
|
18
19
|
|
|
19
20
|
```bash
|
|
20
21
|
pip install voodocs
|
|
@@ -117,11 +118,13 @@ validation/
|
|
|
117
118
|
## Next Steps
|
|
118
119
|
|
|
119
120
|
**Phase 2**: CLI Integration (Week 2)
|
|
121
|
+
|
|
120
122
|
- Integrate into `voodocs` CLI
|
|
121
123
|
- Add `voodocs validate` command
|
|
122
124
|
- Add `--validate` flag to `voodocs generate`
|
|
123
125
|
|
|
124
126
|
**Phase 3**: Advanced Features (Week 3)
|
|
127
|
+
|
|
125
128
|
- Watch mode integration
|
|
126
129
|
- Configuration file support
|
|
127
130
|
- HTML/JSON reports
|
|
@@ -144,4 +147,4 @@ See `../../docs/darkarts/CODE_REVIEW_PROCESS.md` for contribution guidelines.
|
|
|
144
147
|
|
|
145
148
|
## License
|
|
146
149
|
|
|
147
|
-
Part of
|
|
150
|
+
Part of Voodocs - see repository root for license.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voodocs/cli",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "AI-Native Symbolic Documentation System - The world's first documentation tool using mathematical notation with semantic validation",
|
|
5
5
|
"main": "voodocs_cli.py",
|
|
6
6
|
"bin": {
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"lib/darkarts/core/",
|
|
61
61
|
"lib/darkarts/validation/",
|
|
62
62
|
"lib/darkarts/instructions/",
|
|
63
|
+
"lib/darkarts/documentation/",
|
|
63
64
|
"lib/darkarts/exceptions.py",
|
|
64
65
|
"lib/darkarts/telemetry.py",
|
|
65
66
|
"lib/darkarts/parsers/typescript/dist/",
|
package/requirements.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Voodocs Python Dependencies
|
|
2
2
|
# Python 3.7+ required
|
|
3
3
|
# Install with: pip3 install -r requirements.txt
|
|
4
4
|
|
|
@@ -9,5 +9,5 @@ PyYAML>=6.0.0
|
|
|
9
9
|
# pytest>=7.0.0 # For running unit tests
|
|
10
10
|
# hypothesis>=6.0.0 # For property-based testing (used in generated tests)
|
|
11
11
|
|
|
12
|
-
# Note:
|
|
12
|
+
# Note: Voodocs core uses only Python standard library.
|
|
13
13
|
# PyYAML is the only required external dependency for API spec generation.
|