@voodocs/cli 2.2.1 β 2.2.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 +38 -215
- package/LICENSE +1 -1
- package/PRIVACY.md +10 -10
- package/README.md +35 -39
- package/USAGE.md +27 -50
- package/examples/.cursorrules +9 -9
- package/examples/instructions/.claude/instructions.md +65 -77
- package/examples/instructions/.cursorrules +9 -9
- package/examples/instructions/.windsurfrules +9 -9
- package/examples/instructions/VOODOCS_INSTRUCTIONS.md +62 -74
- package/examples/math_example.py +1 -1
- package/examples/phase2_test.py +1 -1
- package/examples/test_function_invariants.py +1 -1
- package/lib/cli/__init__.py +3 -3
- package/lib/cli/benchmark.py +3 -3
- package/lib/cli/context.py +1 -1
- package/lib/cli/fix.py +1 -1
- package/lib/cli/generate.py +1 -1
- package/lib/cli/init.py +10 -10
- package/lib/cli/instruct.py +1 -1
- package/lib/cli/validate.py +3 -3
- package/lib/darkarts/annotations/DARKARTS_SYMBOLS.md +95 -110
- package/lib/darkarts/annotations/TRANSFORMATION_EXAMPLES.md +27 -29
- package/lib/darkarts/annotations/parser.py +215 -36
- package/lib/darkarts/cli_darkarts.py +5 -5
- package/lib/darkarts/context/ai_instructions.py +12 -12
- package/lib/darkarts/context/ai_integrations.py +16 -16
- package/lib/darkarts/context/commands.py +4 -4
- package/lib/darkarts/context/errors.py +1 -1
- package/lib/darkarts/context/models.py +1 -1
- package/lib/darkarts/context/ui.py +4 -4
- package/lib/darkarts/context/yaml_utils.py +3 -3
- package/lib/darkarts/core/loader.py +1 -1
- package/lib/darkarts/exceptions.py +3 -3
- package/lib/darkarts/parsers/typescript/dist/parser.d.ts +16 -0
- package/lib/darkarts/parsers/typescript/dist/parser.d.ts.map +1 -1
- package/lib/darkarts/parsers/typescript/dist/parser.js +64 -0
- package/lib/darkarts/parsers/typescript/dist/parser.js.map +1 -1
- package/lib/darkarts/parsers/typescript/src/parser.ts +68 -0
- package/lib/darkarts/plugins/voodocs/ai_native_plugin.py +1 -1
- package/lib/darkarts/plugins/voodocs/annotation_validator.py +2 -2
- package/lib/darkarts/plugins/voodocs/documentation_generator.py +3 -3
- package/lib/darkarts/plugins/voodocs/html_exporter.py +4 -4
- package/lib/darkarts/plugins/voodocs/instruction_generator.py +10 -10
- package/lib/darkarts/plugins/voodocs/pdf_exporter.py +1 -1
- package/lib/darkarts/plugins/voodocs/test_generator.py +1 -1
- package/lib/darkarts/telemetry.py +5 -5
- package/lib/darkarts/validation/README.md +3 -6
- package/package.json +1 -1
- package/requirements.txt +2 -2
- package/templates/ci/github-actions.yml +64 -64
- package/templates/ci/pre-commit-hook.sh +4 -4
- package/voodocs_cli.py +1 -1
|
@@ -763,50 +763,229 @@ class AnnotationParser:
|
|
|
763
763
|
language: Language,
|
|
764
764
|
darkarts_matches: List
|
|
765
765
|
) -> ParsedAnnotations:
|
|
766
|
-
"""Parse @darkarts annotations
|
|
767
|
-
from .darkarts_parser import parse_darkarts
|
|
768
|
-
from .translator import DarkArtsTranslator
|
|
766
|
+
"""Parse @darkarts annotations using two-pass approach.
|
|
769
767
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
768
|
+
Pass 1: Extract code structure using language-specific parser
|
|
769
|
+
Pass 2: Parse annotations and overlay them onto structure by line number
|
|
770
|
+
"""
|
|
771
|
+
from .darkarts_parser import DarkArtsParser
|
|
772
|
+
|
|
773
|
+
# PASS 1: Extract code structure using language-specific parser
|
|
774
|
+
if language == Language.PYTHON:
|
|
775
|
+
# For Python, extract structure using AST
|
|
776
|
+
structure = self._extract_python_structure(source_code, source_file)
|
|
777
|
+
elif language in (Language.TYPESCRIPT, Language.JAVASCRIPT):
|
|
778
|
+
# For TypeScript/JavaScript, use TypeScript parser
|
|
779
|
+
structure = self._extract_typescript_structure(source_file)
|
|
780
|
+
else:
|
|
781
|
+
# For other languages, create empty structure
|
|
782
|
+
structure = self._create_empty_structure(source_file, language)
|
|
783
|
+
|
|
784
|
+
# PASS 2: Parse @darkarts annotations and match to structure
|
|
785
|
+
darkarts_parser = DarkArtsParser()
|
|
786
|
+
annotations_by_line = {}
|
|
773
787
|
|
|
774
788
|
for match in darkarts_matches:
|
|
775
789
|
darkarts_text = match.group(1)
|
|
790
|
+
line_number = source_code[:match.start()].count('\n') + 1
|
|
776
791
|
|
|
777
|
-
# Parse @darkarts annotation
|
|
778
|
-
|
|
779
|
-
parser = DarkArtsParser()
|
|
780
|
-
darkarts_annotation = parser.parse_annotation(darkarts_text)
|
|
781
|
-
|
|
782
|
-
# Process the annotation
|
|
792
|
+
# Parse @darkarts annotation
|
|
793
|
+
darkarts_annotation = darkarts_parser.parse_annotation(darkarts_text)
|
|
783
794
|
if darkarts_annotation:
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
795
|
+
annotations_by_line[line_number] = darkarts_annotation
|
|
796
|
+
|
|
797
|
+
# PASS 3: Overlay annotations onto structure
|
|
798
|
+
return self._overlay_annotations(structure, annotations_by_line)
|
|
799
|
+
|
|
800
|
+
def _extract_python_structure(self, source_code: str, source_file: str) -> ParsedAnnotations:
|
|
801
|
+
"""Extract Python code structure using AST (without annotations)."""
|
|
802
|
+
try:
|
|
803
|
+
tree = ast.parse(source_code)
|
|
804
|
+
except SyntaxError:
|
|
805
|
+
return self._create_empty_structure(source_file, Language.PYTHON)
|
|
806
|
+
|
|
807
|
+
module = ModuleAnnotation(
|
|
808
|
+
name=Path(source_file).stem,
|
|
809
|
+
source_file=source_file,
|
|
810
|
+
language=Language.PYTHON,
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
# Extract functions and classes from AST
|
|
814
|
+
for node in ast.walk(tree):
|
|
815
|
+
if isinstance(node, ast.FunctionDef):
|
|
816
|
+
func = FunctionAnnotation(
|
|
817
|
+
name=node.name,
|
|
818
|
+
line_number=node.lineno,
|
|
819
|
+
)
|
|
820
|
+
module.functions.append(func)
|
|
821
|
+
elif isinstance(node, ast.ClassDef):
|
|
822
|
+
cls = ClassAnnotation(
|
|
823
|
+
name=node.name,
|
|
824
|
+
line_number=node.lineno,
|
|
825
|
+
)
|
|
826
|
+
# Extract methods
|
|
827
|
+
for item in node.body:
|
|
828
|
+
if isinstance(item, ast.FunctionDef):
|
|
829
|
+
method = FunctionAnnotation(
|
|
830
|
+
name=item.name,
|
|
831
|
+
line_number=item.lineno,
|
|
832
|
+
)
|
|
833
|
+
cls.methods.append(method)
|
|
834
|
+
module.classes.append(cls)
|
|
835
|
+
|
|
836
|
+
return ParsedAnnotations(
|
|
837
|
+
module=module,
|
|
838
|
+
language=Language.PYTHON,
|
|
839
|
+
source_file=source_file,
|
|
840
|
+
)
|
|
841
|
+
|
|
842
|
+
def _extract_typescript_structure(self, source_file: str) -> ParsedAnnotations:
|
|
843
|
+
"""Extract TypeScript/JavaScript code structure using TypeScript parser."""
|
|
844
|
+
try:
|
|
845
|
+
check_parser_for_language('typescript')
|
|
846
|
+
except ParserNotBuiltError:
|
|
847
|
+
return self._create_empty_structure(source_file, Language.TYPESCRIPT)
|
|
848
|
+
|
|
849
|
+
# Get the path to the TypeScript parser CLI
|
|
850
|
+
parser_dir = Path(__file__).parent.parent / 'parsers' / 'typescript'
|
|
851
|
+
parser_cli = parser_dir / 'dist' / 'cli.js'
|
|
852
|
+
|
|
853
|
+
if not parser_cli.exists():
|
|
854
|
+
return self._create_empty_structure(source_file, Language.TYPESCRIPT)
|
|
855
|
+
|
|
856
|
+
# Run the TypeScript parser
|
|
857
|
+
try:
|
|
858
|
+
result = subprocess.run(
|
|
859
|
+
['node', str(parser_cli), source_file],
|
|
860
|
+
capture_output=True,
|
|
861
|
+
text=True,
|
|
862
|
+
check=True
|
|
863
|
+
)
|
|
864
|
+
data = json.loads(result.stdout)
|
|
865
|
+
except (subprocess.CalledProcessError, json.JSONDecodeError):
|
|
866
|
+
return self._create_empty_structure(source_file, Language.TYPESCRIPT)
|
|
867
|
+
|
|
868
|
+
# Convert TypeScript parser output to our format
|
|
869
|
+
language = Language.TYPESCRIPT if data['language'] == 'typescript' else Language.JAVASCRIPT
|
|
870
|
+
|
|
871
|
+
module = ModuleAnnotation(
|
|
872
|
+
name=Path(source_file).stem,
|
|
873
|
+
source_file=source_file,
|
|
874
|
+
language=language,
|
|
875
|
+
)
|
|
876
|
+
|
|
877
|
+
# Extract classes
|
|
878
|
+
for cls_data in data.get('classes', []):
|
|
879
|
+
cls = ClassAnnotation(
|
|
880
|
+
name=cls_data['name'],
|
|
881
|
+
line_number=cls_data['line'],
|
|
882
|
+
)
|
|
883
|
+
# Extract methods
|
|
884
|
+
for method_data in cls_data.get('methods', []):
|
|
885
|
+
method = FunctionAnnotation(
|
|
886
|
+
name=method_data['name'],
|
|
887
|
+
line_number=method_data['line'],
|
|
888
|
+
)
|
|
889
|
+
cls.methods.append(method)
|
|
890
|
+
module.classes.append(cls)
|
|
891
|
+
|
|
892
|
+
# Extract functions
|
|
893
|
+
for func_data in data.get('functions', []):
|
|
894
|
+
func = FunctionAnnotation(
|
|
895
|
+
name=func_data['name'],
|
|
896
|
+
line_number=func_data['line'],
|
|
897
|
+
)
|
|
898
|
+
module.functions.append(func)
|
|
899
|
+
|
|
900
|
+
return ParsedAnnotations(
|
|
901
|
+
module=module,
|
|
902
|
+
language=language,
|
|
903
|
+
source_file=source_file,
|
|
904
|
+
)
|
|
905
|
+
|
|
906
|
+
def _create_empty_structure(self, source_file: str, language: Language) -> ParsedAnnotations:
|
|
907
|
+
"""Create empty structure for unsupported languages."""
|
|
908
|
+
module = ModuleAnnotation(
|
|
909
|
+
name=Path(source_file).stem,
|
|
910
|
+
source_file=source_file,
|
|
911
|
+
language=language,
|
|
912
|
+
)
|
|
913
|
+
return ParsedAnnotations(
|
|
914
|
+
module=module,
|
|
915
|
+
language=language,
|
|
916
|
+
source_file=source_file,
|
|
917
|
+
)
|
|
918
|
+
|
|
919
|
+
def _overlay_annotations(self, structure: ParsedAnnotations, annotations_by_line: Dict[int, Any]) -> ParsedAnnotations:
|
|
920
|
+
"""Overlay parsed annotations onto code structure by matching line numbers."""
|
|
921
|
+
# Match annotations to code elements by finding the closest following element
|
|
922
|
+
for line_num, annotation in annotations_by_line.items():
|
|
923
|
+
# Check if this is a module-level annotation (appears before any code)
|
|
924
|
+
if self._is_module_annotation(annotation):
|
|
925
|
+
self._apply_module_annotation_from_darkarts(structure.module, annotation)
|
|
926
|
+
continue
|
|
927
|
+
|
|
928
|
+
# Find the closest function or class after this line
|
|
929
|
+
matched = False
|
|
930
|
+
|
|
931
|
+
# Try to match to a function
|
|
932
|
+
for func in structure.module.functions:
|
|
933
|
+
if func.line_number >= line_num and func.line_number - line_num <= 5:
|
|
934
|
+
self._apply_function_annotation_from_darkarts(func, annotation)
|
|
935
|
+
matched = True
|
|
936
|
+
break
|
|
937
|
+
|
|
938
|
+
if matched:
|
|
939
|
+
continue
|
|
940
|
+
|
|
941
|
+
# Try to match to a class
|
|
942
|
+
for cls in structure.module.classes:
|
|
943
|
+
if cls.line_number >= line_num and cls.line_number - line_num <= 5:
|
|
944
|
+
self._apply_class_annotation_from_darkarts(cls, annotation)
|
|
945
|
+
matched = True
|
|
946
|
+
break
|
|
793
947
|
|
|
794
|
-
#
|
|
795
|
-
|
|
948
|
+
# Try to match to a method within the class
|
|
949
|
+
for method in cls.methods:
|
|
950
|
+
if method.line_number >= line_num and method.line_number - line_num <= 5:
|
|
951
|
+
self._apply_function_annotation_from_darkarts(method, annotation)
|
|
952
|
+
matched = True
|
|
953
|
+
break
|
|
796
954
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
955
|
+
if matched:
|
|
956
|
+
break
|
|
957
|
+
|
|
958
|
+
return structure
|
|
959
|
+
|
|
960
|
+
def _is_module_annotation(self, annotation: Any) -> bool:
|
|
961
|
+
"""Check if annotation is module-level."""
|
|
962
|
+
return hasattr(annotation, 'module') and annotation.module
|
|
963
|
+
|
|
964
|
+
def _apply_module_annotation_from_darkarts(self, module: ModuleAnnotation, annotation: Any):
|
|
965
|
+
"""Apply @darkarts annotation to module."""
|
|
966
|
+
if hasattr(annotation, 'module') and annotation.module:
|
|
967
|
+
module.module_purpose = f"Module {{{annotation.module}}}"
|
|
968
|
+
if hasattr(annotation, 'dependencies') and annotation.dependencies:
|
|
969
|
+
module.dependencies = annotation.dependencies
|
|
970
|
+
if hasattr(annotation, 'assumptions') and annotation.assumptions:
|
|
971
|
+
module.assumptions = annotation.assumptions
|
|
972
|
+
|
|
973
|
+
def _apply_function_annotation_from_darkarts(self, func: FunctionAnnotation, annotation: Any):
|
|
974
|
+
"""Apply @darkarts annotation to function."""
|
|
975
|
+
if hasattr(annotation, 'preconditions') and annotation.preconditions:
|
|
976
|
+
func.preconditions = annotation.preconditions
|
|
977
|
+
if hasattr(annotation, 'postconditions') and annotation.postconditions:
|
|
978
|
+
func.postconditions = annotation.postconditions
|
|
979
|
+
if hasattr(annotation, 'invariants') and annotation.invariants:
|
|
980
|
+
func.invariants = annotation.invariants
|
|
981
|
+
if hasattr(annotation, 'performance') and annotation.performance:
|
|
982
|
+
if isinstance(annotation.performance, dict) and 'complexity' in annotation.performance:
|
|
983
|
+
func.complexity = annotation.performance['complexity']
|
|
984
|
+
|
|
985
|
+
def _apply_class_annotation_from_darkarts(self, cls: ClassAnnotation, annotation: Any):
|
|
986
|
+
"""Apply @darkarts annotation to class."""
|
|
987
|
+
if hasattr(annotation, 'invariants') and annotation.invariants:
|
|
988
|
+
cls.invariants = annotation.invariants
|
|
810
989
|
|
|
811
990
|
def _darkarts_to_voodocs_yaml(self, annotation_dict: Dict[str, Any]) -> str:
|
|
812
991
|
"""Convert DarkArts annotation dict to YAML format (legacy)."""
|
|
@@ -52,7 +52,7 @@ def cmd_darkarts_translate(args):
|
|
|
52
52
|
|
|
53
53
|
try:
|
|
54
54
|
if to_symbols:
|
|
55
|
-
# Natural language β Symbols (
|
|
55
|
+
# Natural language β Symbols (VooDocs β DarkArts)
|
|
56
56
|
parser = AnnotationParser()
|
|
57
57
|
annotations = parser.parse_file(str(path))
|
|
58
58
|
|
|
@@ -91,7 +91,7 @@ def cmd_darkarts_translate(args):
|
|
|
91
91
|
|
|
92
92
|
def cmd_darkarts_convert(args):
|
|
93
93
|
"""
|
|
94
|
-
Convert files between
|
|
94
|
+
Convert files between VooDocs and DarkArts formats.
|
|
95
95
|
|
|
96
96
|
Usage:
|
|
97
97
|
voodocs darkarts convert <files> [--in-place]
|
|
@@ -121,7 +121,7 @@ def cmd_darkarts_convert(args):
|
|
|
121
121
|
try:
|
|
122
122
|
content = path.read_text()
|
|
123
123
|
|
|
124
|
-
# Parse
|
|
124
|
+
# Parse VooDocs annotations
|
|
125
125
|
parser = AnnotationParser()
|
|
126
126
|
annotations = parser.parse_file(str(path))
|
|
127
127
|
language = parser.detect_language(str(path))
|
|
@@ -412,7 +412,7 @@ def cmd_darkarts_validate(args):
|
|
|
412
412
|
|
|
413
413
|
def add_darkarts_subcommands(subparsers):
|
|
414
414
|
"""
|
|
415
|
-
Add DarkArts subcommands to
|
|
415
|
+
Add DarkArts subcommands to VooDocs CLI.
|
|
416
416
|
|
|
417
417
|
Args:
|
|
418
418
|
subparsers: Argparse subparsers object
|
|
@@ -446,7 +446,7 @@ def add_darkarts_subcommands(subparsers):
|
|
|
446
446
|
# darkarts convert
|
|
447
447
|
convert_parser = darkarts_subparsers.add_parser(
|
|
448
448
|
"convert",
|
|
449
|
-
help="Convert
|
|
449
|
+
help="Convert VooDocs annotations to DarkArts"
|
|
450
450
|
)
|
|
451
451
|
convert_parser.add_argument(
|
|
452
452
|
"files",
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
π{no-implications}
|
|
7
7
|
β‘{O(1)|template-generation}
|
|
8
8
|
|
|
9
|
-
AI instruction templates for
|
|
9
|
+
AI instruction templates for VooDocs Context System.
|
|
10
10
|
|
|
11
11
|
This module provides templates for generating AI assistant instructions
|
|
12
|
-
that teach them how to use the
|
|
12
|
+
that teach them how to use the VooDocs context system effectively.
|
|
13
13
|
"""
|
|
14
14
|
|
|
15
15
|
from typing import Dict, Optional
|
|
@@ -26,14 +26,14 @@ def generate_cursorrules(project_name: str, project_purpose: str) -> str:
|
|
|
26
26
|
Returns:
|
|
27
27
|
Content for .cursorrules file
|
|
28
28
|
"""
|
|
29
|
-
return f"""# {project_name} -
|
|
29
|
+
return f"""# {project_name} - VooDocs Context System
|
|
30
30
|
|
|
31
31
|
## Project Overview
|
|
32
32
|
{project_purpose}
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## VooDocs Context System (v0.2.0+)
|
|
35
35
|
|
|
36
|
-
This project uses
|
|
36
|
+
This project uses VooDocs with the Context System for intelligent documentation and validation.
|
|
37
37
|
|
|
38
38
|
### Context File Location
|
|
39
39
|
- **Context file**: `.voodocs.context` (YAML format)
|
|
@@ -222,7 +222,7 @@ voodocs context diagram --type all --output docs/arch
|
|
|
222
222
|
|
|
223
223
|
---
|
|
224
224
|
|
|
225
|
-
**
|
|
225
|
+
**VooDocs Context System** - AI-native documentation that keeps code and context in sync.
|
|
226
226
|
"""
|
|
227
227
|
|
|
228
228
|
|
|
@@ -237,20 +237,20 @@ def generate_context_guide(project_name: str, project_purpose: str) -> str:
|
|
|
237
237
|
Returns:
|
|
238
238
|
Content for VOODOCS_CONTEXT_GUIDE.md file
|
|
239
239
|
"""
|
|
240
|
-
return f"""#
|
|
240
|
+
return f"""# VooDocs Context System Guide - {project_name}
|
|
241
241
|
|
|
242
242
|
## Project Overview
|
|
243
243
|
|
|
244
244
|
**Name**: {project_name}
|
|
245
245
|
**Purpose**: {project_purpose}
|
|
246
246
|
|
|
247
|
-
This project uses the **
|
|
247
|
+
This project uses the **VooDocs Context System** (v0.2.0+) for intelligent documentation, validation, and architecture management.
|
|
248
248
|
|
|
249
249
|
---
|
|
250
250
|
|
|
251
251
|
## What is the Context System?
|
|
252
252
|
|
|
253
|
-
The
|
|
253
|
+
The VooDocs Context System is an AI-native documentation framework that:
|
|
254
254
|
|
|
255
255
|
1. **Auto-generates** project context from code annotations
|
|
256
256
|
2. **Validates** code against documented invariants
|
|
@@ -620,7 +620,7 @@ jobs:
|
|
|
620
620
|
steps:
|
|
621
621
|
- uses: actions/checkout@v2
|
|
622
622
|
|
|
623
|
-
- name: Install
|
|
623
|
+
- name: Install VooDocs
|
|
624
624
|
run: npm install -g @voodocs/cli
|
|
625
625
|
|
|
626
626
|
- name: Validate Context
|
|
@@ -703,7 +703,7 @@ Or add `module_purpose` to @voodocs annotations and regenerate.
|
|
|
703
703
|
|
|
704
704
|
## Summary
|
|
705
705
|
|
|
706
|
-
The
|
|
706
|
+
The VooDocs Context System is your **single source of truth** for:
|
|
707
707
|
- β
Project understanding
|
|
708
708
|
- β
Architecture documentation
|
|
709
709
|
- β
Code validation
|
|
@@ -714,7 +714,7 @@ The Voodocs Context System is your **single source of truth** for:
|
|
|
714
714
|
|
|
715
715
|
---
|
|
716
716
|
|
|
717
|
-
**
|
|
717
|
+
**VooDocs v0.2.0+** - AI-native documentation that keeps code and context in sync.
|
|
718
718
|
"""
|
|
719
719
|
|
|
720
720
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
π{read-only:detect,write:explicit-user-command}
|
|
7
7
|
β‘{O(nΒ²):detect-with-analysis,O(k):generate|k=ai-count}
|
|
8
8
|
|
|
9
|
-
AI-specific integration templates for
|
|
9
|
+
AI-specific integration templates for VooDocs Context System.
|
|
10
10
|
|
|
11
11
|
This module provides native integration with different AI assistants:
|
|
12
12
|
- Claude Code (skills)
|
|
@@ -23,7 +23,7 @@ from pathlib import Path
|
|
|
23
23
|
|
|
24
24
|
def generate_claude_skill(project_name: str, project_purpose: str) -> Dict[str, str]:
|
|
25
25
|
"""
|
|
26
|
-
Generate Claude Code skill for
|
|
26
|
+
Generate Claude Code skill for VooDocs context system.
|
|
27
27
|
|
|
28
28
|
Args:
|
|
29
29
|
project_name: Name of the project
|
|
@@ -34,15 +34,15 @@ def generate_claude_skill(project_name: str, project_purpose: str) -> Dict[str,
|
|
|
34
34
|
"""
|
|
35
35
|
skill_md = f"""---
|
|
36
36
|
name: voodocs-context
|
|
37
|
-
description: Access and query the
|
|
37
|
+
description: Access and query the VooDocs context system for project understanding, invariants, and architecture
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
-
#
|
|
40
|
+
# VooDocs Context System Skill
|
|
41
41
|
|
|
42
42
|
## Project: {project_name}
|
|
43
43
|
{project_purpose}
|
|
44
44
|
|
|
45
|
-
This skill provides access to the
|
|
45
|
+
This skill provides access to the VooDocs context system for understanding project architecture, invariants, and assumptions.
|
|
46
46
|
|
|
47
47
|
## Available Commands
|
|
48
48
|
|
|
@@ -152,7 +152,7 @@ voodocs context check
|
|
|
152
152
|
|
|
153
153
|
def generate_cursor_rules(project_name: str, project_purpose: str) -> Dict[str, str]:
|
|
154
154
|
"""
|
|
155
|
-
Generate Cursor rules for
|
|
155
|
+
Generate Cursor rules for VooDocs context system.
|
|
156
156
|
|
|
157
157
|
Args:
|
|
158
158
|
project_name: Name of the project
|
|
@@ -162,12 +162,12 @@ def generate_cursor_rules(project_name: str, project_purpose: str) -> Dict[str,
|
|
|
162
162
|
Dictionary mapping file paths to content
|
|
163
163
|
"""
|
|
164
164
|
|
|
165
|
-
main_rule = f"""#
|
|
165
|
+
main_rule = f"""# VooDocs Context System
|
|
166
166
|
|
|
167
167
|
## Project: {project_name}
|
|
168
168
|
{project_purpose}
|
|
169
169
|
|
|
170
|
-
This project uses the
|
|
170
|
+
This project uses the VooDocs Context System (v0.2.0+) for documentation and validation.
|
|
171
171
|
|
|
172
172
|
## Context File
|
|
173
173
|
- **Location**: `.voodocs.context`
|
|
@@ -283,7 +283,7 @@ voodocs context query "module-name" --section architecture
|
|
|
283
283
|
|
|
284
284
|
def generate_copilot_instructions(project_name: str, project_purpose: str) -> Dict[str, str]:
|
|
285
285
|
"""
|
|
286
|
-
Generate GitHub Copilot instructions for
|
|
286
|
+
Generate GitHub Copilot instructions for VooDocs context system.
|
|
287
287
|
|
|
288
288
|
Args:
|
|
289
289
|
project_name: Name of the project
|
|
@@ -298,9 +298,9 @@ def generate_copilot_instructions(project_name: str, project_purpose: str) -> Di
|
|
|
298
298
|
## Project Overview
|
|
299
299
|
{project_purpose}
|
|
300
300
|
|
|
301
|
-
##
|
|
301
|
+
## VooDocs Context System
|
|
302
302
|
|
|
303
|
-
This project uses
|
|
303
|
+
This project uses VooDocs Context System (v0.2.0+) for documentation and validation.
|
|
304
304
|
|
|
305
305
|
### Context File
|
|
306
306
|
- **Location**: `.voodocs.context` (YAML format)
|
|
@@ -400,7 +400,7 @@ voodocs context diagram --type modules
|
|
|
400
400
|
|
|
401
401
|
def generate_windsurf_rules(project_name: str, project_purpose: str) -> Dict[str, str]:
|
|
402
402
|
"""
|
|
403
|
-
Generate Windsurf rules for
|
|
403
|
+
Generate Windsurf rules for VooDocs context system.
|
|
404
404
|
|
|
405
405
|
Args:
|
|
406
406
|
project_name: Name of the project
|
|
@@ -415,9 +415,9 @@ def generate_windsurf_rules(project_name: str, project_purpose: str) -> Dict[str
|
|
|
415
415
|
## Project
|
|
416
416
|
{project_purpose}
|
|
417
417
|
|
|
418
|
-
##
|
|
418
|
+
## VooDocs Context System
|
|
419
419
|
|
|
420
|
-
This project uses
|
|
420
|
+
This project uses VooDocs (v0.2.0+) for context management.
|
|
421
421
|
|
|
422
422
|
### Context Commands
|
|
423
423
|
|
|
@@ -478,7 +478,7 @@ invariants: ["rules"]
|
|
|
478
478
|
|
|
479
479
|
def generate_cline_rules(project_name: str, project_purpose: str) -> Dict[str, str]:
|
|
480
480
|
"""
|
|
481
|
-
Generate Cline rules for
|
|
481
|
+
Generate Cline rules for VooDocs context system.
|
|
482
482
|
|
|
483
483
|
Args:
|
|
484
484
|
project_name: Name of the project
|
|
@@ -493,7 +493,7 @@ def generate_cline_rules(project_name: str, project_purpose: str) -> Dict[str, s
|
|
|
493
493
|
## Project
|
|
494
494
|
{project_purpose}
|
|
495
495
|
|
|
496
|
-
##
|
|
496
|
+
## VooDocs Context System
|
|
497
497
|
|
|
498
498
|
Context file: `.voodocs.context` (YAML)
|
|
499
499
|
|
|
@@ -210,7 +210,7 @@ def cmd_context_init(force: bool = False) -> int:
|
|
|
210
210
|
Exit code (0 for success, 1 for error)
|
|
211
211
|
"""
|
|
212
212
|
try:
|
|
213
|
-
print_header("
|
|
213
|
+
print_header("VooDocs Context Initialization")
|
|
214
214
|
|
|
215
215
|
# Check if context file already exists
|
|
216
216
|
context_path = get_context_file_path()
|
|
@@ -224,7 +224,7 @@ def cmd_context_init(force: bool = False) -> int:
|
|
|
224
224
|
if not confirm(f"Overwrite existing context file at {context_path}?", default=False):
|
|
225
225
|
raise UserInterruptError("Initialization")
|
|
226
226
|
|
|
227
|
-
step("Initializing
|
|
227
|
+
step("Initializing VooDocs context...")
|
|
228
228
|
print()
|
|
229
229
|
|
|
230
230
|
# Detect project information
|
|
@@ -375,7 +375,7 @@ def cmd_context_init(force: bool = False) -> int:
|
|
|
375
375
|
|
|
376
376
|
print()
|
|
377
377
|
print("π€ AI integration complete!")
|
|
378
|
-
print(f" Your {ai_type} assistant will now understand the
|
|
378
|
+
print(f" Your {ai_type} assistant will now understand the VooDocs context system.")
|
|
379
379
|
|
|
380
380
|
except Exception as e:
|
|
381
381
|
print(f"β οΈ Warning: Failed to generate AI integration: {e}")
|
|
@@ -1368,7 +1368,7 @@ def cmd_context_generate(source_dir: Optional[str] = None, update_existing: bool
|
|
|
1368
1368
|
return 1
|
|
1369
1369
|
except ImportError as e:
|
|
1370
1370
|
error(f"Failed to import annotation parser: {e}")
|
|
1371
|
-
warning("Make sure
|
|
1371
|
+
warning("Make sure VooDocs is properly installed")
|
|
1372
1372
|
return 1
|
|
1373
1373
|
except Exception as e:
|
|
1374
1374
|
error(f"Failed to generate context: {e}")
|
|
@@ -52,7 +52,7 @@ class GitNotAvailableError(ConfigurationError):
|
|
|
52
52
|
def __init__(self):
|
|
53
53
|
super().__init__(
|
|
54
54
|
f"Git is not available\n\n"
|
|
55
|
-
f"π‘ Some
|
|
55
|
+
f"π‘ Some VooDocs features require Git. Please install Git:\n"
|
|
56
56
|
f" https://git-scm.com/downloads"
|
|
57
57
|
)
|
|
58
58
|
|
|
@@ -119,8 +119,8 @@ def step(message: str) -> None:
|
|
|
119
119
|
message: Step message to display
|
|
120
120
|
|
|
121
121
|
Example:
|
|
122
|
-
>>> step("Initializing
|
|
123
|
-
βΆοΈ Initializing
|
|
122
|
+
>>> step("Initializing VooDocs context...")
|
|
123
|
+
βΆοΈ Initializing VooDocs context...
|
|
124
124
|
"""
|
|
125
125
|
print(f"{Colors.CYAN}βΆοΈ {message}{Colors.RESET}")
|
|
126
126
|
|
|
@@ -243,10 +243,10 @@ def print_header(title: str) -> None:
|
|
|
243
243
|
title: Header title
|
|
244
244
|
|
|
245
245
|
Example:
|
|
246
|
-
>>> print_header("
|
|
246
|
+
>>> print_header("VooDocs Context System")
|
|
247
247
|
|
|
248
248
|
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
249
|
-
|
|
249
|
+
VooDocs Context System
|
|
250
250
|
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
251
251
|
"""
|
|
252
252
|
width = 80
|
|
@@ -56,7 +56,7 @@ def write_context_yaml(context: ContextFile, file_path: Path) -> None:
|
|
|
56
56
|
# Create file with header comment
|
|
57
57
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
58
58
|
# Write header
|
|
59
|
-
f.write("#
|
|
59
|
+
f.write("# VooDocs Context File\n")
|
|
60
60
|
f.write("# This file contains structured project context for AI assistants and developers.\n")
|
|
61
61
|
f.write("# Format: YAML (DSL for machines, use 'voodocs context view' for human-readable Markdown)\n")
|
|
62
62
|
f.write("# Version: {}\n".format(context.versioning.context_version))
|
|
@@ -333,14 +333,14 @@ def add_to_gitignore(project_root: Path) -> bool:
|
|
|
333
333
|
# Ensure there's a newline before our section
|
|
334
334
|
if not content.endswith('\n'):
|
|
335
335
|
f.write('\n')
|
|
336
|
-
f.write('\n#
|
|
336
|
+
f.write('\n# VooDocs Context File (contains internal project details)\n')
|
|
337
337
|
f.write(f'{context_entry}\n')
|
|
338
338
|
|
|
339
339
|
return True
|
|
340
340
|
else:
|
|
341
341
|
# Create .gitignore with entry
|
|
342
342
|
with open(gitignore_path, 'w', encoding='utf-8') as f:
|
|
343
|
-
f.write('#
|
|
343
|
+
f.write('# VooDocs Context File (contains internal project details)\n')
|
|
344
344
|
f.write(f'{context_entry}\n')
|
|
345
345
|
|
|
346
346
|
return True
|
|
@@ -199,7 +199,7 @@ class PluginLoader:
|
|
|
199
199
|
plugin = self.load_from_module("darkarts.plugins.voodocs", "VooDocsPlugin")
|
|
200
200
|
plugins.append(plugin)
|
|
201
201
|
except PluginError:
|
|
202
|
-
pass #
|
|
202
|
+
pass # VooDocs plugin not yet implemented
|
|
203
203
|
|
|
204
204
|
return plugins
|
|
205
205
|
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
π{pure-exceptions,Β¬io,Β¬side-effects,Β¬exec}
|
|
7
7
|
β‘{O(1):exception-creation}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
VooDocs Custom Exceptions
|
|
10
10
|
|
|
11
11
|
Structured exception hierarchy for error handling with:
|
|
12
|
-
- Base exception (VooDocsError for all
|
|
12
|
+
- Base exception (VooDocsError for all VooDocs errors)
|
|
13
13
|
- Parser errors (ParserError, ParserNotBuiltError, AnnotationError)
|
|
14
14
|
- Validation errors (InvalidAnnotationError, ValidationError)
|
|
15
15
|
- Generator errors (GeneratorError)
|
|
@@ -20,7 +20,7 @@ Structured exception hierarchy for error handling with:
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class VooDocsError(Exception):
|
|
23
|
-
"""Base exception for all
|
|
23
|
+
"""Base exception for all VooDocs errors."""
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
26
|
|