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
@@ -0,0 +1,216 @@
1
+ """Graph Serialization - Export TraceGraph to various formats.
2
+
3
+ This module provides functions to serialize TraceGraph and GraphNode
4
+ to JSON-compatible dicts, markdown, and CSV formats.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import csv
10
+ import io
11
+ from typing import TYPE_CHECKING, Any
12
+
13
+ if TYPE_CHECKING:
14
+ from elspais.graph.builder import TraceGraph
15
+ from elspais.graph.GraphNode import GraphNode
16
+
17
+
18
+ def serialize_node(node: GraphNode) -> dict[str, Any]:
19
+ """Serialize a GraphNode to a JSON-compatible dict.
20
+
21
+ Args:
22
+ node: The node to serialize.
23
+
24
+ Returns:
25
+ Dict suitable for JSON serialization.
26
+ """
27
+
28
+ result: dict[str, Any] = {
29
+ "id": node.id,
30
+ "kind": node.kind.name,
31
+ "label": node.get_label(),
32
+ "uuid": node.uuid,
33
+ "content": node.get_all_content(),
34
+ }
35
+
36
+ # Include source location if present
37
+ if node.source:
38
+ result["source"] = {
39
+ "path": node.source.path,
40
+ "line": node.source.line,
41
+ "end_line": node.source.end_line,
42
+ }
43
+ if node.source.repo:
44
+ result["source"]["repo"] = node.source.repo
45
+
46
+ # Include child IDs
47
+ children = list(node.iter_children())
48
+ if children:
49
+ result["children"] = [child.id for child in children]
50
+
51
+ # Include parent IDs
52
+ parents = list(node.iter_parents())
53
+ if parents:
54
+ result["parents"] = [parent.id for parent in parents]
55
+
56
+ # Include metrics
57
+ if node._metrics:
58
+ result["metrics"] = dict(node._metrics)
59
+
60
+ # Include outgoing edges
61
+ edges = list(node.iter_outgoing_edges())
62
+ if edges:
63
+ result["edges"] = [
64
+ {
65
+ "target": edge.target.id,
66
+ "kind": edge.kind.name,
67
+ }
68
+ for edge in edges
69
+ ]
70
+
71
+ return result
72
+
73
+
74
+ def serialize_graph(graph: TraceGraph) -> dict[str, Any]:
75
+ """Serialize a TraceGraph to a JSON-compatible dict.
76
+
77
+ Args:
78
+ graph: The graph to serialize.
79
+
80
+ Returns:
81
+ Dict with nodes, roots, and metadata.
82
+ """
83
+
84
+ # Serialize all nodes and count by kind in single pass
85
+ nodes = {}
86
+ kind_counts: dict[str, int] = {}
87
+ for node in graph.all_nodes():
88
+ nodes[node.id] = serialize_node(node)
89
+ kind_name = node.kind.name
90
+ kind_counts[kind_name] = kind_counts.get(kind_name, 0) + 1
91
+
92
+ roots = list(graph.iter_roots())
93
+ return {
94
+ "nodes": nodes,
95
+ "roots": [root.id for root in roots],
96
+ "metadata": {
97
+ "node_count": len(nodes),
98
+ "root_count": len(roots),
99
+ "repo_root": str(graph.repo_root),
100
+ "by_kind": kind_counts,
101
+ },
102
+ }
103
+
104
+
105
+ def to_markdown(graph: TraceGraph) -> str:
106
+ """Generate a markdown traceability matrix from graph.
107
+
108
+ Args:
109
+ graph: The TraceGraph to render.
110
+
111
+ Returns:
112
+ Markdown string with traceability matrix.
113
+ """
114
+ from elspais.graph import NodeKind
115
+
116
+ lines = [
117
+ "# Traceability Matrix",
118
+ "",
119
+ "| ID | Level | Title | Status | Implements |",
120
+ "|-----|-------|-------|--------|------------|",
121
+ ]
122
+
123
+ # Get requirements only
124
+ requirements = list(graph.nodes_by_kind(NodeKind.REQUIREMENT))
125
+
126
+ # Sort by ID
127
+ requirements.sort(key=lambda n: n.id)
128
+
129
+ for node in requirements:
130
+ req_id = node.id
131
+ level = node.get_field("level", "")
132
+ title = node.get_label() or ""
133
+ status = node.get_field("status", "")
134
+
135
+ # Get implements from incoming edges (what this node implements)
136
+ implements = []
137
+ for edge in node.iter_incoming_edges():
138
+ from elspais.graph.relations import EdgeKind
139
+
140
+ if edge.kind == EdgeKind.IMPLEMENTS:
141
+ implements.append(edge.source.id)
142
+
143
+ implements_str = ", ".join(implements) if implements else "-"
144
+
145
+ lines.append(f"| {req_id} | {level} | {title} | {status} | {implements_str} |")
146
+
147
+ lines.append("")
148
+ return "\n".join(lines)
149
+
150
+
151
+ def to_csv(graph: TraceGraph) -> str:
152
+ """Generate a CSV export from graph.
153
+
154
+ Args:
155
+ graph: The TraceGraph to export.
156
+
157
+ Returns:
158
+ CSV string with requirement data.
159
+ """
160
+ from elspais.graph import NodeKind
161
+
162
+ output = io.StringIO()
163
+ writer = csv.writer(output, quoting=csv.QUOTE_MINIMAL)
164
+
165
+ # Header
166
+ writer.writerow(
167
+ [
168
+ "id",
169
+ "level",
170
+ "label",
171
+ "status",
172
+ "file_path",
173
+ "line",
174
+ "hash",
175
+ "implements",
176
+ ]
177
+ )
178
+
179
+ # Get requirements only
180
+ requirements = list(graph.nodes_by_kind(NodeKind.REQUIREMENT))
181
+ requirements.sort(key=lambda n: n.id)
182
+
183
+ for node in requirements:
184
+ file_path = node.source.path if node.source else ""
185
+ line = node.source.line if node.source else ""
186
+
187
+ # Get implements from incoming edges (what this node implements)
188
+ implements = []
189
+ for edge in node.iter_incoming_edges():
190
+ from elspais.graph.relations import EdgeKind
191
+
192
+ if edge.kind == EdgeKind.IMPLEMENTS:
193
+ implements.append(edge.source.id)
194
+
195
+ writer.writerow(
196
+ [
197
+ node.id,
198
+ node.get_field("level", ""),
199
+ node.get_label(),
200
+ node.get_field("status", ""),
201
+ file_path,
202
+ line,
203
+ node.get_field("hash", ""),
204
+ "; ".join(implements),
205
+ ]
206
+ )
207
+
208
+ return output.getvalue()
209
+
210
+
211
+ __all__ = [
212
+ "serialize_node",
213
+ "serialize_graph",
214
+ "to_markdown",
215
+ "to_csv",
216
+ ]
@@ -0,0 +1,8 @@
1
+ """HTML Generation module for traceability reports.
2
+
3
+ This module provides HTML generation for interactive traceability matrices.
4
+ """
5
+
6
+ from elspais.html.generator import HTMLGenerator
7
+
8
+ __all__ = ["HTMLGenerator"]