@voodocs/cli 0.1.0

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 (52) hide show
  1. package/LICENSE +37 -0
  2. package/README.md +153 -0
  3. package/USAGE.md +314 -0
  4. package/cli.py +1340 -0
  5. package/examples/.cursorrules +437 -0
  6. package/examples/instructions/.claude/instructions.md +372 -0
  7. package/examples/instructions/.cursorrules +437 -0
  8. package/examples/instructions/.windsurfrules +437 -0
  9. package/examples/instructions/VOODOCS_INSTRUCTIONS.md +437 -0
  10. package/examples/math_example.py +41 -0
  11. package/examples/phase2_test.py +24 -0
  12. package/examples/test_compound_conditions.py +40 -0
  13. package/examples/test_math_example.py +186 -0
  14. package/lib/darkarts/README.md +115 -0
  15. package/lib/darkarts/__init__.py +16 -0
  16. package/lib/darkarts/annotations/__init__.py +34 -0
  17. package/lib/darkarts/annotations/parser.py +618 -0
  18. package/lib/darkarts/annotations/types.py +181 -0
  19. package/lib/darkarts/cli.py +128 -0
  20. package/lib/darkarts/core/__init__.py +32 -0
  21. package/lib/darkarts/core/interface.py +256 -0
  22. package/lib/darkarts/core/loader.py +231 -0
  23. package/lib/darkarts/core/plugin.py +215 -0
  24. package/lib/darkarts/core/registry.py +146 -0
  25. package/lib/darkarts/exceptions.py +51 -0
  26. package/lib/darkarts/parsers/typescript/dist/cli.d.ts +9 -0
  27. package/lib/darkarts/parsers/typescript/dist/cli.d.ts.map +1 -0
  28. package/lib/darkarts/parsers/typescript/dist/cli.js +69 -0
  29. package/lib/darkarts/parsers/typescript/dist/cli.js.map +1 -0
  30. package/lib/darkarts/parsers/typescript/dist/parser.d.ts +111 -0
  31. package/lib/darkarts/parsers/typescript/dist/parser.d.ts.map +1 -0
  32. package/lib/darkarts/parsers/typescript/dist/parser.js +365 -0
  33. package/lib/darkarts/parsers/typescript/dist/parser.js.map +1 -0
  34. package/lib/darkarts/parsers/typescript/package-lock.json +51 -0
  35. package/lib/darkarts/parsers/typescript/package.json +19 -0
  36. package/lib/darkarts/parsers/typescript/src/cli.ts +41 -0
  37. package/lib/darkarts/parsers/typescript/src/parser.ts +408 -0
  38. package/lib/darkarts/parsers/typescript/tsconfig.json +19 -0
  39. package/lib/darkarts/plugins/voodocs/__init__.py +379 -0
  40. package/lib/darkarts/plugins/voodocs/ai_native_plugin.py +151 -0
  41. package/lib/darkarts/plugins/voodocs/annotation_validator.py +280 -0
  42. package/lib/darkarts/plugins/voodocs/api_spec_generator.py +486 -0
  43. package/lib/darkarts/plugins/voodocs/documentation_generator.py +610 -0
  44. package/lib/darkarts/plugins/voodocs/html_exporter.py +260 -0
  45. package/lib/darkarts/plugins/voodocs/instruction_generator.py +706 -0
  46. package/lib/darkarts/plugins/voodocs/pdf_exporter.py +66 -0
  47. package/lib/darkarts/plugins/voodocs/test_generator.py +636 -0
  48. package/package.json +70 -0
  49. package/requirements.txt +13 -0
  50. package/templates/ci/github-actions.yml +73 -0
  51. package/templates/ci/gitlab-ci.yml +35 -0
  52. package/templates/ci/pre-commit-hook.sh +26 -0
@@ -0,0 +1,706 @@
1
+ """
2
+ VooDocs AI Instruction Generator
3
+
4
+ Generates instruction files that teach AI coding assistants (Cursor, Claude Code, etc.)
5
+ how to use @voodocs annotations while writing code.
6
+ """
7
+
8
+ from typing import Optional, Dict, List
9
+ from pathlib import Path
10
+ import json
11
+
12
+
13
+ class InstructionGenerator:
14
+ """Generates AI assistant instruction files for VooDocs."""
15
+
16
+ # Supported AI assistants
17
+ ASSISTANTS = {
18
+ "cursor": {
19
+ "name": "Cursor",
20
+ "config_file": ".cursorrules",
21
+ "format": "markdown"
22
+ },
23
+ "claude": {
24
+ "name": "Claude Code / Cline",
25
+ "config_file": ".claude/instructions.md",
26
+ "format": "markdown"
27
+ },
28
+ "copilot": {
29
+ "name": "GitHub Copilot",
30
+ "config_file": ".github/copilot-instructions.md",
31
+ "format": "markdown"
32
+ },
33
+ "windsurf": {
34
+ "name": "Windsurf",
35
+ "config_file": ".windsurfrules",
36
+ "format": "markdown"
37
+ },
38
+ "generic": {
39
+ "name": "Generic AI Assistant",
40
+ "config_file": "VOODOCS_INSTRUCTIONS.md",
41
+ "format": "markdown"
42
+ }
43
+ }
44
+
45
+ def __init__(self, assistant: str = "generic", project_name: str = "Your Project"):
46
+ """
47
+ Initialize instruction generator.
48
+
49
+ Args:
50
+ assistant: AI assistant type ("cursor", "claude", "copilot", "windsurf", "generic")
51
+ project_name: Name of the project for personalization
52
+ """
53
+ if assistant not in self.ASSISTANTS:
54
+ raise ValueError(f"Unsupported assistant: {assistant}. Choose from: {list(self.ASSISTANTS.keys())}")
55
+
56
+ self.assistant = assistant
57
+ self.assistant_info = self.ASSISTANTS[assistant]
58
+ self.project_name = project_name
59
+
60
+ def generate(self, output_file: Optional[str] = None, language: str = "python") -> str:
61
+ """
62
+ Generate instruction file for the AI assistant.
63
+
64
+ Args:
65
+ output_file: Optional output file path (defaults to assistant's config file)
66
+ language: Primary programming language ("python", "typescript", "javascript")
67
+
68
+ Returns:
69
+ Generated instruction content
70
+ """
71
+ instructions = self._generate_instructions(language)
72
+
73
+ # Determine output file
74
+ if output_file is None:
75
+ output_file = self.assistant_info["config_file"]
76
+
77
+ # Write to file
78
+ output_path = Path(output_file)
79
+ output_path.parent.mkdir(parents=True, exist_ok=True)
80
+ output_path.write_text(instructions, encoding='utf-8')
81
+
82
+ return instructions
83
+
84
+ def _generate_instructions(self, language: str) -> str:
85
+ """Generate the instruction content."""
86
+ sections = []
87
+
88
+ # Header
89
+ sections.append(self._generate_header())
90
+
91
+ # Overview
92
+ sections.append(self._generate_overview())
93
+
94
+ # Core principles
95
+ sections.append(self._generate_core_principles())
96
+
97
+ # Annotation syntax
98
+ sections.append(self._generate_annotation_syntax(language))
99
+
100
+ # Annotation fields
101
+ sections.append(self._generate_annotation_fields())
102
+
103
+ # DarkArts language guide
104
+ sections.append(self._generate_darkarts_guide())
105
+
106
+ # Examples
107
+ sections.append(self._generate_examples(language))
108
+
109
+ # Workflow integration
110
+ sections.append(self._generate_workflow())
111
+
112
+ # Best practices
113
+ sections.append(self._generate_best_practices())
114
+
115
+ # Footer
116
+ sections.append(self._generate_footer())
117
+
118
+ return "\n\n".join(sections)
119
+
120
+ def _generate_header(self) -> str:
121
+ """Generate instruction header."""
122
+ return f"""# VooDocs Instructions for {self.assistant_info['name']}
123
+
124
+ **Project**: {self.project_name}
125
+ **Generated**: Automatically by VooDocs
126
+ **Purpose**: Guide AI assistants to document code using @voodocs annotations
127
+
128
+ ---"""
129
+
130
+ def _generate_overview(self) -> str:
131
+ """Generate overview section."""
132
+ return """## Overview
133
+
134
+ 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.
135
+
136
+ **Key Benefits:**
137
+ - Document in AI's native language (mathematical notation)
138
+ - Automatic generation of comprehensive tests
139
+ - Property-based testing with Hypothesis
140
+ - OpenAPI/GraphQL spec generation
141
+ - Human-readable documentation output
142
+
143
+ **Your Role:**
144
+ As an AI coding assistant, you should add `@voodocs` annotations to **every significant function, class, and module** you write. Think of it as "documentation-driven development" where you specify the contract first."""
145
+
146
+ def _generate_core_principles(self) -> str:
147
+ """Generate core principles section."""
148
+ return """## Core Principles
149
+
150
+ When writing code with VooDocs annotations, follow these principles:
151
+
152
+ 1. **Annotate as you code** - Add `@voodocs` annotations immediately when creating functions/classes
153
+ 2. **Be precise** - Use mathematical notation for exact specifications
154
+ 3. **Think in contracts** - Define preconditions, postconditions, and invariants
155
+ 4. **Specify complexity** - Always include time/space complexity
156
+ 5. **Document security** - Note security implications and assumptions
157
+ 6. **Fail-safe design** - Specify error cases and how they're handled"""
158
+
159
+ def _generate_annotation_syntax(self, language: str) -> str:
160
+ """Generate annotation syntax section."""
161
+ if language == "python":
162
+ return """## Annotation Syntax (Python)
163
+
164
+ Place `@voodocs` annotations in docstrings:
165
+
166
+ ```python
167
+ def function_name(param1: type, param2: type) -> return_type:
168
+ \"\"\"@voodocs
169
+ preconditions: ["param1 > 0", "param2 is not None"]
170
+ postconditions: ["result >= param1"]
171
+ complexity: "O(n)"
172
+ \"\"\"
173
+ # Implementation
174
+ pass
175
+ ```
176
+
177
+ For classes:
178
+
179
+ ```python
180
+ class ClassName:
181
+ \"\"\"@voodocs
182
+ class_invariants: ["∀ item ∈ self.items: item.is_valid()"]
183
+ state_transitions: ["IDLE → PROCESSING", "PROCESSING → COMPLETE"]
184
+ \"\"\"
185
+ pass
186
+ ```"""
187
+
188
+ elif language in ["typescript", "javascript"]:
189
+ return """## Annotation Syntax (TypeScript/JavaScript)
190
+
191
+ Place `@voodocs` annotations in JSDoc-style comments:
192
+
193
+ ```typescript
194
+ /**@voodocs
195
+ preconditions: ["amount > 0", "account.isActive()"]
196
+ postconditions: ["account.balance decreased by amount"]
197
+ complexity: "O(1)"
198
+ security_implications: ["Requires authentication", "Validates account ownership"]
199
+ */
200
+ function withdraw(account: Account, amount: number): boolean {
201
+ // Implementation
202
+ }
203
+ ```
204
+
205
+ For classes:
206
+
207
+ ```typescript
208
+ /**@voodocs
209
+ class_invariants: ["this.balance >= 0", "this.transactions.length >= 0"]
210
+ state_transitions: ["PENDING → ACTIVE", "ACTIVE → SUSPENDED", "SUSPENDED → CLOSED"]
211
+ */
212
+ class BankAccount {
213
+ // Implementation
214
+ }
215
+ ```"""
216
+
217
+ else:
218
+ return """## Annotation Syntax
219
+
220
+ Use language-appropriate comment syntax with `@voodocs` marker."""
221
+
222
+ def _generate_annotation_fields(self) -> str:
223
+ """Generate annotation fields reference."""
224
+ return """## Annotation Fields Reference
225
+
226
+ ### For Functions/Methods
227
+
228
+ | Field | Required | Description | Example |
229
+ |-------|----------|-------------|---------|
230
+ | `preconditions` | Recommended | Conditions that must be true before execution | `["x > 0", "user is authenticated"]` |
231
+ | `postconditions` | Recommended | Conditions guaranteed after execution | `["result > 0", "database updated"]` |
232
+ | `complexity` | Recommended | Time/space complexity | `"O(n log n)"` or `"O(n)"` |
233
+ | `invariants` | Optional | Properties that remain unchanged | `["∀ x: x ∈ original_set ⇒ x ∈ result_set"]` |
234
+ | `error_cases` | Optional | Error conditions and exceptions | `["x < 0 → ValueError", "file not found → FileNotFoundError"]` |
235
+ | `side_effects` | Optional | External changes made | `["Writes to database", "Sends email"]` |
236
+ | `security_implications` | Optional | Security considerations | `["Requires admin role", "Rate limited"]` |
237
+ | `assumptions` | Optional | Environmental assumptions | `["Database is available", "Network is stable"]` |
238
+
239
+ ### For Classes
240
+
241
+ | Field | Description | Example |
242
+ |-------|-------------|---------|
243
+ | `class_invariants` | Properties that always hold | `["∀ item ∈ queue: item.status ∈ VALID_STATUSES"]` |
244
+ | `state_transitions` | Valid state changes | `["IDLE → PROCESSING", "PROCESSING → COMPLETE"]` |
245
+ | `thread_safety` | Concurrency safety | `"Thread-safe with mutex"` or `"Not thread-safe"` |
246
+
247
+ ### For Modules
248
+
249
+ | Field | Description | Example |
250
+ |-------|-------------|---------|
251
+ | `module_purpose` | High-level module description | `"User authentication and authorization"` |
252
+ | `dependencies` | External dependencies | `["@supabase/supabase-js", "bcrypt"]` |
253
+ | `assumptions` | Module-level assumptions | `["Database schema v2.0", "Redis available"]` |
254
+ | `security_model` | Overall security approach | `"Defense in depth - fails closed"` |"""
255
+
256
+ def _generate_darkarts_guide(self) -> str:
257
+ """Generate DarkArts language guide."""
258
+ return """## DarkArts Language Guide
259
+
260
+ DarkArts is a mathematical notation language for precise specifications. Use these symbols:
261
+
262
+ ### Logical Operators
263
+
264
+ | Symbol | Meaning | Example |
265
+ |--------|---------|---------|
266
+ | `∧` | AND | `x > 0 ∧ y > 0` |
267
+ | `∨` | OR | `x = 0 ∨ y = 0` |
268
+ | `¬` | NOT | `¬(x < 0)` |
269
+ | `⇒` | IMPLIES | `x > 0 ⇒ result > 0` |
270
+ | `⇔` | IF AND ONLY IF | `result = true ⇔ user.isAdmin` |
271
+
272
+ ### Quantifiers
273
+
274
+ | Symbol | Meaning | Example |
275
+ |--------|---------|---------|
276
+ | `∀` | FOR ALL | `∀ x ∈ items: x > 0` |
277
+ | `∃` | THERE EXISTS | `∃ x ∈ items: x = target` |
278
+
279
+ ### Set Operations
280
+
281
+ | Symbol | Meaning | Example |
282
+ |--------|---------|---------|
283
+ | `∈` | IN / ELEMENT OF | `x ∈ valid_values` |
284
+ | `∉` | NOT IN | `x ∉ blacklist` |
285
+ | `⊆` | SUBSET OF | `result ⊆ input` |
286
+ | `∪` | UNION | `result = set1 ∪ set2` |
287
+ | `∩` | INTERSECTION | `common = set1 ∩ set2` |
288
+
289
+ ### Comparisons
290
+
291
+ | Symbol | Meaning | Example |
292
+ |--------|---------|---------|
293
+ | `≥` | GREATER THAN OR EQUAL | `x ≥ 0` |
294
+ | `≤` | LESS THAN OR EQUAL | `x ≤ 100` |
295
+ | `≠` | NOT EQUAL | `x ≠ 0` |
296
+ | `≈` | APPROXIMATELY EQUAL | `result ≈ expected` |
297
+
298
+ ### Number Sets
299
+
300
+ | Symbol | Meaning | Example |
301
+ |--------|---------|---------|
302
+ | `ℕ` | Natural numbers (0, 1, 2, ...) | `n ∈ ℕ` |
303
+ | `ℤ` | Integers (..., -1, 0, 1, ...) | `x ∈ ℤ` |
304
+ | `ℝ` | Real numbers | `x ∈ ℝ` |
305
+
306
+ **Tip**: You can use plain English too! VooDocs understands both mathematical notation and natural language. Mix them for clarity."""
307
+
308
+ def _generate_examples(self, language: str) -> str:
309
+ """Generate example annotations."""
310
+ if language == "python":
311
+ return """## Examples
312
+
313
+ ### Example 1: Simple Function
314
+
315
+ ```python
316
+ def calculate_discount(price: float, discount_percent: float) -> float:
317
+ \"\"\"@voodocs
318
+ preconditions: [
319
+ "price > 0",
320
+ "discount_percent >= 0",
321
+ "discount_percent <= 100"
322
+ ]
323
+ postconditions: [
324
+ "result >= 0",
325
+ "result <= price",
326
+ "result = price * (1 - discount_percent/100)"
327
+ ]
328
+ complexity: "O(1)"
329
+ error_cases: [
330
+ "price <= 0 → ValueError",
331
+ "discount_percent < 0 → ValueError",
332
+ "discount_percent > 100 → ValueError"
333
+ ]
334
+ \"\"\"
335
+ if price <= 0:
336
+ raise ValueError("Price must be positive")
337
+ if not 0 <= discount_percent <= 100:
338
+ raise ValueError("Discount must be between 0 and 100")
339
+
340
+ return price * (1 - discount_percent / 100)
341
+ ```
342
+
343
+ ### Example 2: Function with Security
344
+
345
+ ```python
346
+ def delete_user(user_id: str, admin_token: str) -> bool:
347
+ \"\"\"@voodocs
348
+ preconditions: [
349
+ "user_id is valid UUID",
350
+ "admin_token is valid JWT",
351
+ "admin has 'delete_user' permission"
352
+ ]
353
+ postconditions: [
354
+ "returns true ⇔ user deleted successfully",
355
+ "returns false ⇔ user not found ∨ permission denied"
356
+ ]
357
+ security_implications: [
358
+ "Requires admin authentication",
359
+ "Logs deletion for audit trail",
360
+ "Soft delete - data retained for 30 days"
361
+ ]
362
+ side_effects: [
363
+ "Writes to audit log",
364
+ "Sends notification email",
365
+ "Invalidates user sessions"
366
+ ]
367
+ complexity: "O(1)"
368
+ \"\"\"
369
+ # Implementation
370
+ pass
371
+ ```
372
+
373
+ ### Example 3: Class with Invariants
374
+
375
+ ```python
376
+ class BankAccount:
377
+ \"\"\"@voodocs
378
+ class_invariants: [
379
+ "self.balance >= 0",
380
+ "len(self.transactions) >= 0",
381
+ "∀ tx ∈ self.transactions: tx.amount ≠ 0"
382
+ ]
383
+ state_transitions: [
384
+ "PENDING → ACTIVE: when KYC verified",
385
+ "ACTIVE → FROZEN: when suspicious activity detected",
386
+ "FROZEN → ACTIVE: when investigation cleared",
387
+ "ACTIVE → CLOSED: when user requests closure"
388
+ ]
389
+ thread_safety: "Thread-safe with account-level mutex"
390
+ \"\"\"
391
+
392
+ def __init__(self, account_id: str):
393
+ self.balance = 0.0
394
+ self.transactions = []
395
+ self.status = "PENDING"
396
+
397
+ def deposit(self, amount: float) -> bool:
398
+ \"\"\"@voodocs
399
+ preconditions: [
400
+ "amount > 0",
401
+ "self.status = ACTIVE"
402
+ ]
403
+ postconditions: [
404
+ "self.balance = old(self.balance) + amount",
405
+ "len(self.transactions) = old(len(self.transactions)) + 1"
406
+ ]
407
+ invariants: [
408
+ "self.balance >= 0"
409
+ ]
410
+ complexity: "O(1)"
411
+ \"\"\"
412
+ # Implementation
413
+ pass
414
+ ```
415
+
416
+ ### Example 4: Algorithm with Complexity
417
+
418
+ ```python
419
+ def quicksort(arr: list[int]) -> list[int]:
420
+ \"\"\"@voodocs
421
+ preconditions: [
422
+ "arr is list of integers"
423
+ ]
424
+ postconditions: [
425
+ "len(result) = len(arr)",
426
+ "∀ i, j: i < j ⇒ result[i] <= result[j]",
427
+ "result contains same elements as arr (permutation)"
428
+ ]
429
+ complexity: "O(n log n)"
430
+ invariants: [
431
+ "Partition maintains: ∀ x ∈ left: x <= pivot",
432
+ "∀ x ∈ right: x > pivot"
433
+ ]
434
+ \"\"\"
435
+ # Implementation
436
+ pass
437
+ ```"""
438
+
439
+ else: # TypeScript/JavaScript
440
+ return """## Examples
441
+
442
+ ### Example 1: API Route Handler
443
+
444
+ ```typescript
445
+ /**@voodocs
446
+ preconditions: [
447
+ "request.user is authenticated",
448
+ "request.body.amount > 0",
449
+ "request.body.recipientId exists in database"
450
+ ]
451
+ postconditions: [
452
+ "returns 200 ⇔ transfer successful",
453
+ "returns 400 ⇔ invalid input",
454
+ "returns 403 ⇔ insufficient funds",
455
+ "sender.balance decreased by amount",
456
+ "recipient.balance increased by amount"
457
+ ]
458
+ security_implications: [
459
+ "Requires authentication",
460
+ "Rate limited to 10 transfers/minute",
461
+ "Validates account ownership"
462
+ ]
463
+ side_effects: [
464
+ "Updates database (2 accounts)",
465
+ "Creates transaction record",
466
+ "Sends notification emails"
467
+ ]
468
+ complexity: "O(1)"
469
+ */
470
+ async function transferMoney(
471
+ request: Request,
472
+ response: Response
473
+ ): Promise<void> {
474
+ // Implementation
475
+ }
476
+ ```
477
+
478
+ ### Example 2: React Component
479
+
480
+ ```typescript
481
+ /**@voodocs
482
+ preconditions: [
483
+ "props.items is non-empty array",
484
+ "props.onSelect is function"
485
+ ]
486
+ postconditions: [
487
+ "renders list with props.items.length elements",
488
+ "clicking item calls props.onSelect with item"
489
+ ]
490
+ assumptions: [
491
+ "items have unique 'id' property",
492
+ "items have 'name' property for display"
493
+ ]
494
+ complexity: "O(n) where n = props.items.length"
495
+ */
496
+ function ItemList({ items, onSelect }: ItemListProps) {
497
+ // Implementation
498
+ }
499
+ ```"""
500
+
501
+ def _generate_workflow(self) -> str:
502
+ """Generate workflow integration section."""
503
+ return """## Workflow Integration
504
+
505
+ ### When to Add Annotations
506
+
507
+ Add `@voodocs` annotations in these scenarios:
508
+
509
+ 1. **New Functions** - Annotate immediately after writing the function signature
510
+ 2. **New Classes** - Annotate class and all public methods
511
+ 3. **API Endpoints** - Always annotate with security and side effects
512
+ 4. **Complex Logic** - Annotate algorithms with complexity and invariants
513
+ 5. **Security-Critical Code** - Always annotate with security implications
514
+
515
+ ### Annotation Workflow
516
+
517
+ ```
518
+ 1. Write function signature
519
+
520
+ 2. Add @voodocs annotation with preconditions/postconditions
521
+
522
+ 3. Implement function body
523
+
524
+ 4. Verify implementation matches postconditions
525
+
526
+ 5. Run `voodocs generate` to create tests and docs
527
+ ```
528
+
529
+ ### Generated Outputs
530
+
531
+ When you annotate code with `@voodocs`, the following are automatically generated:
532
+
533
+ 1. **Property-Based Tests** - Hypothesis tests with inferred strategies
534
+ 2. **Documentation** - Human-readable Markdown docs
535
+ 3. **API Specs** - OpenAPI 3.0 or GraphQL schemas
536
+ 4. **Type Hints** - Enhanced type information
537
+
538
+ ### Example Generation
539
+
540
+ Given this annotation:
541
+
542
+ ```python
543
+ \"\"\"@voodocs
544
+ preconditions: ["x > 0", "y > 0"]
545
+ postconditions: ["result > x", "result > y"]
546
+ complexity: "O(1)"
547
+ \"\"\"
548
+ ```
549
+
550
+ VooDocs generates:
551
+
552
+ ```python
553
+ # Generated test
554
+ @given(x=st.integers(min_value=1), y=st.integers(min_value=1))
555
+ def test_property_based_add(x, y):
556
+ assume(x > 0)
557
+ assume(y > 0)
558
+ result = add(x, y)
559
+ assert result > x
560
+ assert result > y
561
+ ```"""
562
+
563
+ def _generate_best_practices(self) -> str:
564
+ """Generate best practices section."""
565
+ return """## Best Practices
566
+
567
+ ### 1. Be Specific with Preconditions
568
+
569
+ **Good:**
570
+ ```python
571
+ preconditions: [
572
+ "amount > 0",
573
+ "amount <= account.balance",
574
+ "account.status = ACTIVE"
575
+ ]
576
+ ```
577
+
578
+ **Avoid:**
579
+ ```python
580
+ preconditions: ["valid input"] # Too vague
581
+ ```
582
+
583
+ ### 2. Use Mathematical Notation for Precision
584
+
585
+ **Good:**
586
+ ```python
587
+ postconditions: [
588
+ "∀ x ∈ result: x ∈ input", # All results are from input
589
+ "len(result) ≤ len(input)" # Result is subset
590
+ ]
591
+ ```
592
+
593
+ **Avoid:**
594
+ ```python
595
+ postconditions: ["returns filtered list"] # Imprecise
596
+ ```
597
+
598
+ ### 3. Always Specify Complexity
599
+
600
+ **Good:**
601
+ ```python
602
+ complexity: "O(n log n)"
603
+ ```
604
+
605
+ **Also Good:**
606
+ ```python
607
+ complexity: "O(n)" # VooDocs infers space as O(1)
608
+ ```
609
+
610
+ ### 4. Document Security Implications
611
+
612
+ **Good:**
613
+ ```python
614
+ security_implications: [
615
+ "Requires admin role",
616
+ "Rate limited to 100 requests/hour",
617
+ "Validates CSRF token"
618
+ ]
619
+ ```
620
+
621
+ ### 5. Specify Error Cases
622
+
623
+ **Good:**
624
+ ```python
625
+ error_cases: [
626
+ "amount <= 0 → ValueError",
627
+ "insufficient funds → InsufficientFundsError",
628
+ "account frozen → AccountFrozenError"
629
+ ]
630
+ ```
631
+
632
+ ### 6. Use Invariants for Loops and Recursion
633
+
634
+ **Good:**
635
+ ```python
636
+ invariants: [
637
+ "∀ iteration: 0 <= i < len(arr)",
638
+ "sorted(arr[0:i])" # First i elements are sorted
639
+ ]
640
+ ```
641
+
642
+ ### 7. Document Side Effects
643
+
644
+ **Good:**
645
+ ```python
646
+ side_effects: [
647
+ "Writes to database",
648
+ "Sends email notification",
649
+ "Updates cache"
650
+ ]
651
+ ```
652
+
653
+ **Avoid:**
654
+ ```python
655
+ side_effects: ["Does stuff"] # Too vague
656
+ ```"""
657
+
658
+ def _generate_footer(self) -> str:
659
+ """Generate footer section."""
660
+ return """---
661
+
662
+ ## Summary
663
+
664
+ **Remember**: Every time you write a function or class, ask yourself:
665
+
666
+ 1. What must be true before this runs? → **preconditions**
667
+ 2. What will be true after this runs? → **postconditions**
668
+ 3. How fast is this? → **complexity**
669
+ 4. What can go wrong? → **error_cases**
670
+ 5. Is this security-sensitive? → **security_implications**
671
+
672
+ 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.
673
+
674
+ **Generated by VooDocs** - AI-native documentation for modern development."""
675
+
676
+ def detect_assistant(self) -> Optional[str]:
677
+ """
678
+ Detect which AI assistant is being used based on environment or config files.
679
+
680
+ Returns:
681
+ Assistant name or None if not detected
682
+ """
683
+ # Check for config files in current directory
684
+ for assistant, info in self.ASSISTANTS.items():
685
+ config_path = Path(info["config_file"])
686
+ if config_path.exists():
687
+ return assistant
688
+
689
+ return None
690
+
691
+ @staticmethod
692
+ def list_assistants() -> List[Dict[str, str]]:
693
+ """
694
+ List all supported AI assistants.
695
+
696
+ Returns:
697
+ List of assistant info dictionaries
698
+ """
699
+ return [
700
+ {
701
+ "id": assistant_id,
702
+ "name": info["name"],
703
+ "config_file": info["config_file"]
704
+ }
705
+ for assistant_id, info in InstructionGenerator.ASSISTANTS.items()
706
+ ]