@voodocs/cli 2.0.0 → 2.1.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 +75 -0
- package/lib/cli/__init__.py +3 -1
- package/lib/cli/context.py +99 -0
- package/lib/cli/generate.py +60 -11
- package/lib/cli/init.py +76 -3
- package/lib/darkarts/annotations/parser.py +11 -15
- package/lib/darkarts/annotations/translator.py +2 -2
- package/lib/darkarts/annotations/types.py +1 -1
- package/lib/darkarts/context/commands.py +17 -7
- package/lib/darkarts/instructions/claude.md +24 -15
- package/lib/darkarts/instructions/cursor.md +24 -15
- package/lib/darkarts/instructions/default.md +24 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
|
+
## [2.1.1] - 2025-12-21
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
- npm publish issue (version bump to resolve registry conflict)
|
|
5
|
+
|
|
6
|
+
## [2.1.0] - 2025-12-21
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- **Context System Integration**: Full AI context generation from @darkarts annotations
|
|
10
|
+
- New `voodocs context` command group (init, generate, view, status, validate)
|
|
11
|
+
- Automatic context generation during `voodocs generate`
|
|
12
|
+
- Auto-creates minimal context file if it doesn't exist
|
|
13
|
+
- Extracts modules, assumptions, and invariants from code
|
|
14
|
+
- **Auto-Update Options**: Choose how context is updated
|
|
15
|
+
- Manual mode (default): Run `voodocs generate` to update
|
|
16
|
+
- Git hooks mode: Auto-update context on commit
|
|
17
|
+
- **Config-Based Defaults**: No more specifying paths every time
|
|
18
|
+
- `voodocs generate` uses paths from `.voodocs.json`
|
|
19
|
+
- Default output directory: `./voodocs/`
|
|
20
|
+
- Default context directory: `./context/`
|
|
21
|
+
- Recursive scanning enabled by default
|
|
22
|
+
- **Examples in Output Directory**: Examples now created in `./voodocs/examples/`
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
- Parser now correctly handles @darkarts-only format (removed @voodocs pattern lookup)
|
|
26
|
+
- Context system now recognizes @darkarts annotations instead of @voodocs
|
|
27
|
+
- Git hooks installation for automatic context updates
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
- Default output directory changed from `./docs/` to `./voodocs/`
|
|
31
|
+
- Examples directory moved from project root to output directory
|
|
32
|
+
- Context generation is now opt-in via config (enabled by default)
|
|
33
|
+
|
|
34
|
+
# CHANGELOG
|
|
35
|
+
|
|
36
|
+
## [2.0.2] - 2024-12-21
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
- **Default paths in config** - `.voodocs.json` now includes `paths` section with `source`, `output`, and `recursive` settings
|
|
40
|
+
- **Generate without arguments** - `voodocs generate` now uses config defaults, no need to specify source/output every time
|
|
41
|
+
- **Recursive by default** - New projects default to recursive scanning (can be overridden with explicit flag)
|
|
42
|
+
- **Examples in output directory** - Example files now created in `{output}/examples/` instead of project root
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
- **Default output directory** - Changed from `./docs` to `./voodocs` for better branding
|
|
46
|
+
- **Examples location** - Examples now created in `./voodocs/examples/` instead of `./voodocs-examples/`
|
|
47
|
+
- `voodocs generate` SOURCE and OUTPUT arguments are now optional
|
|
48
|
+
- Recursive flag defaults to config setting (or `true` if no config)
|
|
49
|
+
- Improved user experience - simpler workflow after `voodocs init`
|
|
50
|
+
|
|
51
|
+
### Documentation
|
|
52
|
+
- Updated generate command help text to show config-based usage
|
|
53
|
+
- Added example: `voodocs generate` (uses config defaults)
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## [2.0.1] - 2024-12-21
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
- Removed non-existent conversion script reference from CHANGELOG migration guide
|
|
61
|
+
- Updated parser to check for `@darkarts` annotations instead of `@voodocs`
|
|
62
|
+
- Removed "incorrect format" examples from instruction files for cleaner documentation
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
- Simplified migration guide to manual-only approach
|
|
66
|
+
- Updated all internal references from `@voodocs` annotation format to `@darkarts`
|
|
67
|
+
- Instruction files now focus exclusively on `@darkarts` format without showing legacy examples
|
|
68
|
+
|
|
69
|
+
### Documentation
|
|
70
|
+
- Clarified that v2.0.0+ is DarkArts-only (no migration tooling needed)
|
|
71
|
+
- Emphasized distinction between Voodocs (product) and DarkArts (language)
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
1
75
|
## [2.0.0] - 2024-12-21
|
|
2
76
|
|
|
77
|
+
|
|
3
78
|
### 🚨 BREAKING CHANGES
|
|
4
79
|
|
|
5
80
|
**VooDocs is now DarkArts-only!**
|
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__ = "2.
|
|
19
|
+
__version__ = "2.1.1"
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@click.group()
|
|
@@ -40,6 +40,7 @@ from .validate import validate
|
|
|
40
40
|
from .generate import generate
|
|
41
41
|
from .benchmark import benchmark
|
|
42
42
|
from .fix import fix
|
|
43
|
+
from .context import context
|
|
43
44
|
|
|
44
45
|
# Register commands
|
|
45
46
|
cli.add_command(init)
|
|
@@ -48,6 +49,7 @@ cli.add_command(validate)
|
|
|
48
49
|
cli.add_command(generate)
|
|
49
50
|
cli.add_command(benchmark)
|
|
50
51
|
cli.add_command(fix)
|
|
52
|
+
cli.add_command(context)
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
def main():
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"""@darkarts
|
|
2
|
+
⊢cli:context
|
|
3
|
+
∂{click,pathlib,sys}
|
|
4
|
+
⚠{python≥3.7,click≥8.0,context-system-available}
|
|
5
|
+
⊨{∀command→delegates-to-context-module}
|
|
6
|
+
🔒{read-write:context-directory}
|
|
7
|
+
⚡{O(1):command-dispatch}
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
VooDocs CLI - Context Command
|
|
12
|
+
|
|
13
|
+
Manages AI context files generated from @darkarts annotations.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import click
|
|
17
|
+
import sys
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
# Add parent to path for imports
|
|
21
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
22
|
+
from darkarts.context import (
|
|
23
|
+
cmd_context_init,
|
|
24
|
+
cmd_context_generate,
|
|
25
|
+
cmd_context_view,
|
|
26
|
+
cmd_context_status,
|
|
27
|
+
cmd_context_validate
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@click.group()
|
|
32
|
+
def context():
|
|
33
|
+
"""
|
|
34
|
+
Manage AI context files.
|
|
35
|
+
|
|
36
|
+
Context files provide AI assistants with structured information
|
|
37
|
+
about your codebase in pure DarkArts language.
|
|
38
|
+
"""
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@context.command('init')
|
|
43
|
+
@click.option('--force', is_flag=True, help='Overwrite existing context file')
|
|
44
|
+
def context_init(force):
|
|
45
|
+
"""Initialize context system."""
|
|
46
|
+
try:
|
|
47
|
+
cmd_context_init(force=force)
|
|
48
|
+
click.echo(click.style('✓ Context initialized', fg='green'))
|
|
49
|
+
except Exception as e:
|
|
50
|
+
click.echo(click.style(f'Error: {e}', fg='red'), err=True)
|
|
51
|
+
sys.exit(1)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@context.command('generate')
|
|
55
|
+
@click.argument('source', type=click.Path(exists=True), required=False)
|
|
56
|
+
def context_generate(source):
|
|
57
|
+
"""Generate context from @darkarts annotations."""
|
|
58
|
+
if source is None:
|
|
59
|
+
source = '.'
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
click.echo(f'Generating context from: {source}')
|
|
63
|
+
result = cmd_context_generate(source, update_existing=True)
|
|
64
|
+
click.echo(click.style(f'✓ Context generated', fg='green'))
|
|
65
|
+
except Exception as e:
|
|
66
|
+
click.echo(click.style(f'Error: {e}', fg='red'), err=True)
|
|
67
|
+
sys.exit(1)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@context.command('view')
|
|
71
|
+
@click.option('--format', type=click.Choice(['yaml', 'markdown']), default='markdown', help='Output format')
|
|
72
|
+
def context_view(format):
|
|
73
|
+
"""View current context."""
|
|
74
|
+
try:
|
|
75
|
+
cmd_context_view()
|
|
76
|
+
except Exception as e:
|
|
77
|
+
click.echo(click.style(f'Error: {e}', fg='red'), err=True)
|
|
78
|
+
sys.exit(1)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@context.command('status')
|
|
82
|
+
def context_status():
|
|
83
|
+
"""Show context status."""
|
|
84
|
+
try:
|
|
85
|
+
cmd_context_status()
|
|
86
|
+
except Exception as e:
|
|
87
|
+
click.echo(click.style(f'Error: {e}', fg='red'), err=True)
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@context.command('validate')
|
|
92
|
+
def context_validate():
|
|
93
|
+
"""Validate context file."""
|
|
94
|
+
try:
|
|
95
|
+
cmd_context_validate()
|
|
96
|
+
click.echo(click.style('✓ Context is valid', fg='green'))
|
|
97
|
+
except Exception as e:
|
|
98
|
+
click.echo(click.style(f'Error: {e}', fg='red'), err=True)
|
|
99
|
+
sys.exit(1)
|
package/lib/cli/generate.py
CHANGED
|
@@ -26,9 +26,9 @@ from darkarts.validation.performance_wrapper import PerformanceTracker
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@click.command()
|
|
29
|
-
@click.argument('source', type=click.Path(exists=True))
|
|
30
|
-
@click.argument('output', type=click.Path())
|
|
31
|
-
@click.option('-r', '--recursive', is_flag=True, help='Recursively process all files')
|
|
29
|
+
@click.argument('source', type=click.Path(exists=True), required=False)
|
|
30
|
+
@click.argument('output', type=click.Path(), required=False)
|
|
31
|
+
@click.option('-r', '--recursive', is_flag=True, default=None, help='Recursively process all files (default: from config or True)')
|
|
32
32
|
@click.option('--validate', is_flag=True, help='Validate annotations before generating')
|
|
33
33
|
@click.option('--strict', is_flag=True, help='Fail if validation fails')
|
|
34
34
|
@click.option('--format', type=click.Choice(['markdown', 'html', 'json']), default='markdown', help='Output format')
|
|
@@ -48,27 +48,64 @@ def generate(
|
|
|
48
48
|
Reads @darkarts annotations from Python files and generates
|
|
49
49
|
comprehensive documentation in various formats.
|
|
50
50
|
|
|
51
|
+
If SOURCE and OUTPUT are not provided, reads from .voodocs.json config.
|
|
52
|
+
|
|
51
53
|
Examples:
|
|
52
54
|
|
|
55
|
+
# Use config defaults
|
|
56
|
+
voodocs generate
|
|
57
|
+
|
|
53
58
|
# Generate markdown docs
|
|
54
59
|
voodocs generate lib/ docs/
|
|
55
60
|
|
|
56
61
|
# Generate with validation
|
|
57
62
|
voodocs generate lib/ docs/ --validate
|
|
58
63
|
|
|
59
|
-
#
|
|
60
|
-
voodocs generate lib/ docs/
|
|
61
|
-
|
|
62
|
-
# HTML format
|
|
63
|
-
voodocs generate lib/ docs/ --format html
|
|
64
|
-
|
|
65
|
-
# Recursive processing
|
|
66
|
-
voodocs generate lib/ docs/ -r
|
|
64
|
+
# Recursive processing (default from config)
|
|
65
|
+
voodocs generate lib/ docs/
|
|
67
66
|
"""
|
|
68
67
|
|
|
68
|
+
# Load config if source/output not provided
|
|
69
|
+
import json
|
|
70
|
+
config_path = Path.cwd() / '.voodocs.json'
|
|
71
|
+
config = None
|
|
72
|
+
|
|
73
|
+
if config_path.exists():
|
|
74
|
+
try:
|
|
75
|
+
with open(config_path) as f:
|
|
76
|
+
config = json.load(f)
|
|
77
|
+
except:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
# Use config defaults if arguments not provided
|
|
81
|
+
if source is None:
|
|
82
|
+
if config and 'paths' in config:
|
|
83
|
+
source = config['paths'].get('source', '.')
|
|
84
|
+
else:
|
|
85
|
+
click.echo(click.style('Error: No SOURCE argument and no .voodocs.json config found', fg='red'))
|
|
86
|
+
click.echo('Run "voodocs init" first or provide SOURCE and OUTPUT arguments')
|
|
87
|
+
sys.exit(1)
|
|
88
|
+
|
|
89
|
+
if output is None:
|
|
90
|
+
if config and 'paths' in config:
|
|
91
|
+
output = config['paths'].get('output', './voodocs')
|
|
92
|
+
else:
|
|
93
|
+
click.echo(click.style('Error: No OUTPUT argument and no .voodocs.json config found', fg='red'))
|
|
94
|
+
click.echo('Run "voodocs init" first or provide SOURCE and OUTPUT arguments')
|
|
95
|
+
sys.exit(1)
|
|
96
|
+
|
|
97
|
+
# Use config recursive setting if not explicitly provided
|
|
98
|
+
if recursive is None:
|
|
99
|
+
if config and 'paths' in config:
|
|
100
|
+
recursive = config['paths'].get('recursive', True)
|
|
101
|
+
else:
|
|
102
|
+
recursive = True # Default to True
|
|
103
|
+
|
|
69
104
|
click.echo(f"Generating documentation from: {source}")
|
|
70
105
|
click.echo(f"Output directory: {output}")
|
|
71
106
|
click.echo(f"Format: {format}")
|
|
107
|
+
if recursive:
|
|
108
|
+
click.echo(f"Recursive: {click.style('Yes', fg='green')}")
|
|
72
109
|
click.echo()
|
|
73
110
|
|
|
74
111
|
# Collect source files
|
|
@@ -173,6 +210,18 @@ def generate(
|
|
|
173
210
|
click.echo(f"Output directory: {output_path}")
|
|
174
211
|
click.echo("━" * 60)
|
|
175
212
|
|
|
213
|
+
# Generate context if enabled
|
|
214
|
+
if config and config.get('context', {}).get('enabled', True):
|
|
215
|
+
click.echo()
|
|
216
|
+
click.echo(click.style('⚙️ Generating AI context...', fg='blue'))
|
|
217
|
+
try:
|
|
218
|
+
from darkarts.context import cmd_context_generate
|
|
219
|
+
context_path = config.get('paths', {}).get('context', './context')
|
|
220
|
+
cmd_context_generate(str(source_path), update_existing=True)
|
|
221
|
+
click.echo(click.style(f' ✓ Context generated: {context_path}', fg='green'))
|
|
222
|
+
except Exception as e:
|
|
223
|
+
click.echo(click.style(f' ⚠️ Context generation failed: {e}', fg='yellow'))
|
|
224
|
+
|
|
176
225
|
if len(generated_files) == len(files_to_process):
|
|
177
226
|
click.echo()
|
|
178
227
|
click.secho("✅ Documentation generation complete!", fg='green')
|
package/lib/cli/init.py
CHANGED
|
@@ -216,6 +216,29 @@ def init(non_interactive, upgrade):
|
|
|
216
216
|
|
|
217
217
|
click.echo()
|
|
218
218
|
|
|
219
|
+
# Step 6: Context Auto-Update
|
|
220
|
+
click.echo(click.style('🔄 Step 6: Context Auto-Update', fg='blue', bold=True))
|
|
221
|
+
click.echo()
|
|
222
|
+
click.echo('Context files provide AI assistants with structured information')
|
|
223
|
+
click.echo('about your codebase in DarkArts language.')
|
|
224
|
+
click.echo()
|
|
225
|
+
|
|
226
|
+
if non_interactive:
|
|
227
|
+
auto_update_choice = 'manual'
|
|
228
|
+
else:
|
|
229
|
+
click.echo('How should context be updated?')
|
|
230
|
+
click.echo(' 1. Manual (run "voodocs generate" to update)')
|
|
231
|
+
click.echo(' 2. Git hooks (auto-update on commit)')
|
|
232
|
+
click.echo()
|
|
233
|
+
auto_update_choice = click.prompt(
|
|
234
|
+
'Choice',
|
|
235
|
+
type=click.Choice(['1', '2'], case_sensitive=False),
|
|
236
|
+
default='1'
|
|
237
|
+
)
|
|
238
|
+
auto_update_choice = 'manual' if auto_update_choice == '1' else 'git-hooks'
|
|
239
|
+
|
|
240
|
+
click.echo()
|
|
241
|
+
|
|
219
242
|
# Show configuration summary
|
|
220
243
|
click.echo(click.style('📊 Configuration Summary', fg='cyan', bold=True))
|
|
221
244
|
click.echo(click.style('─' * 50, fg='cyan'))
|
|
@@ -254,6 +277,17 @@ def init(non_interactive, upgrade):
|
|
|
254
277
|
"repository": repository if repository else None
|
|
255
278
|
},
|
|
256
279
|
"format": format_choice,
|
|
280
|
+
"paths": {
|
|
281
|
+
"source": ".",
|
|
282
|
+
"output": "./voodocs",
|
|
283
|
+
"context": "./context",
|
|
284
|
+
"recursive": True
|
|
285
|
+
},
|
|
286
|
+
"context": {
|
|
287
|
+
"enabled": True,
|
|
288
|
+
"auto_update": auto_update_choice,
|
|
289
|
+
"format": "darkarts"
|
|
290
|
+
},
|
|
257
291
|
"validation": {
|
|
258
292
|
"semantic": True,
|
|
259
293
|
"performance": True,
|
|
@@ -302,15 +336,26 @@ def init(non_interactive, upgrade):
|
|
|
302
336
|
# Create example files
|
|
303
337
|
if create_examples:
|
|
304
338
|
click.echo(click.style(' ⚙️ Creating example files...', fg='blue'))
|
|
305
|
-
|
|
306
|
-
|
|
339
|
+
# Use output path from config for examples
|
|
340
|
+
output_path = config['paths']['output']
|
|
341
|
+
examples_dir = cwd / output_path / 'examples'
|
|
342
|
+
examples_dir.mkdir(parents=True, exist_ok=True)
|
|
307
343
|
|
|
308
344
|
if format_choice == 'voodocs':
|
|
309
345
|
_create_voodocs_examples(examples_dir)
|
|
310
346
|
else:
|
|
311
347
|
_create_darkarts_examples(examples_dir)
|
|
312
348
|
|
|
313
|
-
click.echo(click.style(f' ✓ Created examples in {examples_dir}/', fg='green'))
|
|
349
|
+
click.echo(click.style(f' ✓ Created examples in {examples_dir.relative_to(cwd)}/', fg='green'))
|
|
350
|
+
|
|
351
|
+
# Install git hooks if requested
|
|
352
|
+
if auto_update_choice == 'git-hooks':
|
|
353
|
+
click.echo(click.style(' ⚙️ Installing git hooks...', fg='blue'))
|
|
354
|
+
try:
|
|
355
|
+
_install_git_hooks(cwd)
|
|
356
|
+
click.echo(click.style(' ✓ Git hooks installed', fg='green'))
|
|
357
|
+
except Exception as e:
|
|
358
|
+
click.echo(click.style(f' ⚠️ Git hooks installation failed: {e}', fg='yellow'))
|
|
314
359
|
|
|
315
360
|
# Success!
|
|
316
361
|
click.echo()
|
|
@@ -578,3 +623,31 @@ export function greet(name: string, age: number): string {
|
|
|
578
623
|
'''
|
|
579
624
|
|
|
580
625
|
(examples_dir / 'example.ts').write_text(ts_example)
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
def _install_git_hooks(cwd: Path):
|
|
629
|
+
"""Install git hooks for automatic context updates."""
|
|
630
|
+
git_dir = cwd / '.git'
|
|
631
|
+
|
|
632
|
+
if not git_dir.exists():
|
|
633
|
+
raise Exception('Not a git repository. Initialize git first with: git init')
|
|
634
|
+
|
|
635
|
+
hooks_dir = git_dir / 'hooks'
|
|
636
|
+
hooks_dir.mkdir(exist_ok=True)
|
|
637
|
+
|
|
638
|
+
# Create pre-commit hook
|
|
639
|
+
pre_commit_hook = hooks_dir / 'pre-commit'
|
|
640
|
+
|
|
641
|
+
hook_content = '''#!/bin/sh
|
|
642
|
+
# VooDocs auto-update hook
|
|
643
|
+
# Updates context files before commit
|
|
644
|
+
|
|
645
|
+
echo "🔄 Updating VooDocs context..."
|
|
646
|
+
voodocs generate --quiet 2>&1 || true
|
|
647
|
+
git add context/
|
|
648
|
+
|
|
649
|
+
exit 0
|
|
650
|
+
'''
|
|
651
|
+
|
|
652
|
+
pre_commit_hook.write_text(hook_content)
|
|
653
|
+
pre_commit_hook.chmod(0o755) # Make executable
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""@darkarts
|
|
2
2
|
⊢parser:annotations.multi-lang
|
|
3
3
|
∂{re,ast,pathlib,types}
|
|
4
|
-
⚠{src:utf8,@
|
|
4
|
+
⚠{src:utf8,@darkarts∈docstrings,yaml-lists,fs:readable}
|
|
5
5
|
⊨{∀parse→¬modify-src,∀read→handle-encoding,parsed∈pyobj,dedup-invariants,lang-detect:accurate}
|
|
6
6
|
🔒{read-only,¬exec}
|
|
7
7
|
⚡{O(n'*m/c)|n'=files-with-annotations,m=avg-file-size,c=cache-constant,speedup=5-10x}
|
|
@@ -129,22 +129,18 @@ class AnnotationParser:
|
|
|
129
129
|
if language is None:
|
|
130
130
|
language = self.detect_language(source_file)
|
|
131
131
|
|
|
132
|
-
# Extract
|
|
133
|
-
pattern = self.PATTERNS.get(language, self.PATTERNS[Language.PYTHON])
|
|
132
|
+
# Extract @darkarts annotation blocks only (v2.0.0+)
|
|
134
133
|
darkarts_pattern = self.DARKARTS_PATTERNS.get(language, self.DARKARTS_PATTERNS[Language.PYTHON])
|
|
135
134
|
|
|
136
|
-
#
|
|
137
|
-
voodocs_matches = list(re.finditer(pattern, source_code, re.DOTALL))
|
|
138
|
-
|
|
139
|
-
# Also check for DarkArts
|
|
135
|
+
# Find all @darkarts annotations
|
|
140
136
|
darkarts_matches = list(re.finditer(darkarts_pattern, source_code, re.DOTALL))
|
|
141
137
|
|
|
142
|
-
#
|
|
143
|
-
if darkarts_matches
|
|
138
|
+
# Parse DarkArts annotations
|
|
139
|
+
if darkarts_matches:
|
|
144
140
|
return self._parse_darkarts_annotations(source_code, source_file, language, darkarts_matches)
|
|
145
141
|
|
|
146
|
-
#
|
|
147
|
-
matches =
|
|
142
|
+
# No annotations found - return empty
|
|
143
|
+
matches = []
|
|
148
144
|
|
|
149
145
|
annotations = []
|
|
150
146
|
for match in matches:
|
|
@@ -681,10 +677,10 @@ class AnnotationParser:
|
|
|
681
677
|
@staticmethod
|
|
682
678
|
def _has_annotations(file_path: Path) -> bool:
|
|
683
679
|
"""
|
|
684
|
-
Quick check if a file contains @
|
|
680
|
+
Quick check if a file contains @darkarts annotations.
|
|
685
681
|
|
|
686
682
|
Phase 1 Optimization: Pre-filter files before full parsing.
|
|
687
|
-
Reads only first 10KB to check for @
|
|
683
|
+
Reads only first 10KB to check for @darkarts marker.
|
|
688
684
|
|
|
689
685
|
Args:
|
|
690
686
|
file_path: Path to the file to check
|
|
@@ -696,7 +692,7 @@ class AnnotationParser:
|
|
|
696
692
|
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
|
697
693
|
# Read first 10KB (enough for module-level annotations)
|
|
698
694
|
preview = f.read(10000)
|
|
699
|
-
return '@
|
|
695
|
+
return '@darkarts' in preview
|
|
700
696
|
except Exception:
|
|
701
697
|
# If we can't read it, skip it
|
|
702
698
|
return False
|
|
@@ -813,7 +809,7 @@ class AnnotationParser:
|
|
|
813
809
|
return self._parse_generic(source_code, source_file, language, translated_annotations)
|
|
814
810
|
|
|
815
811
|
def _darkarts_to_voodocs_yaml(self, annotation_dict: Dict[str, Any]) -> str:
|
|
816
|
-
"""Convert DarkArts annotation dict to
|
|
812
|
+
"""Convert DarkArts annotation dict to YAML format (legacy)."""
|
|
817
813
|
lines = []
|
|
818
814
|
|
|
819
815
|
# Module name becomes module_purpose (just use the identifier)
|
|
@@ -271,7 +271,7 @@ class DarkArtsTranslator:
|
|
|
271
271
|
|
|
272
272
|
def create_darkarts_from_voodocs(self, voodocs_dict: Dict) -> str:
|
|
273
273
|
"""
|
|
274
|
-
Create @darkarts annotation from
|
|
274
|
+
Create @darkarts annotation from dictionary (legacy conversion).
|
|
275
275
|
|
|
276
276
|
Args:
|
|
277
277
|
voodocs_dict: Dictionary with keys like 'module_purpose',
|
|
@@ -408,6 +408,6 @@ def translate_to_symbols(text: str) -> str:
|
|
|
408
408
|
|
|
409
409
|
|
|
410
410
|
def convert_voodocs_to_darkarts(voodocs_dict: Dict) -> str:
|
|
411
|
-
"""Convert
|
|
411
|
+
"""Convert dictionary to @darkarts annotation (legacy)."""
|
|
412
412
|
translator = DarkArtsTranslator()
|
|
413
413
|
return translator.create_darkarts_from_voodocs(voodocs_dict)
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
DarkArts Annotation Types
|
|
10
10
|
|
|
11
|
-
Data structures for parsed @darkarts
|
|
11
|
+
Data structures for parsed @darkarts annotations with:
|
|
12
12
|
- Annotation types (function, method, class, module)
|
|
13
13
|
- Language support (Python, TypeScript, JavaScript, Java, C++, C#, Go, Rust)
|
|
14
14
|
- Complexity annotations (time, space, best/worst/average case)
|
|
@@ -1206,7 +1206,7 @@ def cmd_context_generate(source_dir: Optional[str] = None, update_existing: bool
|
|
|
1206
1206
|
else:
|
|
1207
1207
|
scan_path = Path.cwd()
|
|
1208
1208
|
|
|
1209
|
-
step(f"Scanning for @
|
|
1209
|
+
step(f"Scanning for @darkarts annotations in: {scan_path}")
|
|
1210
1210
|
print()
|
|
1211
1211
|
|
|
1212
1212
|
# Import the annotation parser
|
|
@@ -1218,8 +1218,8 @@ def cmd_context_generate(source_dir: Optional[str] = None, update_existing: bool
|
|
|
1218
1218
|
results = parser.parse_directory(scan_path)
|
|
1219
1219
|
|
|
1220
1220
|
if not results:
|
|
1221
|
-
warning("No @
|
|
1222
|
-
info("Add @
|
|
1221
|
+
warning("No @darkarts annotations found.")
|
|
1222
|
+
info("Add @darkarts annotations to your code first.")
|
|
1223
1223
|
return 1
|
|
1224
1224
|
|
|
1225
1225
|
# Extract global invariants from all annotations
|
|
@@ -1281,11 +1281,21 @@ def cmd_context_generate(source_dir: Optional[str] = None, update_existing: bool
|
|
|
1281
1281
|
update_existing = True
|
|
1282
1282
|
|
|
1283
1283
|
if update_existing:
|
|
1284
|
-
# Update existing context
|
|
1284
|
+
# Update existing context (or create if doesn't exist)
|
|
1285
1285
|
if not context_file_exists():
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1286
|
+
info("No context file found. Creating minimal context...")
|
|
1287
|
+
# Auto-create minimal context
|
|
1288
|
+
from .models import create_minimal_context
|
|
1289
|
+
minimal_context = create_minimal_context(
|
|
1290
|
+
project_name=scan_path.name,
|
|
1291
|
+
project_purpose="Auto-generated from @darkarts annotations",
|
|
1292
|
+
code_version="1.0.0"
|
|
1293
|
+
)
|
|
1294
|
+
from .yaml_utils import write_context_yaml
|
|
1295
|
+
context_path = get_context_file_path()
|
|
1296
|
+
write_context_yaml(minimal_context, context_path)
|
|
1297
|
+
info(f"Created context file: {context_path}")
|
|
1298
|
+
print()
|
|
1289
1299
|
|
|
1290
1300
|
context_path = get_context_file_path()
|
|
1291
1301
|
data = read_context_yaml(context_path)
|
|
@@ -13,7 +13,7 @@ Your primary goal is to **write and maintain symbolic DarkArts annotations** for
|
|
|
13
13
|
|
|
14
14
|
## 2. Annotation Format: Symbolic DarkArts
|
|
15
15
|
|
|
16
|
-
**Always use the symbolic DarkArts format.**
|
|
16
|
+
**Always use the symbolic DarkArts format.** This is the only supported format in v2.0+.
|
|
17
17
|
|
|
18
18
|
### Correct Format
|
|
19
19
|
|
|
@@ -33,15 +33,6 @@ Your primary goal is to **write and maintain symbolic DarkArts annotations** for
|
|
|
33
33
|
*/
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
### Incorrect Format (Do Not Use)
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
/**@voodocs
|
|
40
|
-
module_purpose: "..."
|
|
41
|
-
dependencies: [...]
|
|
42
|
-
*/
|
|
43
|
-
```
|
|
44
|
-
|
|
45
36
|
---
|
|
46
37
|
|
|
47
38
|
## 3. Key Rules
|
|
@@ -73,7 +64,24 @@ dependencies: [...]
|
|
|
73
64
|
|
|
74
65
|
---
|
|
75
66
|
|
|
76
|
-
## 5.
|
|
67
|
+
## 5. Project Context File
|
|
68
|
+
|
|
69
|
+
**Before working on this codebase, always read the `.voodocs.context` file first.**
|
|
70
|
+
|
|
71
|
+
This file contains:
|
|
72
|
+
- **Project Overview:** Purpose, architecture, and key decisions
|
|
73
|
+
- **Module Information:** What each module does and how they relate
|
|
74
|
+
- **Global Invariants:** Rules that must always hold true
|
|
75
|
+
- **Assumptions:** What the codebase depends on
|
|
76
|
+
- **Tech Stack:** Technologies and their versions
|
|
77
|
+
|
|
78
|
+
The context file is automatically generated from @darkarts annotations and provides a high-level understanding of the entire codebase. Use it to understand the project before making changes.
|
|
79
|
+
|
|
80
|
+
**Location:** `.voodocs.context` (in project root)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 6. Workflow
|
|
77
85
|
|
|
78
86
|
1. **When writing new code:** Add symbolic DarkArts annotations as you go.
|
|
79
87
|
2. **When modifying existing code:** Update the corresponding annotations to reflect your changes.
|
|
@@ -82,7 +90,7 @@ dependencies: [...]
|
|
|
82
90
|
|
|
83
91
|
---
|
|
84
92
|
|
|
85
|
-
##
|
|
93
|
+
## 7. Example: Adding a New Function
|
|
86
94
|
|
|
87
95
|
If you add a new function `getUserById`, you must add a symbolic annotation block:
|
|
88
96
|
|
|
@@ -103,7 +111,7 @@ export async function getUserById(userId: string): Promise<User | null> {
|
|
|
103
111
|
|
|
104
112
|
---
|
|
105
113
|
|
|
106
|
-
##
|
|
114
|
+
## 8. Example: Modifying a Module
|
|
107
115
|
|
|
108
116
|
If you add a new dependency to a module, update the `∂` field:
|
|
109
117
|
|
|
@@ -128,11 +136,12 @@ If you add a new dependency to a module, update the `∂` field:
|
|
|
128
136
|
|
|
129
137
|
---
|
|
130
138
|
|
|
131
|
-
##
|
|
139
|
+
## 9. Important Commands
|
|
132
140
|
|
|
133
141
|
- **Validate:** `voodocs validate . --recursive`
|
|
134
142
|
- **Fix:** `voodocs fix . --recursive`
|
|
135
|
-
- **Generate Docs:** `voodocs generate
|
|
143
|
+
- **Generate Docs & Context:** `voodocs generate`
|
|
144
|
+
- **View Context:** `voodocs context view`
|
|
136
145
|
|
|
137
146
|
---
|
|
138
147
|
|
|
@@ -13,7 +13,7 @@ Your primary goal is to **write and maintain symbolic DarkArts annotations** for
|
|
|
13
13
|
|
|
14
14
|
## 2. Annotation Format: Symbolic DarkArts
|
|
15
15
|
|
|
16
|
-
**Always use the symbolic DarkArts format.**
|
|
16
|
+
**Always use the symbolic DarkArts format.** This is the only supported format in v2.0+.
|
|
17
17
|
|
|
18
18
|
### Correct Format
|
|
19
19
|
|
|
@@ -33,15 +33,6 @@ Your primary goal is to **write and maintain symbolic DarkArts annotations** for
|
|
|
33
33
|
*/
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
### Incorrect Format (Do Not Use)
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
/**@voodocs
|
|
40
|
-
module_purpose: "..."
|
|
41
|
-
dependencies: [...]
|
|
42
|
-
*/
|
|
43
|
-
```
|
|
44
|
-
|
|
45
36
|
---
|
|
46
37
|
|
|
47
38
|
## 3. Key Rules
|
|
@@ -73,7 +64,24 @@ dependencies: [...]
|
|
|
73
64
|
|
|
74
65
|
---
|
|
75
66
|
|
|
76
|
-
## 5.
|
|
67
|
+
## 5. Project Context File
|
|
68
|
+
|
|
69
|
+
**Before working on this codebase, always read the `.voodocs.context` file first.**
|
|
70
|
+
|
|
71
|
+
This file contains:
|
|
72
|
+
- **Project Overview:** Purpose, architecture, and key decisions
|
|
73
|
+
- **Module Information:** What each module does and how they relate
|
|
74
|
+
- **Global Invariants:** Rules that must always hold true
|
|
75
|
+
- **Assumptions:** What the codebase depends on
|
|
76
|
+
- **Tech Stack:** Technologies and their versions
|
|
77
|
+
|
|
78
|
+
The context file is automatically generated from @darkarts annotations and provides a high-level understanding of the entire codebase. Use it to understand the project before making changes.
|
|
79
|
+
|
|
80
|
+
**Location:** `.voodocs.context` (in project root)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 6. Workflow
|
|
77
85
|
|
|
78
86
|
1. **When writing new code:** Add symbolic DarkArts annotations as you go.
|
|
79
87
|
2. **When modifying existing code:** Update the corresponding annotations to reflect your changes.
|
|
@@ -82,7 +90,7 @@ dependencies: [...]
|
|
|
82
90
|
|
|
83
91
|
---
|
|
84
92
|
|
|
85
|
-
##
|
|
93
|
+
## 7. Example: Adding a New Function
|
|
86
94
|
|
|
87
95
|
If you add a new function `getUserById`, you must add a symbolic annotation block:
|
|
88
96
|
|
|
@@ -103,7 +111,7 @@ export async function getUserById(userId: string): Promise<User | null> {
|
|
|
103
111
|
|
|
104
112
|
---
|
|
105
113
|
|
|
106
|
-
##
|
|
114
|
+
## 8. Example: Modifying a Module
|
|
107
115
|
|
|
108
116
|
If you add a new dependency to a module, update the `∂` field:
|
|
109
117
|
|
|
@@ -128,11 +136,12 @@ If you add a new dependency to a module, update the `∂` field:
|
|
|
128
136
|
|
|
129
137
|
---
|
|
130
138
|
|
|
131
|
-
##
|
|
139
|
+
## 9. Important Commands
|
|
132
140
|
|
|
133
141
|
- **Validate:** `voodocs validate . --recursive`
|
|
134
142
|
- **Fix:** `voodocs fix . --recursive`
|
|
135
|
-
- **Generate Docs:** `voodocs generate
|
|
143
|
+
- **Generate Docs & Context:** `voodocs generate`
|
|
144
|
+
- **View Context:** `voodocs context view`
|
|
136
145
|
|
|
137
146
|
---
|
|
138
147
|
|
|
@@ -13,7 +13,7 @@ Your primary goal is to **write and maintain symbolic DarkArts annotations** for
|
|
|
13
13
|
|
|
14
14
|
## 2. Annotation Format: Symbolic DarkArts
|
|
15
15
|
|
|
16
|
-
**Always use the symbolic DarkArts format.**
|
|
16
|
+
**Always use the symbolic DarkArts format.** This is the only supported format in v2.0+.
|
|
17
17
|
|
|
18
18
|
### Correct Format
|
|
19
19
|
|
|
@@ -33,15 +33,6 @@ Your primary goal is to **write and maintain symbolic DarkArts annotations** for
|
|
|
33
33
|
*/
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
### Incorrect Format (Do Not Use)
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
/**@voodocs
|
|
40
|
-
module_purpose: "..."
|
|
41
|
-
dependencies: [...]
|
|
42
|
-
*/
|
|
43
|
-
```
|
|
44
|
-
|
|
45
36
|
---
|
|
46
37
|
|
|
47
38
|
## 3. Key Rules
|
|
@@ -73,7 +64,24 @@ dependencies: [...]
|
|
|
73
64
|
|
|
74
65
|
---
|
|
75
66
|
|
|
76
|
-
## 5.
|
|
67
|
+
## 5. Project Context File
|
|
68
|
+
|
|
69
|
+
**Before working on this codebase, always read the `.voodocs.context` file first.**
|
|
70
|
+
|
|
71
|
+
This file contains:
|
|
72
|
+
- **Project Overview:** Purpose, architecture, and key decisions
|
|
73
|
+
- **Module Information:** What each module does and how they relate
|
|
74
|
+
- **Global Invariants:** Rules that must always hold true
|
|
75
|
+
- **Assumptions:** What the codebase depends on
|
|
76
|
+
- **Tech Stack:** Technologies and their versions
|
|
77
|
+
|
|
78
|
+
The context file is automatically generated from @darkarts annotations and provides a high-level understanding of the entire codebase. Use it to understand the project before making changes.
|
|
79
|
+
|
|
80
|
+
**Location:** `.voodocs.context` (in project root)
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 6. Workflow
|
|
77
85
|
|
|
78
86
|
1. **When writing new code:** Add symbolic DarkArts annotations as you go.
|
|
79
87
|
2. **When modifying existing code:** Update the corresponding annotations to reflect your changes.
|
|
@@ -82,7 +90,7 @@ dependencies: [...]
|
|
|
82
90
|
|
|
83
91
|
---
|
|
84
92
|
|
|
85
|
-
##
|
|
93
|
+
## 7. Example: Adding a New Function
|
|
86
94
|
|
|
87
95
|
If you add a new function `getUserById`, you must add a symbolic annotation block:
|
|
88
96
|
|
|
@@ -103,7 +111,7 @@ export async function getUserById(userId: string): Promise<User | null> {
|
|
|
103
111
|
|
|
104
112
|
---
|
|
105
113
|
|
|
106
|
-
##
|
|
114
|
+
## 8. Example: Modifying a Module
|
|
107
115
|
|
|
108
116
|
If you add a new dependency to a module, update the `∂` field:
|
|
109
117
|
|
|
@@ -128,11 +136,12 @@ If you add a new dependency to a module, update the `∂` field:
|
|
|
128
136
|
|
|
129
137
|
---
|
|
130
138
|
|
|
131
|
-
##
|
|
139
|
+
## 9. Important Commands
|
|
132
140
|
|
|
133
141
|
- **Validate:** `voodocs validate . --recursive`
|
|
134
142
|
- **Fix:** `voodocs fix . --recursive`
|
|
135
|
-
- **Generate Docs:** `voodocs generate
|
|
143
|
+
- **Generate Docs & Context:** `voodocs generate`
|
|
144
|
+
- **View Context:** `voodocs context view`
|
|
136
145
|
|
|
137
146
|
---
|
|
138
147
|
|
package/package.json
CHANGED