@voodocs/cli 0.1.1 → 0.1.2

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 CHANGED
@@ -1,3 +1,24 @@
1
+ ## [0.1.2] - 2025-12-19
2
+
3
+ ### Fixed
4
+ - Fixed bug in documentation generator where `class_invariants` was incorrectly referenced as `invariants` on line 570
5
+ - Function-level invariants now render correctly in generated documentation
6
+
7
+ ### Added
8
+ - Comprehensive example file demonstrating function-level invariants (`examples/test_function_invariants.py`)
9
+ - Examples showing `transfer_funds()`, `binary_search()`, and `BankAccount` class with invariants
10
+ - Documentation in USAGE.md clarifying when to use `invariants` vs `class_invariants`
11
+ - Real-world examples of conservation laws and state constraints using invariants
12
+
13
+ ### Changed
14
+ - Updated USAGE.md annotation fields table to clarify `invariants` usage
15
+ - Added "Function with Invariants" and "Class with Invariants" examples to USAGE.md
16
+
17
+ ### Documentation
18
+ - Clarified that `invariants` can be used at function level for execution-time properties
19
+ - Clarified that `class_invariants` should be used for object state constraints
20
+ - Added examples showing both use cases
21
+
1
22
  ## [0.1.1] - 2025-12-19
2
23
 
3
24
  ### Fixed
package/USAGE.md CHANGED
@@ -247,7 +247,7 @@ function myFunction(x: number): number {
247
247
  | `assumptions` | Assumptions made by the module. |
248
248
  | `preconditions` | Conditions that must be true before a function is called. |
249
249
  | `postconditions` | Conditions that must be true after a function returns. |
250
- | `invariants` | Conditions that must always be true for a class. |
250
+ | `invariants` | Properties that remain unchanged throughout execution. For functions: conditions that hold during execution. For classes: use `class_invariants` for object state constraints. |
251
251
  | `complexity` | Time and space complexity of an algorithm. |
252
252
  | `error_cases` | How the function behaves in error scenarios. |
253
253
  | `security_model` | Security implications and threat model. |
@@ -268,7 +268,57 @@ The DarkArts language is a formal notation used in annotations. It includes:
268
268
 
269
269
  ## Examples
270
270
 
271
- See the `examples/` directory for complete examples in Python and TypeScript.
271
+ ### Function with Invariants
272
+
273
+ **Python**:
274
+ ```python
275
+ def transfer_funds(from_account, to_account, amount):
276
+ """@voodocs
277
+ preconditions: [
278
+ "from_account.balance >= amount",
279
+ "amount > 0",
280
+ "from_account != to_account"
281
+ ]
282
+ postconditions: [
283
+ "from_account.balance = from_account.balance₀ - amount",
284
+ "to_account.balance = to_account.balance₀ + amount"
285
+ ]
286
+ invariants: [
287
+ "total_balance = from_account.balance + to_account.balance (conservation)",
288
+ "from_account.balance >= 0",
289
+ "to_account.balance >= 0"
290
+ ]
291
+ complexity: "O(1)"
292
+ """
293
+ from_account.balance -= amount
294
+ to_account.balance += amount
295
+ ```
296
+
297
+ ### Class with Invariants
298
+
299
+ **Python**:
300
+ ```python
301
+ class BankAccount:
302
+ """@voodocs
303
+ class_invariants: [
304
+ "balance >= 0 (no overdrafts)",
305
+ "account_id is unique and immutable"
306
+ ]
307
+ """
308
+
309
+ def deposit(self, amount):
310
+ """@voodocs
311
+ preconditions: ["amount > 0"]
312
+ postconditions: ["self.balance = self.balance₀ + amount"]
313
+ invariants: [
314
+ "self.balance >= 0 (class invariant maintained)",
315
+ "self.account_id unchanged"
316
+ ]
317
+ """
318
+ self.balance += amount
319
+ ```
320
+
321
+ See the `examples/` directory for more complete examples in Python and TypeScript.
272
322
 
273
323
  ---
274
324
 
package/cli.py CHANGED
@@ -137,7 +137,7 @@ Documentation: https://github.com/3vilEnterprises/vooodooo-magic/tree/main/packa
137
137
  parser.add_argument(
138
138
  "--version",
139
139
  action="version",
140
- version="VooDocs 0.1.1"
140
+ version="VooDocs 0.1.2"
141
141
  )
142
142
 
143
143
  subparsers = parser.add_subparsers(dest="command", help="Available commands")
@@ -435,7 +435,7 @@ def cmd_init(args):
435
435
  config = {
436
436
  "project_name": project_name,
437
437
  "language": language,
438
- "version": "0.1.1",
438
+ "version": "0.1.2",
439
439
  "output_dir": "./voodocs-output",
440
440
  "test_framework": "pytest",
441
441
  "api_format": "openapi",
@@ -0,0 +1,134 @@
1
+ """
2
+ Example demonstrating function-level invariants in VooDocs.
3
+
4
+ This file shows how to use invariants at the function level to document
5
+ properties that must hold throughout the function's execution.
6
+ """
7
+
8
+
9
+ def transfer_funds(from_account, to_account, amount):
10
+ """@voodocs
11
+ preconditions: [
12
+ "from_account.balance >= amount",
13
+ "amount > 0",
14
+ "from_account != to_account"
15
+ ]
16
+ postconditions: [
17
+ "from_account.balance = from_account.balance₀ - amount",
18
+ "to_account.balance = to_account.balance₀ + amount",
19
+ "total_balance = from_account.balance + to_account.balance = total_balance₀"
20
+ ]
21
+ invariants: [
22
+ "total_balance = from_account.balance + to_account.balance (conservation of funds)",
23
+ "from_account.balance >= 0 (no negative balances)",
24
+ "to_account.balance >= 0 (no negative balances)",
25
+ "amount remains constant throughout execution"
26
+ ]
27
+ side_effects: [
28
+ "Modifies from_account.balance",
29
+ "Modifies to_account.balance",
30
+ "Logs transaction to audit trail"
31
+ ]
32
+ complexity: "O(1)"
33
+ """
34
+ # Verify preconditions
35
+ if from_account.balance < amount:
36
+ raise ValueError("Insufficient funds")
37
+ if amount <= 0:
38
+ raise ValueError("Amount must be positive")
39
+ if from_account == to_account:
40
+ raise ValueError("Cannot transfer to same account")
41
+
42
+ # Perform transfer (invariants hold throughout)
43
+ from_account.balance -= amount
44
+ to_account.balance += amount
45
+
46
+ # Log transaction
47
+ print(f"Transferred {amount} from {from_account.id} to {to_account.id}")
48
+
49
+
50
+ def binary_search(arr, target):
51
+ """@voodocs
52
+ preconditions: [
53
+ "arr is sorted in ascending order",
54
+ "∀ i, j: 0 ≤ i < j < len(arr) ⇒ arr[i] ≤ arr[j]"
55
+ ]
56
+ postconditions: [
57
+ "result ≥ 0 ⇒ arr[result] = target",
58
+ "result = -1 ⇒ target ∉ arr"
59
+ ]
60
+ invariants: [
61
+ "0 ≤ left ≤ right < len(arr) (search bounds)",
62
+ "target ∈ arr ⇒ target ∈ arr[left:right+1] (target in search range)",
63
+ "arr remains unchanged (no side effects on input)"
64
+ ]
65
+ complexity: "O(log n) where n = len(arr)"
66
+ """
67
+ left, right = 0, len(arr) - 1
68
+
69
+ while left <= right:
70
+ mid = (left + right) // 2
71
+
72
+ if arr[mid] == target:
73
+ return mid
74
+ elif arr[mid] < target:
75
+ left = mid + 1
76
+ else:
77
+ right = mid - 1
78
+
79
+ return -1
80
+
81
+
82
+ class BankAccount:
83
+ """@voodocs
84
+ class_invariants: [
85
+ "balance >= 0 (no overdrafts)",
86
+ "account_id is unique and immutable",
87
+ "len(transaction_history) >= 0"
88
+ ]
89
+ """
90
+
91
+ def __init__(self, account_id, initial_balance=0):
92
+ """@voodocs
93
+ preconditions: [
94
+ "initial_balance >= 0",
95
+ "account_id is not None"
96
+ ]
97
+ postconditions: [
98
+ "self.balance = initial_balance",
99
+ "self.account_id = account_id",
100
+ "len(self.transaction_history) = 0"
101
+ ]
102
+ invariants: [
103
+ "self.balance >= 0 (established at initialization)"
104
+ ]
105
+ """
106
+ self.account_id = account_id
107
+ self.balance = initial_balance
108
+ self.transaction_history = []
109
+
110
+ def deposit(self, amount):
111
+ """@voodocs
112
+ preconditions: [
113
+ "amount > 0"
114
+ ]
115
+ postconditions: [
116
+ "self.balance = self.balance₀ + amount",
117
+ "len(self.transaction_history) = len(self.transaction_history₀) + 1"
118
+ ]
119
+ invariants: [
120
+ "self.balance >= 0 (class invariant maintained)",
121
+ "amount remains constant",
122
+ "self.account_id unchanged"
123
+ ]
124
+ side_effects: [
125
+ "Modifies self.balance",
126
+ "Appends to self.transaction_history"
127
+ ]
128
+ complexity: "O(1)"
129
+ """
130
+ if amount <= 0:
131
+ raise ValueError("Deposit amount must be positive")
132
+
133
+ self.balance += amount
134
+ self.transaction_history.append(("deposit", amount))
@@ -567,7 +567,7 @@ class DocumentationGenerator:
567
567
 
568
568
  # Documentation coverage badge
569
569
  total_items = len(parsed.module.classes) + len(parsed.get_all_functions())
570
- annotated_items = sum(1 for _ in parsed.module.classes if _.invariants or _.state_transitions)
570
+ annotated_items = sum(1 for _ in parsed.module.classes if _.class_invariants or _.state_transitions)
571
571
  annotated_items += sum(1 for f in parsed.get_all_functions() if f.preconditions or f.postconditions)
572
572
 
573
573
  if total_items > 0:
@@ -20,7 +20,7 @@ SUPABASE_URL = os.getenv("VOODOCS_SUPABASE_URL", "https://sjatkayudkbkmipubhfy.s
20
20
  SUPABASE_ANON_KEY = os.getenv("VOODOCS_SUPABASE_ANON_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InNqYXRrYXl1ZGtia21pcHViaGZ5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjYxNjE0MTMsImV4cCI6MjA4MTczNzQxM30.Wj3dbokjKPsmWTgbPw77aPnCoZCsE5hrFfIH-R_ErzI")
21
21
 
22
22
  # VooDocs version
23
- VERSION = "0.1.1"
23
+ VERSION = "0.1.2"
24
24
 
25
25
  class TelemetryClient:
26
26
  """Anonymous telemetry client for VooDocs CLI."""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voodocs/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "AI-Native Documentation System - Generate docs, tests, and API specs from @voodocs annotations using the DarkArts language",
5
5
  "main": "cli.py",
6
6
  "bin": {