elspais 0.11.1__py3-none-any.whl → 0.43.5__py3-none-any.whl

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.
Files changed (148) hide show
  1. elspais/__init__.py +2 -11
  2. elspais/{sponsors/__init__.py → associates.py} +102 -58
  3. elspais/cli.py +395 -79
  4. elspais/commands/__init__.py +9 -3
  5. elspais/commands/analyze.py +121 -173
  6. elspais/commands/changed.py +15 -30
  7. elspais/commands/config_cmd.py +13 -16
  8. elspais/commands/edit.py +60 -44
  9. elspais/commands/example_cmd.py +319 -0
  10. elspais/commands/hash_cmd.py +167 -183
  11. elspais/commands/health.py +1177 -0
  12. elspais/commands/index.py +98 -114
  13. elspais/commands/init.py +103 -26
  14. elspais/commands/reformat_cmd.py +41 -444
  15. elspais/commands/rules_cmd.py +7 -3
  16. elspais/commands/trace.py +444 -321
  17. elspais/commands/validate.py +195 -415
  18. elspais/config/__init__.py +799 -5
  19. elspais/{core/content_rules.py → content_rules.py} +20 -3
  20. elspais/docs/cli/assertions.md +67 -0
  21. elspais/docs/cli/commands.md +304 -0
  22. elspais/docs/cli/config.md +262 -0
  23. elspais/docs/cli/format.md +66 -0
  24. elspais/docs/cli/git.md +45 -0
  25. elspais/docs/cli/health.md +190 -0
  26. elspais/docs/cli/hierarchy.md +60 -0
  27. elspais/docs/cli/ignore.md +72 -0
  28. elspais/docs/cli/mcp.md +245 -0
  29. elspais/docs/cli/quickstart.md +58 -0
  30. elspais/docs/cli/traceability.md +89 -0
  31. elspais/docs/cli/validation.md +96 -0
  32. elspais/graph/GraphNode.py +383 -0
  33. elspais/graph/__init__.py +40 -0
  34. elspais/graph/annotators.py +927 -0
  35. elspais/graph/builder.py +1886 -0
  36. elspais/graph/deserializer.py +248 -0
  37. elspais/graph/factory.py +284 -0
  38. elspais/graph/metrics.py +127 -0
  39. elspais/graph/mutations.py +161 -0
  40. elspais/graph/parsers/__init__.py +156 -0
  41. elspais/graph/parsers/code.py +213 -0
  42. elspais/graph/parsers/comments.py +112 -0
  43. elspais/graph/parsers/config_helpers.py +29 -0
  44. elspais/graph/parsers/heredocs.py +225 -0
  45. elspais/graph/parsers/journey.py +131 -0
  46. elspais/graph/parsers/remainder.py +79 -0
  47. elspais/graph/parsers/requirement.py +347 -0
  48. elspais/graph/parsers/results/__init__.py +6 -0
  49. elspais/graph/parsers/results/junit_xml.py +229 -0
  50. elspais/graph/parsers/results/pytest_json.py +313 -0
  51. elspais/graph/parsers/test.py +305 -0
  52. elspais/graph/relations.py +78 -0
  53. elspais/graph/serialize.py +216 -0
  54. elspais/html/__init__.py +8 -0
  55. elspais/html/generator.py +731 -0
  56. elspais/html/templates/trace_view.html.j2 +2151 -0
  57. elspais/mcp/__init__.py +47 -29
  58. elspais/mcp/__main__.py +5 -1
  59. elspais/mcp/file_mutations.py +138 -0
  60. elspais/mcp/server.py +2016 -247
  61. elspais/testing/__init__.py +4 -4
  62. elspais/testing/config.py +3 -0
  63. elspais/testing/mapper.py +1 -1
  64. elspais/testing/result_parser.py +25 -21
  65. elspais/testing/scanner.py +301 -12
  66. elspais/utilities/__init__.py +1 -0
  67. elspais/utilities/docs_loader.py +115 -0
  68. elspais/utilities/git.py +607 -0
  69. elspais/{core → utilities}/hasher.py +8 -22
  70. elspais/utilities/md_renderer.py +189 -0
  71. elspais/{core → utilities}/patterns.py +58 -57
  72. elspais/utilities/reference_config.py +626 -0
  73. elspais/validation/__init__.py +19 -0
  74. elspais/validation/format.py +264 -0
  75. {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/METADATA +7 -4
  76. elspais-0.43.5.dist-info/RECORD +80 -0
  77. elspais/config/defaults.py +0 -173
  78. elspais/config/loader.py +0 -494
  79. elspais/core/__init__.py +0 -21
  80. elspais/core/git.py +0 -352
  81. elspais/core/models.py +0 -320
  82. elspais/core/parser.py +0 -640
  83. elspais/core/rules.py +0 -514
  84. elspais/mcp/context.py +0 -171
  85. elspais/mcp/serializers.py +0 -112
  86. elspais/reformat/__init__.py +0 -50
  87. elspais/reformat/detector.py +0 -119
  88. elspais/reformat/hierarchy.py +0 -246
  89. elspais/reformat/line_breaks.py +0 -220
  90. elspais/reformat/prompts.py +0 -123
  91. elspais/reformat/transformer.py +0 -264
  92. elspais/trace_view/__init__.py +0 -54
  93. elspais/trace_view/coverage.py +0 -183
  94. elspais/trace_view/generators/__init__.py +0 -12
  95. elspais/trace_view/generators/base.py +0 -329
  96. elspais/trace_view/generators/csv.py +0 -122
  97. elspais/trace_view/generators/markdown.py +0 -175
  98. elspais/trace_view/html/__init__.py +0 -31
  99. elspais/trace_view/html/generator.py +0 -1006
  100. elspais/trace_view/html/templates/base.html +0 -283
  101. elspais/trace_view/html/templates/components/code_viewer_modal.html +0 -14
  102. elspais/trace_view/html/templates/components/file_picker_modal.html +0 -20
  103. elspais/trace_view/html/templates/components/legend_modal.html +0 -69
  104. elspais/trace_view/html/templates/components/review_panel.html +0 -118
  105. elspais/trace_view/html/templates/partials/review/help/help-panel.json +0 -244
  106. elspais/trace_view/html/templates/partials/review/help/onboarding.json +0 -77
  107. elspais/trace_view/html/templates/partials/review/help/tooltips.json +0 -237
  108. elspais/trace_view/html/templates/partials/review/review-comments.js +0 -928
  109. elspais/trace_view/html/templates/partials/review/review-data.js +0 -961
  110. elspais/trace_view/html/templates/partials/review/review-help.js +0 -679
  111. elspais/trace_view/html/templates/partials/review/review-init.js +0 -177
  112. elspais/trace_view/html/templates/partials/review/review-line-numbers.js +0 -429
  113. elspais/trace_view/html/templates/partials/review/review-packages.js +0 -1029
  114. elspais/trace_view/html/templates/partials/review/review-position.js +0 -540
  115. elspais/trace_view/html/templates/partials/review/review-resize.js +0 -115
  116. elspais/trace_view/html/templates/partials/review/review-status.js +0 -659
  117. elspais/trace_view/html/templates/partials/review/review-sync.js +0 -992
  118. elspais/trace_view/html/templates/partials/review-styles.css +0 -2238
  119. elspais/trace_view/html/templates/partials/scripts.js +0 -1741
  120. elspais/trace_view/html/templates/partials/styles.css +0 -1756
  121. elspais/trace_view/models.py +0 -353
  122. elspais/trace_view/review/__init__.py +0 -60
  123. elspais/trace_view/review/branches.py +0 -1149
  124. elspais/trace_view/review/models.py +0 -1205
  125. elspais/trace_view/review/position.py +0 -609
  126. elspais/trace_view/review/server.py +0 -1056
  127. elspais/trace_view/review/status.py +0 -470
  128. elspais/trace_view/review/storage.py +0 -1367
  129. elspais/trace_view/scanning.py +0 -213
  130. elspais/trace_view/specs/README.md +0 -84
  131. elspais/trace_view/specs/tv-d00001-template-architecture.md +0 -36
  132. elspais/trace_view/specs/tv-d00002-css-extraction.md +0 -37
  133. elspais/trace_view/specs/tv-d00003-js-extraction.md +0 -43
  134. elspais/trace_view/specs/tv-d00004-build-embedding.md +0 -40
  135. elspais/trace_view/specs/tv-d00005-test-format.md +0 -78
  136. elspais/trace_view/specs/tv-d00010-review-data-models.md +0 -33
  137. elspais/trace_view/specs/tv-d00011-review-storage.md +0 -33
  138. elspais/trace_view/specs/tv-d00012-position-resolution.md +0 -33
  139. elspais/trace_view/specs/tv-d00013-git-branches.md +0 -31
  140. elspais/trace_view/specs/tv-d00014-review-api-server.md +0 -31
  141. elspais/trace_view/specs/tv-d00015-status-modifier.md +0 -27
  142. elspais/trace_view/specs/tv-d00016-js-integration.md +0 -33
  143. elspais/trace_view/specs/tv-p00001-html-generator.md +0 -33
  144. elspais/trace_view/specs/tv-p00002-review-system.md +0 -29
  145. elspais-0.11.1.dist-info/RECORD +0 -101
  146. {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/WHEEL +0 -0
  147. {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/entry_points.txt +0 -0
  148. {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/licenses/LICENSE +0 -0
@@ -1,175 +0,0 @@
1
- """
2
- elspais.trace_view.generators.markdown - Markdown generation.
3
-
4
- Provides functions to generate markdown traceability matrices.
5
- """
6
-
7
- import sys
8
- from datetime import datetime
9
- from typing import Dict, List, Optional
10
-
11
- from elspais.trace_view.models import TraceViewRequirement
12
- from elspais.trace_view.coverage import count_by_level, find_orphaned_requirements
13
-
14
-
15
- def generate_legend_markdown() -> str:
16
- """Generate markdown legend section.
17
-
18
- Returns:
19
- Markdown string with legend explaining symbols
20
- """
21
- return """## Legend
22
-
23
- **Requirement Status:**
24
- - Active requirement
25
- - Draft requirement
26
- - Deprecated requirement
27
-
28
- **Traceability:**
29
- - Has implementation file(s)
30
- - No implementation found
31
-
32
- **Interactive (HTML only):**
33
- - Expandable (has child requirements)
34
- - Collapsed (click to expand)
35
- """
36
-
37
-
38
- def generate_markdown(
39
- requirements: Dict[str, TraceViewRequirement],
40
- base_path: str = "",
41
- ) -> str:
42
- """Generate markdown traceability matrix.
43
-
44
- Args:
45
- requirements: Dict mapping requirement ID to TraceViewRequirement
46
- base_path: Base path for links (e.g., '../' for files in subdirectory)
47
-
48
- Returns:
49
- Complete markdown traceability matrix
50
- """
51
- lines = []
52
- lines.append("# Requirements Traceability Matrix")
53
- lines.append(f"\n**Generated**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
54
- lines.append(f"**Total Requirements**: {len(requirements)}\n")
55
-
56
- # Summary by level (using active counts, excluding deprecated)
57
- by_level = count_by_level(requirements)
58
- lines.append("## Summary\n")
59
- lines.append(f"- **PRD Requirements**: {by_level['active']['PRD']}")
60
- lines.append(f"- **OPS Requirements**: {by_level['active']['OPS']}")
61
- lines.append(f"- **DEV Requirements**: {by_level['active']['DEV']}\n")
62
-
63
- # Add legend
64
- lines.append(generate_legend_markdown())
65
-
66
- # Full traceability tree
67
- lines.append("## Traceability Tree\n")
68
-
69
- # Start with top-level PRD requirements
70
- prd_reqs = [req for req in requirements.values() if req.level == "PRD"]
71
- prd_reqs.sort(key=lambda r: r.id)
72
-
73
- for prd_req in prd_reqs:
74
- lines.append(
75
- format_req_tree_md(
76
- prd_req, requirements, indent=0, ancestor_path=[], base_path=base_path
77
- )
78
- )
79
-
80
- # Orphaned ops/dev requirements
81
- orphaned = find_orphaned_requirements(requirements)
82
- if orphaned:
83
- lines.append("\n## Orphaned Requirements\n")
84
- lines.append("*(Requirements not linked from any parent)*\n")
85
- for req in orphaned:
86
- lines.append(
87
- f"- **REQ-{req.id}**: {req.title} ({req.level}) - {req.display_filename}"
88
- )
89
-
90
- return "\n".join(lines)
91
-
92
-
93
- def format_req_tree_md(
94
- req: TraceViewRequirement,
95
- requirements: Dict[str, TraceViewRequirement],
96
- indent: int,
97
- ancestor_path: Optional[List[str]] = None,
98
- base_path: str = "",
99
- ) -> str:
100
- """Format requirement and its children as markdown tree.
101
-
102
- Args:
103
- req: The requirement to format
104
- requirements: Dict mapping requirement ID to TraceViewRequirement
105
- indent: Current indentation level
106
- ancestor_path: List of requirement IDs in the current traversal path (for cycle detection)
107
- base_path: Base path for links
108
-
109
- Returns:
110
- Formatted markdown string
111
- """
112
- if ancestor_path is None:
113
- ancestor_path = []
114
-
115
- # Cycle detection: check if this requirement is already in our traversal path
116
- if req.id in ancestor_path:
117
- cycle_path = ancestor_path + [req.id]
118
- cycle_str = " -> ".join([f"REQ-{rid}" for rid in cycle_path])
119
- print(f"Warning: CYCLE DETECTED: {cycle_str}", file=sys.stderr)
120
- return (
121
- " " * indent
122
- + f"- **CYCLE DETECTED**: REQ-{req.id} (path: {cycle_str})"
123
- )
124
-
125
- # Safety depth limit
126
- MAX_DEPTH = 50
127
- if indent > MAX_DEPTH:
128
- print(f"Warning: MAX DEPTH ({MAX_DEPTH}) exceeded at REQ-{req.id}", file=sys.stderr)
129
- return " " * indent + f"- **MAX DEPTH EXCEEDED**: REQ-{req.id}"
130
-
131
- lines = []
132
- prefix = " " * indent
133
-
134
- # Format current requirement
135
- status_indicator = {
136
- "Active": "[Active]",
137
- "Draft": "[Draft]",
138
- "Deprecated": "[Deprecated]",
139
- }
140
- indicator = status_indicator.get(req.status, "[?]")
141
-
142
- # Create link to source file with REQ anchor
143
- if req.external_spec_path:
144
- req_link = f"[REQ-{req.id}](file://{req.external_spec_path}#REQ-{req.id})"
145
- else:
146
- spec_subpath = "spec/roadmap" if req.is_roadmap else "spec"
147
- req_link = f"[REQ-{req.id}]({base_path}{spec_subpath}/{req.file_path.name}#REQ-{req.id})"
148
-
149
- lines.append(
150
- f"{prefix}- {indicator} **{req_link}**: {req.title}\n"
151
- f"{prefix} - Level: {req.level} | Status: {req.status}\n"
152
- f"{prefix} - File: {req.display_filename}:{req.line_number}"
153
- )
154
-
155
- # Format implementation files as nested list with clickable links
156
- if req.implementation_files:
157
- lines.append(f"{prefix} - **Implemented in**:")
158
- for file_path, line_num in req.implementation_files:
159
- # Create markdown link to file with line number anchor
160
- link = f"[{file_path}:{line_num}]({base_path}{file_path}#L{line_num})"
161
- lines.append(f"{prefix} - {link}")
162
-
163
- # Find and format children
164
- children = [r for r in requirements.values() if req.id in r.implements]
165
- children.sort(key=lambda r: r.id)
166
-
167
- if children:
168
- # Add current req to path before recursing into children
169
- current_path = ancestor_path + [req.id]
170
- for child in children:
171
- lines.append(
172
- format_req_tree_md(child, requirements, indent + 1, current_path, base_path)
173
- )
174
-
175
- return "\n".join(lines)
@@ -1,31 +0,0 @@
1
- # Implements: REQ-int-d00002-B (HTML generation requires jinja2)
2
- """
3
- elspais.trace_view.html - Interactive HTML generation.
4
-
5
- Requires: pip install elspais[trace-view]
6
- """
7
-
8
- def _check_jinja2():
9
- try:
10
- import jinja2 # noqa: F401
11
- return True
12
- except ImportError:
13
- return False
14
-
15
-
16
- JINJA2_AVAILABLE = _check_jinja2()
17
-
18
- if JINJA2_AVAILABLE:
19
- from elspais.trace_view.html.generator import HTMLGenerator
20
- __all__ = ["HTMLGenerator", "JINJA2_AVAILABLE"]
21
- else:
22
- __all__ = ["JINJA2_AVAILABLE"]
23
-
24
- class HTMLGenerator:
25
- """Placeholder when jinja2 is not installed."""
26
-
27
- def __init__(self, *args, **kwargs):
28
- raise ImportError(
29
- "HTMLGenerator requires Jinja2. "
30
- "Install with: pip install elspais[trace-view]"
31
- )