@voodocs/cli 1.0.2 → 1.0.5
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 +220 -0
- package/lib/cli/__init__.py +3 -1
- package/lib/cli/generate.py +55 -9
- package/lib/cli/instruct.py +129 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,223 @@
|
|
|
1
|
+
## v1.0.5 (2024-12-21)
|
|
2
|
+
|
|
3
|
+
### 🐛 Bug Fix: Instruct Command Import Error
|
|
4
|
+
|
|
5
|
+
**Problem:** The `voodocs instruct` command failed with `ModuleNotFoundError: No module named 'darkarts.instruction_generator'` when trying to generate AI instructions.
|
|
6
|
+
|
|
7
|
+
**Root Cause:** The instruct command was trying to import complex modules (`InstructionGenerator`, `AIEnvironment`) that had dependencies issues in the npm package.
|
|
8
|
+
|
|
9
|
+
**Fix:** Simplified the instruct command to directly read template files without complex module dependencies.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
### Changes
|
|
14
|
+
|
|
15
|
+
- Rewrote `lib/cli/instruct.py` to be self-contained
|
|
16
|
+
- Removed dependency on `darkarts.instruction_generator` and `darkarts.ai_detector`
|
|
17
|
+
- Simplified AI environment detection
|
|
18
|
+
- All functionality preserved
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### Testing
|
|
23
|
+
|
|
24
|
+
| Test Case | Status |
|
|
25
|
+
|-----------|--------|
|
|
26
|
+
| `voodocs instruct --list-templates` | ✅ Pass |
|
|
27
|
+
| `voodocs instruct --ai cursor` | ✅ Pass |
|
|
28
|
+
| `voodocs instruct --ai claude` | ✅ Pass |
|
|
29
|
+
| `voodocs instruct --output .cursorrules` | ✅ Pass |
|
|
30
|
+
| AI auto-detection | ✅ Pass |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
### Upgrade
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g @voodocs/cli@1.0.5
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## v1.0.4 (2024-12-21)
|
|
41
|
+
|
|
42
|
+
### 🐛 Critical Bug Fixes: Documentation Generation
|
|
43
|
+
|
|
44
|
+
This release fixes critical bugs that prevented documentation generation for TypeScript, JavaScript, and Solidity files.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
#### Issue 1: Annotation Parsing Failure
|
|
51
|
+
**Problem:** The generator failed to recognize valid `@voodocs` or `@darkarts` annotations in TypeScript/JavaScript files.
|
|
52
|
+
|
|
53
|
+
**Root Cause:** The `_extract_annotation` function only looked for Python docstring format (`"""@darkarts`), not TypeScript/JavaScript block comments (`/**@voodocs` or `/**@darkarts`).
|
|
54
|
+
|
|
55
|
+
**Fix:**
|
|
56
|
+
- Added regex pattern matching for TypeScript/JavaScript block comments
|
|
57
|
+
- Support both `/**@voodocs` and `/**@darkarts` tags
|
|
58
|
+
- Support both Python (`"""`) and JS/TS (`/**`) comment styles
|
|
59
|
+
|
|
60
|
+
#### Issue 2: File Discovery Limitations
|
|
61
|
+
**Problem:** When running `voodocs generate . ./docs` in a directory, the tool reported "No Python files found to process" even when TypeScript or Solidity files were present.
|
|
62
|
+
|
|
63
|
+
**Root Cause:** The file discovery logic only looked for `.py` files.
|
|
64
|
+
|
|
65
|
+
**Fix:**
|
|
66
|
+
- Extended file discovery to include: `.py`, `.ts`, `.js`, `.jsx`, `.tsx`, `.sol`
|
|
67
|
+
- Updated error message to list all supported extensions
|
|
68
|
+
|
|
69
|
+
#### Issue 3: Natural Language Format Parsing
|
|
70
|
+
**Problem:** YAML-style annotations (e.g., `module_purpose: "..."`, `dependencies: []`) were not being parsed correctly.
|
|
71
|
+
|
|
72
|
+
**Fix:**
|
|
73
|
+
- Added support for natural language format alongside symbolic format
|
|
74
|
+
- Properly handle YAML-style lists with `-` markers
|
|
75
|
+
- Clean up formatting and remove trailing comment markers
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### Improvements
|
|
80
|
+
|
|
81
|
+
- **Multi-language Support:** Now works with TypeScript, JavaScript, Solidity, and Python
|
|
82
|
+
- **Dual Format Support:** Accepts both natural language (`module_purpose:`) and symbolic (`⊢{}`) formats
|
|
83
|
+
- **Better Error Messages:** Clear indication of supported file extensions
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Testing
|
|
88
|
+
|
|
89
|
+
All reported issues have been tested and verified:
|
|
90
|
+
|
|
91
|
+
| Test Case | Status |
|
|
92
|
+
|-----------|--------|
|
|
93
|
+
| TypeScript file with `/**@voodocs` | ✅ Pass |
|
|
94
|
+
| TypeScript file with `/**@darkarts` | ✅ Pass |
|
|
95
|
+
| Natural language format | ✅ Pass |
|
|
96
|
+
| Symbolic format | ✅ Pass |
|
|
97
|
+
| Directory discovery (`.ts` files) | ✅ Pass |
|
|
98
|
+
| Multiple files in directory | ✅ Pass |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### Example: Now Working
|
|
103
|
+
|
|
104
|
+
**File: test.ts**
|
|
105
|
+
```typescript
|
|
106
|
+
/**@voodocs
|
|
107
|
+
module_purpose: Test module
|
|
108
|
+
dependencies: []
|
|
109
|
+
assumptions:
|
|
110
|
+
- Node.js environment
|
|
111
|
+
*/
|
|
112
|
+
export function hello(name: string): string {
|
|
113
|
+
return `Hello, ${name}`;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Command:**
|
|
118
|
+
```bash
|
|
119
|
+
voodocs generate ./test.ts ./docs
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Result:**
|
|
123
|
+
```markdown
|
|
124
|
+
# test.ts
|
|
125
|
+
|
|
126
|
+
**Module:** `Test module`
|
|
127
|
+
|
|
128
|
+
## Assumptions
|
|
129
|
+
|
|
130
|
+
Node.js environment
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### Upgrade Notes
|
|
136
|
+
|
|
137
|
+
No breaking changes. Simply upgrade:
|
|
138
|
+
```bash
|
|
139
|
+
npm install -g @voodocs/cli@1.0.4
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
All existing annotations continue to work. This release only adds support for previously unsupported file types and formats.
|
|
143
|
+
|
|
144
|
+
## v1.0.3 (2024-12-21)
|
|
145
|
+
|
|
146
|
+
### ✨ New Feature: AI Instruction Generation
|
|
147
|
+
|
|
148
|
+
This release adds the `voodocs instruct` command to automatically generate AI-specific instructions for writing symbolic DarkArts annotations.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Added
|
|
153
|
+
|
|
154
|
+
#### `voodocs instruct` Command
|
|
155
|
+
- **Auto-detects AI environment** (Cursor, Claude, Gemini, etc.)
|
|
156
|
+
- **Generates tailored instructions** for each AI assistant
|
|
157
|
+
- **Supports multiple output formats** (console or file)
|
|
158
|
+
- **Lists available templates** with `--list-templates` flag
|
|
159
|
+
|
|
160
|
+
**Usage:**
|
|
161
|
+
```bash
|
|
162
|
+
voodocs instruct # Auto-detect and print instructions
|
|
163
|
+
voodocs instruct --ai cursor # Generate for specific AI
|
|
164
|
+
voodocs instruct --output .cursorrules # Save to file
|
|
165
|
+
voodocs instruct --list-templates # List available templates
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Updated Instruction Templates
|
|
169
|
+
- **Symbolic DarkArts format** - All templates updated to use symbolic annotations
|
|
170
|
+
- **Cursor template** - Tailored for Cursor AI
|
|
171
|
+
- **Claude template** - Tailored for Claude AI
|
|
172
|
+
- **Default template** - Generic instructions for any AI
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
### Improved
|
|
177
|
+
|
|
178
|
+
- **AI Instructions** - Now guide AIs to write symbolic `@darkarts` annotations instead of natural language `@voodocs`
|
|
179
|
+
- **Documentation** - Added comprehensive AI instruction guide
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### What This Means
|
|
184
|
+
|
|
185
|
+
With `voodocs instruct`, you can now:
|
|
186
|
+
1. Run the command in your project
|
|
187
|
+
2. Get AI-specific instructions
|
|
188
|
+
3. Add them to your `.cursorrules` or Claude project settings
|
|
189
|
+
4. Have your AI assistant automatically write correct symbolic annotations
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### Example Workflow
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Initialize project
|
|
197
|
+
voodocs init
|
|
198
|
+
|
|
199
|
+
# Generate AI instructions
|
|
200
|
+
voodocs instruct --output .cursorrules
|
|
201
|
+
|
|
202
|
+
# Now your AI will automatically write symbolic annotations!
|
|
203
|
+
# When you write code, your AI adds:
|
|
204
|
+
/**@darkarts
|
|
205
|
+
⊳{userId must be a valid UUID}
|
|
206
|
+
⊲{Returns user object or null}
|
|
207
|
+
⊨{Does ¬ modify database}
|
|
208
|
+
⚡{O(1)}
|
|
209
|
+
*/
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### Upgrade Notes
|
|
215
|
+
|
|
216
|
+
No breaking changes. Simply upgrade:
|
|
217
|
+
```bash
|
|
218
|
+
npm install -g @voodocs/cli@1.0.3
|
|
219
|
+
```
|
|
220
|
+
|
|
1
221
|
## v1.0.2 (2024-12-21)
|
|
2
222
|
|
|
3
223
|
### 🔧 Critical Bug Fixes
|
package/lib/cli/__init__.py
CHANGED
|
@@ -16,7 +16,7 @@ This module provides the command-line interface for VooDocs.
|
|
|
16
16
|
import click
|
|
17
17
|
from typing import Optional
|
|
18
18
|
|
|
19
|
-
__version__ = "1.0.
|
|
19
|
+
__version__ = "1.0.5"
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@click.group()
|
|
@@ -35,6 +35,7 @@ def cli(ctx):
|
|
|
35
35
|
|
|
36
36
|
# Import subcommands
|
|
37
37
|
from .init import init
|
|
38
|
+
from .instruct import instruct
|
|
38
39
|
from .validate import validate
|
|
39
40
|
from .generate import generate
|
|
40
41
|
from .benchmark import benchmark
|
|
@@ -42,6 +43,7 @@ from .fix import fix
|
|
|
42
43
|
|
|
43
44
|
# Register commands
|
|
44
45
|
cli.add_command(init)
|
|
46
|
+
cli.add_command(instruct)
|
|
45
47
|
cli.add_command(validate)
|
|
46
48
|
cli.add_command(generate)
|
|
47
49
|
cli.add_command(benchmark)
|
package/lib/cli/generate.py
CHANGED
|
@@ -78,11 +78,19 @@ def generate(
|
|
|
78
78
|
if source_path.is_file():
|
|
79
79
|
files_to_process = [source_path]
|
|
80
80
|
elif source_path.is_dir():
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
# Support multiple file extensions
|
|
82
|
+
extensions = ['*.py', '*.ts', '*.js', '*.jsx', '*.tsx', '*.sol']
|
|
83
|
+
files_to_process = []
|
|
84
|
+
|
|
85
|
+
if recursive:
|
|
86
|
+
for ext in extensions:
|
|
87
|
+
files_to_process.extend([f for f in source_path.glob(f"**/{ext}") if f.is_file()])
|
|
88
|
+
else:
|
|
89
|
+
for ext in extensions:
|
|
90
|
+
files_to_process.extend([f for f in source_path.glob(ext) if f.is_file()])
|
|
83
91
|
|
|
84
92
|
if not files_to_process:
|
|
85
|
-
click.secho("No
|
|
93
|
+
click.secho("No files found to process. Supported extensions: .py, .ts, .js, .jsx, .tsx, .sol", fg='yellow')
|
|
86
94
|
sys.exit(1)
|
|
87
95
|
|
|
88
96
|
click.echo(f"Found {len(files_to_process)} files to process")
|
|
@@ -214,20 +222,58 @@ def _generate_doc_for_file(file_path: Path, format: str, include_private: bool)
|
|
|
214
222
|
|
|
215
223
|
|
|
216
224
|
def _extract_annotation(content: str) -> str:
|
|
217
|
-
"""Extract @darkarts annotation from file content."""
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
"""Extract @darkarts or @voodocs annotation from file content."""
|
|
226
|
+
import re
|
|
227
|
+
|
|
228
|
+
# Try Python docstring format first ("""@darkarts or """@voodocs)
|
|
229
|
+
python_pattern = r'"""@(?:darkarts|voodocs)\s*(.*?)"""'
|
|
230
|
+
match = re.search(python_pattern, content, re.DOTALL)
|
|
231
|
+
if match:
|
|
232
|
+
return match.group(0)
|
|
233
|
+
|
|
234
|
+
# Try TypeScript/JavaScript block comment format (/**@darkarts or /**@voodocs)
|
|
235
|
+
js_pattern = r'/\*\*@(?:darkarts|voodocs)\s*(.*?)\*/'
|
|
236
|
+
match = re.search(js_pattern, content, re.DOTALL)
|
|
237
|
+
if match:
|
|
238
|
+
return match.group(0)
|
|
239
|
+
|
|
222
240
|
return ""
|
|
223
241
|
|
|
224
242
|
|
|
225
243
|
def _extract_section(annotation: str, symbol: str) -> str:
|
|
226
|
-
"""Extract a specific section from annotation."""
|
|
244
|
+
"""Extract a specific section from annotation (supports both symbolic and natural language)."""
|
|
245
|
+
import re
|
|
246
|
+
|
|
247
|
+
# Map symbols to natural language keys
|
|
248
|
+
symbol_to_key = {
|
|
249
|
+
'⊢': 'module_purpose',
|
|
250
|
+
'∂': 'dependencies',
|
|
251
|
+
'⚠': 'assumptions',
|
|
252
|
+
'⊨': 'invariants',
|
|
253
|
+
'🔒': 'security',
|
|
254
|
+
'⚡': 'complexity'
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
# Try symbolic format first
|
|
227
258
|
lines = annotation.split('\n')
|
|
228
259
|
for line in lines:
|
|
229
260
|
if line.strip().startswith(symbol):
|
|
230
261
|
return line.strip()[len(symbol):].strip('{}')
|
|
262
|
+
|
|
263
|
+
# Try natural language format
|
|
264
|
+
key = symbol_to_key.get(symbol)
|
|
265
|
+
if key:
|
|
266
|
+
# Match key: value or key: [list]
|
|
267
|
+
pattern = rf'{key}\s*:\s*(.+?)(?=\n[a-z_]+\s*:|\*/|$)'
|
|
268
|
+
match = re.search(pattern, annotation, re.DOTALL | re.IGNORECASE)
|
|
269
|
+
if match:
|
|
270
|
+
value = match.group(1).strip()
|
|
271
|
+
# Clean up list formatting and remove trailing comment markers
|
|
272
|
+
value = value.strip('[]').strip()
|
|
273
|
+
# Remove YAML list markers and join lines
|
|
274
|
+
lines = [line.strip().lstrip('-').strip() for line in value.split('\n') if line.strip()]
|
|
275
|
+
return ', '.join(lines)
|
|
276
|
+
|
|
231
277
|
return ""
|
|
232
278
|
|
|
233
279
|
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""@darkarts
|
|
2
|
+
⊢{cli:instruct}
|
|
3
|
+
∂{click,pathlib,os}
|
|
4
|
+
⚠{write-access:cwd}
|
|
5
|
+
⊨{idempotent:instruction-generation}
|
|
6
|
+
🔒{read-write:filesystem}
|
|
7
|
+
⚡{O(1):file-creation}
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
VooDocs Instruct Command
|
|
12
|
+
|
|
13
|
+
Generate AI-specific instructions for writing @darkarts annotations.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import click
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
import os
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.command()
|
|
22
|
+
@click.option(
|
|
23
|
+
'--ai',
|
|
24
|
+
type=click.Choice(['cursor', 'claude', 'default'], case_sensitive=False),
|
|
25
|
+
help='Target AI assistant (auto-detects if not specified)'
|
|
26
|
+
)
|
|
27
|
+
@click.option(
|
|
28
|
+
'--output',
|
|
29
|
+
'-o',
|
|
30
|
+
type=click.Path(),
|
|
31
|
+
help='Output file path (prints to console if not specified)'
|
|
32
|
+
)
|
|
33
|
+
@click.option(
|
|
34
|
+
'--list-templates',
|
|
35
|
+
is_flag=True,
|
|
36
|
+
help='List available instruction templates'
|
|
37
|
+
)
|
|
38
|
+
def instruct(ai, output, list_templates):
|
|
39
|
+
"""
|
|
40
|
+
Generate AI-specific instructions for writing @darkarts annotations.
|
|
41
|
+
|
|
42
|
+
This command generates tailored instructions for AI assistants to help them
|
|
43
|
+
write correct symbolic DarkArts annotations in your codebase.
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
|
|
47
|
+
# Auto-detect AI and print instructions
|
|
48
|
+
voodocs instruct
|
|
49
|
+
|
|
50
|
+
# Generate for Cursor and save to .cursorrules
|
|
51
|
+
voodocs instruct --ai cursor --output .cursorrules
|
|
52
|
+
|
|
53
|
+
# Generate for Claude
|
|
54
|
+
voodocs instruct --ai claude
|
|
55
|
+
|
|
56
|
+
# List available templates
|
|
57
|
+
voodocs instruct --list-templates
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
# Get the instructions directory
|
|
61
|
+
cli_dir = Path(__file__).parent
|
|
62
|
+
instructions_dir = cli_dir.parent / 'darkarts' / 'instructions'
|
|
63
|
+
|
|
64
|
+
if not instructions_dir.exists():
|
|
65
|
+
click.secho("Error: Instructions directory not found", fg='red')
|
|
66
|
+
click.echo(f"Expected at: {instructions_dir}")
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
# List templates if requested
|
|
70
|
+
if list_templates:
|
|
71
|
+
click.echo("Available instruction templates:")
|
|
72
|
+
click.echo()
|
|
73
|
+
templates = list(instructions_dir.glob('*.md'))
|
|
74
|
+
for template in templates:
|
|
75
|
+
click.echo(f" • {template.stem}")
|
|
76
|
+
click.echo()
|
|
77
|
+
click.echo(f"Total: {len(templates)} templates")
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
# Auto-detect AI if not specified
|
|
81
|
+
if not ai:
|
|
82
|
+
ai = _detect_ai_environment()
|
|
83
|
+
if ai:
|
|
84
|
+
click.echo(f"Detected AI environment: {ai}")
|
|
85
|
+
else:
|
|
86
|
+
ai = 'default'
|
|
87
|
+
click.echo("Using default instructions (AI environment not detected)")
|
|
88
|
+
click.echo()
|
|
89
|
+
|
|
90
|
+
# Load the appropriate template
|
|
91
|
+
template_file = instructions_dir / f"{ai}.md"
|
|
92
|
+
|
|
93
|
+
if not template_file.exists():
|
|
94
|
+
click.secho(f"Warning: Template '{ai}.md' not found, using default", fg='yellow')
|
|
95
|
+
template_file = instructions_dir / "default.md"
|
|
96
|
+
|
|
97
|
+
if not template_file.exists():
|
|
98
|
+
click.secho("Error: No instruction templates found", fg='red')
|
|
99
|
+
return
|
|
100
|
+
|
|
101
|
+
# Read the template
|
|
102
|
+
instructions = template_file.read_text(encoding='utf-8')
|
|
103
|
+
|
|
104
|
+
# Output the instructions
|
|
105
|
+
if output:
|
|
106
|
+
output_path = Path(output)
|
|
107
|
+
output_path.write_text(instructions, encoding='utf-8')
|
|
108
|
+
click.secho(f"✅ Instructions written to: {output_path}", fg='green')
|
|
109
|
+
click.echo()
|
|
110
|
+
click.echo("Your AI assistant will now write symbolic DarkArts annotations!")
|
|
111
|
+
else:
|
|
112
|
+
click.echo(instructions)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _detect_ai_environment():
|
|
116
|
+
"""Detect which AI environment is being used."""
|
|
117
|
+
# Check for Cursor
|
|
118
|
+
if os.environ.get('CURSOR_USER') or os.path.exists('.cursorrules'):
|
|
119
|
+
return 'cursor'
|
|
120
|
+
|
|
121
|
+
# Check for Claude
|
|
122
|
+
if os.environ.get('CLAUDE_API_KEY') or os.path.exists('.claude'):
|
|
123
|
+
return 'claude'
|
|
124
|
+
|
|
125
|
+
# Check for other AI indicators
|
|
126
|
+
if os.environ.get('OPENAI_API_KEY'):
|
|
127
|
+
return 'default'
|
|
128
|
+
|
|
129
|
+
return None
|
package/package.json
CHANGED