@voodocs/cli 2.4.0 → 2.5.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.
@@ -0,0 +1,343 @@
1
+ """
2
+ VooDocs Lite Parser
3
+
4
+ Parses VooDocs Lite format and converts between Lite and Standard formats.
5
+ """
6
+
7
+ import re
8
+ from typing import Dict, Optional
9
+ from .voodocs_lite_dict import (
10
+ expand_text,
11
+ compress_text,
12
+ get_lite_symbol,
13
+ get_standard_symbol,
14
+ LITE_TO_STANDARD,
15
+ STANDARD_TO_LITE,
16
+ )
17
+ from .voodocs_lite_dict_v2 import ultra_compress, ultra_expand
18
+
19
+
20
+ class VooDocsLiteParser:
21
+ """Parser for VooDocs Lite format."""
22
+
23
+ # Lite format patterns
24
+ LITE_PATTERNS = {
25
+ 'purpose': r'^>\s*(.+)$',
26
+ 'dependencies': r'^@\s*(.+)$',
27
+ 'assumptions': r'^!\s*(.+)$',
28
+ 'preconditions': r'^<\s*(.+)$',
29
+ 'postconditions': r'^>\s*(.+)$', # Same as purpose, context-dependent
30
+ 'invariants': r'^=\s*(.+)$',
31
+ 'complexity': r'^~\s*(.+)$',
32
+ 'security': r'^#\s*(.+)$',
33
+ }
34
+
35
+ # Standard format patterns
36
+ STANDARD_PATTERNS = {
37
+ 'purpose': r'⊢\{([^}]+)\}',
38
+ 'dependencies': r'∂\{([^}]+)\}',
39
+ 'assumptions': r'⚠\{([^}]+)\}',
40
+ 'preconditions': r'⊳\{([^}]+)\}',
41
+ 'postconditions': r'⊲\{([^}]+)\}',
42
+ 'invariants': r'⊨\{([^}]+)\}',
43
+ 'complexity': r'⚡\{([^}]+)\}',
44
+ 'security': r'🔒\{([^}]+)\}',
45
+ }
46
+
47
+ @classmethod
48
+ def parse_lite(cls, content: str) -> Dict[str, any]:
49
+ """
50
+ Parse VooDocs Lite format annotation.
51
+
52
+ Args:
53
+ content: Lite format annotation text
54
+
55
+ Returns:
56
+ Dictionary with parsed fields
57
+ """
58
+ result = {
59
+ 'purpose': None,
60
+ 'dependencies': [],
61
+ 'assumptions': [],
62
+ 'preconditions': [],
63
+ 'postconditions': [],
64
+ 'invariants': [],
65
+ 'complexity': None,
66
+ 'security': [],
67
+ }
68
+
69
+ lines = content.strip().split('\n')
70
+
71
+ for line in lines:
72
+ line = line.strip()
73
+ if not line:
74
+ continue
75
+
76
+ # Check each pattern
77
+ if line.startswith('>'):
78
+ # Could be purpose or postcondition
79
+ # If we already have purpose, it's postcondition
80
+ match = re.match(cls.LITE_PATTERNS['purpose'], line)
81
+ if match:
82
+ value = match.group(1).strip()
83
+ if result['purpose'] is None:
84
+ result['purpose'] = value
85
+ else:
86
+ result['postconditions'].append(value)
87
+
88
+ elif line.startswith('@'):
89
+ match = re.match(cls.LITE_PATTERNS['dependencies'], line)
90
+ if match:
91
+ deps = match.group(1).strip()
92
+ # Split by comma
93
+ result['dependencies'] = [d.strip() for d in deps.split(',')]
94
+
95
+ elif line.startswith('!'):
96
+ match = re.match(cls.LITE_PATTERNS['assumptions'], line)
97
+ if match:
98
+ result['assumptions'].append(match.group(1).strip())
99
+
100
+ elif line.startswith('<'):
101
+ match = re.match(cls.LITE_PATTERNS['preconditions'], line)
102
+ if match:
103
+ result['preconditions'].append(match.group(1).strip())
104
+
105
+ elif line.startswith('='):
106
+ match = re.match(cls.LITE_PATTERNS['invariants'], line)
107
+ if match:
108
+ result['invariants'].append(match.group(1).strip())
109
+
110
+ elif line.startswith('~'):
111
+ match = re.match(cls.LITE_PATTERNS['complexity'], line)
112
+ if match:
113
+ result['complexity'] = match.group(1).strip()
114
+
115
+ elif line.startswith('#'):
116
+ match = re.match(cls.LITE_PATTERNS['security'], line)
117
+ if match:
118
+ result['security'].append(match.group(1).strip())
119
+
120
+ return result
121
+
122
+ @classmethod
123
+ def parse_standard(cls, content: str) -> Dict[str, any]:
124
+ """
125
+ Parse standard VooDocs format annotation.
126
+
127
+ Args:
128
+ content: Standard format annotation text
129
+
130
+ Returns:
131
+ Dictionary with parsed fields
132
+ """
133
+ result = {
134
+ 'purpose': None,
135
+ 'dependencies': [],
136
+ 'assumptions': [],
137
+ 'preconditions': [],
138
+ 'postconditions': [],
139
+ 'invariants': [],
140
+ 'complexity': None,
141
+ 'security': [],
142
+ }
143
+
144
+ # Extract each field
145
+ for field, pattern in cls.STANDARD_PATTERNS.items():
146
+ matches = re.findall(pattern, content)
147
+
148
+ if field in ['purpose', 'complexity']:
149
+ # Single value fields
150
+ if matches:
151
+ result[field] = matches[0].strip()
152
+ elif field == 'dependencies':
153
+ # Comma-separated list
154
+ if matches:
155
+ deps = matches[0].strip()
156
+ result[field] = [d.strip() for d in deps.split(',')]
157
+ else:
158
+ # Multiple value fields
159
+ result[field] = [m.strip() for m in matches]
160
+
161
+ return result
162
+
163
+ @classmethod
164
+ def lite_to_standard(cls, lite_content: str, expand_abbreviations: bool = True) -> str:
165
+ """
166
+ Convert Lite format to Standard format.
167
+
168
+ Args:
169
+ lite_content: Lite format annotation
170
+ expand_abbreviations: Whether to expand abbreviations
171
+
172
+ Returns:
173
+ Standard format annotation
174
+ """
175
+ parsed = cls.parse_lite(lite_content)
176
+
177
+ lines = []
178
+
179
+ # Purpose
180
+ if parsed['purpose']:
181
+ text = parsed['purpose']
182
+ if expand_abbreviations:
183
+ text = expand_text(text)
184
+ lines.append(f"⊢{{{text}}}")
185
+
186
+ # Dependencies
187
+ if parsed['dependencies']:
188
+ deps = ', '.join(parsed['dependencies'])
189
+ if expand_abbreviations:
190
+ deps = expand_text(deps)
191
+ lines.append(f"∂{{{deps}}}")
192
+
193
+ # Assumptions
194
+ if parsed['assumptions']:
195
+ for assumption in parsed['assumptions']:
196
+ text = assumption
197
+ if expand_abbreviations:
198
+ text = expand_text(text)
199
+ lines.append(f"⚠{{{text}}}")
200
+
201
+ # Preconditions
202
+ if parsed['preconditions']:
203
+ for precond in parsed['preconditions']:
204
+ text = precond
205
+ if expand_abbreviations:
206
+ text = expand_text(text)
207
+ lines.append(f"⊳{{{text}}}")
208
+
209
+ # Postconditions
210
+ if parsed['postconditions']:
211
+ for postcond in parsed['postconditions']:
212
+ text = postcond
213
+ if expand_abbreviations:
214
+ text = expand_text(text)
215
+ lines.append(f"⊲{{{text}}}")
216
+
217
+ # Invariants
218
+ if parsed['invariants']:
219
+ for invariant in parsed['invariants']:
220
+ text = invariant
221
+ if expand_abbreviations:
222
+ text = expand_text(text)
223
+ lines.append(f"⊨{{{text}}}")
224
+
225
+ # Complexity
226
+ if parsed['complexity']:
227
+ text = parsed['complexity']
228
+ # Don't expand complexity (O(n) should stay as-is)
229
+ lines.append(f"⚡{{{text}}}")
230
+
231
+ # Security
232
+ if parsed['security']:
233
+ for security in parsed['security']:
234
+ text = security
235
+ if expand_abbreviations:
236
+ text = expand_text(text)
237
+ lines.append(f"🔒{{{text}}}")
238
+
239
+ return '\n'.join(lines)
240
+
241
+ @classmethod
242
+ def standard_to_lite(cls, standard_content: str, compress_abbreviations: bool = True) -> str:
243
+ """
244
+ Convert Standard format to Lite format.
245
+
246
+ Args:
247
+ standard_content: Standard format annotation
248
+ compress_abbreviations: Whether to compress to abbreviations
249
+
250
+ Returns:
251
+ Lite format annotation
252
+ """
253
+ parsed = cls.parse_standard(standard_content)
254
+
255
+ lines = []
256
+
257
+ # Purpose
258
+ if parsed['purpose']:
259
+ text = parsed['purpose']
260
+ if compress_abbreviations:
261
+ text = ultra_compress(text)
262
+ lines.append(f">{text}")
263
+
264
+ # Dependencies
265
+ if parsed['dependencies']:
266
+ deps = ','.join(parsed['dependencies'])
267
+ if compress_abbreviations:
268
+ deps = ultra_compress(deps)
269
+ lines.append(f"@{deps}")
270
+
271
+ # Assumptions
272
+ if parsed['assumptions']:
273
+ for assumption in parsed['assumptions']:
274
+ text = assumption
275
+ if compress_abbreviations:
276
+ text = ultra_compress(text)
277
+ lines.append(f"!{text}")
278
+
279
+ # Preconditions
280
+ if parsed['preconditions']:
281
+ for precond in parsed['preconditions']:
282
+ text = precond
283
+ if compress_abbreviations:
284
+ text = ultra_compress(text)
285
+ lines.append(f"<{text}")
286
+
287
+ # Postconditions
288
+ if parsed['postconditions']:
289
+ for postcond in parsed['postconditions']:
290
+ text = postcond
291
+ if compress_abbreviations:
292
+ text = ultra_compress(text)
293
+ lines.append(f">{text}")
294
+
295
+ # Invariants
296
+ if parsed['invariants']:
297
+ for invariant in parsed['invariants']:
298
+ text = invariant
299
+ if compress_abbreviations:
300
+ text = ultra_compress(text)
301
+ lines.append(f"={text}")
302
+
303
+ # Complexity
304
+ if parsed['complexity']:
305
+ text = parsed['complexity']
306
+ # Don't compress complexity
307
+ lines.append(f"~{text}")
308
+
309
+ # Security
310
+ if parsed['security']:
311
+ for security in parsed['security']:
312
+ text = security
313
+ if compress_abbreviations:
314
+ text = ultra_compress(text)
315
+ lines.append(f"#{text}")
316
+
317
+ return '\n'.join(lines)
318
+
319
+ @classmethod
320
+ def detect_format(cls, content: str) -> str:
321
+ """
322
+ Detect whether content is Lite or Standard format.
323
+
324
+ Returns:
325
+ 'lite', 'standard', or 'unknown'
326
+ """
327
+ # Check for Lite symbols at start of lines
328
+ lite_indicators = ['>', '@', '!', '<', '=', '~', '#']
329
+ has_lite = any(line.strip().startswith(sym) for sym in lite_indicators for line in content.split('\n'))
330
+
331
+ # Check for Standard symbols
332
+ standard_indicators = ['⊢', '∂', '⚠', '⊳', '⊲', '⊨', '⚡', '🔒']
333
+ has_standard = any(sym in content for sym in standard_indicators)
334
+
335
+ if has_lite and not has_standard:
336
+ return 'lite'
337
+ elif has_standard and not has_lite:
338
+ return 'standard'
339
+ elif has_lite and has_standard:
340
+ # Mixed format, prefer standard
341
+ return 'standard'
342
+ else:
343
+ return 'unknown'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voodocs/cli",
3
- "version": "2.4.0",
3
+ "version": "2.5.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": {
@@ -64,6 +64,10 @@
64
64
  "lib/darkarts/exceptions.py",
65
65
  "lib/darkarts/telemetry.py",
66
66
  "lib/darkarts/companion_files.py",
67
+ "lib/darkarts/voodocs_lite_dict.py",
68
+ "lib/darkarts/voodocs_lite_dict_v2.py",
69
+ "lib/darkarts/voodocs_lite_parser.py",
70
+ "lib/darkarts/priority_analyzer/",
67
71
  "lib/darkarts/parsers/typescript/dist/",
68
72
  "lib/darkarts/parsers/typescript/src/",
69
73
  "lib/darkarts/parsers/typescript/package.json",