elspais 0.11.2__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 (147) hide show
  1. elspais/__init__.py +1 -10
  2. elspais/{sponsors/__init__.py → associates.py} +102 -56
  3. elspais/cli.py +366 -69
  4. elspais/commands/__init__.py +9 -3
  5. elspais/commands/analyze.py +118 -169
  6. elspais/commands/changed.py +12 -23
  7. elspais/commands/config_cmd.py +10 -13
  8. elspais/commands/edit.py +33 -13
  9. elspais/commands/example_cmd.py +319 -0
  10. elspais/commands/hash_cmd.py +161 -183
  11. elspais/commands/health.py +1177 -0
  12. elspais/commands/index.py +98 -115
  13. elspais/commands/init.py +99 -22
  14. elspais/commands/reformat_cmd.py +41 -433
  15. elspais/commands/rules_cmd.py +2 -2
  16. elspais/commands/trace.py +443 -324
  17. elspais/commands/validate.py +193 -411
  18. elspais/config/__init__.py +799 -5
  19. elspais/{core/content_rules.py → content_rules.py} +20 -2
  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 +45 -29
  58. elspais/mcp/__main__.py +5 -1
  59. elspais/mcp/file_mutations.py +138 -0
  60. elspais/mcp/server.py +1998 -244
  61. elspais/testing/__init__.py +3 -3
  62. elspais/testing/config.py +3 -0
  63. elspais/testing/mapper.py +1 -1
  64. elspais/testing/scanner.py +301 -12
  65. elspais/utilities/__init__.py +1 -0
  66. elspais/utilities/docs_loader.py +115 -0
  67. elspais/utilities/git.py +607 -0
  68. elspais/{core → utilities}/hasher.py +8 -22
  69. elspais/utilities/md_renderer.py +189 -0
  70. elspais/{core → utilities}/patterns.py +56 -51
  71. elspais/utilities/reference_config.py +626 -0
  72. elspais/validation/__init__.py +19 -0
  73. elspais/validation/format.py +264 -0
  74. {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/METADATA +7 -4
  75. elspais-0.43.5.dist-info/RECORD +80 -0
  76. elspais/config/defaults.py +0 -179
  77. elspais/config/loader.py +0 -494
  78. elspais/core/__init__.py +0 -21
  79. elspais/core/git.py +0 -346
  80. elspais/core/models.py +0 -320
  81. elspais/core/parser.py +0 -639
  82. elspais/core/rules.py +0 -509
  83. elspais/mcp/context.py +0 -172
  84. elspais/mcp/serializers.py +0 -112
  85. elspais/reformat/__init__.py +0 -50
  86. elspais/reformat/detector.py +0 -112
  87. elspais/reformat/hierarchy.py +0 -247
  88. elspais/reformat/line_breaks.py +0 -218
  89. elspais/reformat/prompts.py +0 -133
  90. elspais/reformat/transformer.py +0 -266
  91. elspais/trace_view/__init__.py +0 -55
  92. elspais/trace_view/coverage.py +0 -183
  93. elspais/trace_view/generators/__init__.py +0 -12
  94. elspais/trace_view/generators/base.py +0 -334
  95. elspais/trace_view/generators/csv.py +0 -118
  96. elspais/trace_view/generators/markdown.py +0 -170
  97. elspais/trace_view/html/__init__.py +0 -33
  98. elspais/trace_view/html/generator.py +0 -1140
  99. elspais/trace_view/html/templates/base.html +0 -283
  100. elspais/trace_view/html/templates/components/code_viewer_modal.html +0 -14
  101. elspais/trace_view/html/templates/components/file_picker_modal.html +0 -20
  102. elspais/trace_view/html/templates/components/legend_modal.html +0 -69
  103. elspais/trace_view/html/templates/components/review_panel.html +0 -118
  104. elspais/trace_view/html/templates/partials/review/help/help-panel.json +0 -244
  105. elspais/trace_view/html/templates/partials/review/help/onboarding.json +0 -77
  106. elspais/trace_view/html/templates/partials/review/help/tooltips.json +0 -237
  107. elspais/trace_view/html/templates/partials/review/review-comments.js +0 -928
  108. elspais/trace_view/html/templates/partials/review/review-data.js +0 -961
  109. elspais/trace_view/html/templates/partials/review/review-help.js +0 -679
  110. elspais/trace_view/html/templates/partials/review/review-init.js +0 -177
  111. elspais/trace_view/html/templates/partials/review/review-line-numbers.js +0 -429
  112. elspais/trace_view/html/templates/partials/review/review-packages.js +0 -1029
  113. elspais/trace_view/html/templates/partials/review/review-position.js +0 -540
  114. elspais/trace_view/html/templates/partials/review/review-resize.js +0 -115
  115. elspais/trace_view/html/templates/partials/review/review-status.js +0 -659
  116. elspais/trace_view/html/templates/partials/review/review-sync.js +0 -992
  117. elspais/trace_view/html/templates/partials/review-styles.css +0 -2238
  118. elspais/trace_view/html/templates/partials/scripts.js +0 -1741
  119. elspais/trace_view/html/templates/partials/styles.css +0 -1756
  120. elspais/trace_view/models.py +0 -378
  121. elspais/trace_view/review/__init__.py +0 -63
  122. elspais/trace_view/review/branches.py +0 -1142
  123. elspais/trace_view/review/models.py +0 -1200
  124. elspais/trace_view/review/position.py +0 -591
  125. elspais/trace_view/review/server.py +0 -1032
  126. elspais/trace_view/review/status.py +0 -455
  127. elspais/trace_view/review/storage.py +0 -1343
  128. elspais/trace_view/scanning.py +0 -213
  129. elspais/trace_view/specs/README.md +0 -84
  130. elspais/trace_view/specs/tv-d00001-template-architecture.md +0 -36
  131. elspais/trace_view/specs/tv-d00002-css-extraction.md +0 -37
  132. elspais/trace_view/specs/tv-d00003-js-extraction.md +0 -43
  133. elspais/trace_view/specs/tv-d00004-build-embedding.md +0 -40
  134. elspais/trace_view/specs/tv-d00005-test-format.md +0 -78
  135. elspais/trace_view/specs/tv-d00010-review-data-models.md +0 -33
  136. elspais/trace_view/specs/tv-d00011-review-storage.md +0 -33
  137. elspais/trace_view/specs/tv-d00012-position-resolution.md +0 -33
  138. elspais/trace_view/specs/tv-d00013-git-branches.md +0 -31
  139. elspais/trace_view/specs/tv-d00014-review-api-server.md +0 -31
  140. elspais/trace_view/specs/tv-d00015-status-modifier.md +0 -27
  141. elspais/trace_view/specs/tv-d00016-js-integration.md +0 -33
  142. elspais/trace_view/specs/tv-p00001-html-generator.md +0 -33
  143. elspais/trace_view/specs/tv-p00002-review-system.md +0 -29
  144. elspais-0.11.2.dist-info/RECORD +0 -101
  145. {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/WHEEL +0 -0
  146. {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/entry_points.txt +0 -0
  147. {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,319 @@
1
+ """
2
+ elspais.commands.example_cmd - Display requirement format examples.
3
+
4
+ Quick reference command for requirement format discovery.
5
+ """
6
+
7
+ import argparse
8
+ from pathlib import Path
9
+
10
+ # ============================================================================
11
+ # Requirement Format Templates
12
+ # ============================================================================
13
+
14
+ REQUIREMENT_TEMPLATE = """# REQ-{type}{id}: Requirement Title
15
+
16
+ **Level**: {level} | **Status**: Draft | **Implements**: {implements}
17
+
18
+ ## Assertions
19
+
20
+ A. The system SHALL <do something specific>.
21
+ B. The system SHALL <do another thing>.
22
+
23
+ ## Rationale
24
+
25
+ <optional non-normative explanation>
26
+
27
+ *End* *Requirement Title* | **Hash**: 00000000
28
+
29
+ ---
30
+ Level codes: p = PRD (Product), o = OPS (Operations), d = DEV (Development)
31
+ Implements: Use "-" for top-level requirements, or REQ-pXXXXX for children
32
+ Hash: Run `elspais hash update` to compute automatically
33
+ """
34
+
35
+ REQUIREMENT_TEMPLATE_PRD = REQUIREMENT_TEMPLATE.format(
36
+ type="p", id="00001", level="PRD", implements="-"
37
+ )
38
+
39
+ REQUIREMENT_TEMPLATE_OPS = REQUIREMENT_TEMPLATE.format(
40
+ type="o", id="00001", level="Ops", implements="REQ-p00001"
41
+ )
42
+
43
+ REQUIREMENT_TEMPLATE_DEV = REQUIREMENT_TEMPLATE.format(
44
+ type="d", id="00001", level="Dev", implements="REQ-o00001"
45
+ )
46
+
47
+ JOURNEY_TEMPLATE = """# JNY-{prefix}-01: User Journey Title
48
+
49
+ **Actor**: End User
50
+ **Goal**: <what the user wants to accomplish>
51
+
52
+ ## Steps
53
+
54
+ 1. User <does something>
55
+ 2. System <responds with something>
56
+ 3. User <completes action>
57
+
58
+ ## Requirements
59
+
60
+ - REQ-p00001: <requirement title>
61
+ - REQ-p00002: <requirement title>
62
+
63
+ *End* *User Journey Title*
64
+
65
+ ---
66
+ Journey prefix: Use meaningful 2-4 char codes (e.g., AUTH, PAY, ONBD)
67
+ Steps: Describe the happy path interaction
68
+ Requirements: Link to PRD requirements this journey validates
69
+ """
70
+
71
+ ASSERTION_RULES = """# Assertion Format Rules
72
+
73
+ ## Basic Format
74
+ Each assertion is a labeled statement using SHALL language:
75
+
76
+ A. The system SHALL <do something specific>.
77
+ B. The system SHALL <do another thing>.
78
+
79
+ ## Label Styles (configurable)
80
+ - uppercase: A, B, C ... Z (default, max 26)
81
+ - numeric: 1, 2, 3 ... or 01, 02, 03 ...
82
+ - alphanumeric: 0-9, A-Z (max 36)
83
+
84
+ ## Keywords
85
+ - SHALL: Required functionality (normative)
86
+ - SHOULD: Recommended but not required
87
+ - MAY: Optional functionality
88
+
89
+ ## Placeholders for Removed Assertions
90
+ When an assertion is removed, use a placeholder to maintain sequential labels:
91
+
92
+ A. The system SHALL validate user input.
93
+ B. Removed.
94
+ C. The system SHALL log all transactions.
95
+
96
+ Valid placeholder values: "Removed", "obsolete", "deprecated", "N/A", "-", "reserved"
97
+
98
+ ## Test References
99
+ Tests can reference specific assertions:
100
+
101
+ # test_auth.py
102
+ def test_user_validation():
103
+ \"\"\"Test REQ-d00001-A assertion.\"\"\"
104
+ ...
105
+
106
+ ## Configuration
107
+
108
+ ```toml
109
+ [patterns.assertions]
110
+ label_style = "uppercase" # "uppercase", "numeric", "alphanumeric"
111
+ max_count = 26
112
+
113
+ [rules.format]
114
+ require_assertions = true
115
+ require_shall = true
116
+ labels_sequential = true
117
+ ```
118
+ """
119
+
120
+ ID_PATTERNS_TEMPLATE = """# Requirement ID Patterns
121
+
122
+ ## Current Configuration
123
+
124
+ The ID pattern is built from these components:
125
+ prefix = {prefix}
126
+ id_template = {id_template}
127
+
128
+ ## Standard ID Formats
129
+
130
+ **Core repository:**
131
+ PRD: {prefix}-p00001
132
+ OPS: {prefix}-o00001
133
+ DEV: {prefix}-d00001
134
+
135
+ **With assertion reference:**
136
+ {prefix}-d00001-A (assertion A of DEV requirement)
137
+
138
+ **Associated repository (if enabled):**
139
+ TTN-{prefix}-p00001 (prefixed with associated code)
140
+
141
+ ## Type Levels
142
+
143
+ {types}
144
+
145
+ ## Examples in this project
146
+
147
+ {prefix}-p00001: PRD requirement (Product, Level 1)
148
+ {prefix}-o00001: OPS requirement (Operations, Level 2)
149
+ {prefix}-d00001: DEV requirement (Development, Level 3)
150
+
151
+ Run `elspais config show --section patterns` for full pattern configuration.
152
+ """
153
+
154
+ DEFAULT_TEMPLATE = """# Requirement Format Quick Reference
155
+
156
+ Use `elspais example <type>` for detailed templates:
157
+
158
+ elspais example requirement Show full requirement template
159
+ elspais example journey Show user journey template
160
+ elspais example assertion Show assertion rules and examples
161
+ elspais example ids Show ID patterns from your config
162
+ elspais example --full Display spec/requirements-spec.md
163
+
164
+ ## Basic Requirement Structure
165
+
166
+ ```markdown
167
+ # REQ-d00001: Title
168
+
169
+ **Level**: Dev | **Status**: Draft | **Implements**: REQ-o00001
170
+
171
+ ## Assertions
172
+
173
+ A. The system SHALL <do something>.
174
+
175
+ ## Rationale
176
+
177
+ <optional explanation>
178
+
179
+ *End* *Title* | **Hash**: 00000000
180
+ ```
181
+
182
+ ## Key Rules
183
+
184
+ 1. **Assertions** - Use SHALL for required behavior
185
+ 2. **Implements** - Children reference parents (dev -> ops -> prd)
186
+ 3. **Hash** - Auto-computed with `elspais hash update`
187
+ 4. **Sequential labels** - A, B, C... don't skip letters
188
+
189
+ Run `elspais validate` to check format compliance.
190
+ """
191
+
192
+
193
+ def run(args: argparse.Namespace) -> int:
194
+ """
195
+ Run the example command.
196
+
197
+ Args:
198
+ args: Parsed command line arguments
199
+
200
+ Returns:
201
+ Exit code (0 for success)
202
+ """
203
+ # Handle --full flag first
204
+ if args.full:
205
+ return show_full_spec(args)
206
+
207
+ # Handle subcommand
208
+ subcommand = args.example_type
209
+
210
+ if subcommand == "requirement":
211
+ return show_requirement_template(args)
212
+ elif subcommand == "journey":
213
+ return show_journey_template(args)
214
+ elif subcommand == "assertion":
215
+ return show_assertion_rules(args)
216
+ elif subcommand == "ids":
217
+ return show_id_patterns(args)
218
+ else:
219
+ # Default: show quick reference
220
+ print(DEFAULT_TEMPLATE)
221
+ return 0
222
+
223
+
224
+ def show_requirement_template(args: argparse.Namespace) -> int:
225
+ """Show requirement template."""
226
+ print("# Requirement Templates\n")
227
+ print("## PRD (Product Requirement)")
228
+ print(REQUIREMENT_TEMPLATE_PRD)
229
+ print("\n## OPS (Operations Requirement)")
230
+ print(REQUIREMENT_TEMPLATE_OPS)
231
+ print("\n## DEV (Development Requirement)")
232
+ print(REQUIREMENT_TEMPLATE_DEV)
233
+ return 0
234
+
235
+
236
+ def show_journey_template(args: argparse.Namespace) -> int:
237
+ """Show user journey template."""
238
+ print(JOURNEY_TEMPLATE)
239
+ return 0
240
+
241
+
242
+ def show_assertion_rules(args: argparse.Namespace) -> int:
243
+ """Show assertion format rules."""
244
+ print(ASSERTION_RULES)
245
+ return 0
246
+
247
+
248
+ def show_id_patterns(args: argparse.Namespace) -> int:
249
+ """Show ID patterns from current configuration."""
250
+ from elspais.config import load_config
251
+
252
+ try:
253
+ config = load_config(args.config if hasattr(args, "config") else None)
254
+ except Exception:
255
+ # Use defaults if no config found
256
+ config = {
257
+ "patterns": {
258
+ "prefix": "REQ",
259
+ "id_template": "{prefix}-{type}{id}",
260
+ "types": {
261
+ "prd": {"id": "p", "name": "Product Requirement", "level": 1},
262
+ "ops": {"id": "o", "name": "Operations Requirement", "level": 2},
263
+ "dev": {"id": "d", "name": "Development Requirement", "level": 3},
264
+ },
265
+ }
266
+ }
267
+
268
+ patterns = config.get("patterns", {})
269
+ prefix = patterns.get("prefix", "REQ")
270
+ id_template = patterns.get("id_template", "{prefix}-{type}{id}")
271
+ types = patterns.get("types", {})
272
+
273
+ # Format types section
274
+ types_text = ""
275
+ for type_key, type_info in types.items():
276
+ if isinstance(type_info, dict):
277
+ type_id = type_info.get("id", type_key[0])
278
+ type_name = type_info.get("name", type_key.upper())
279
+ type_level = type_info.get("level", "?")
280
+ types_text += f" {type_key.upper()}: {type_id} = Level {type_level} ({type_name})\n"
281
+
282
+ output = ID_PATTERNS_TEMPLATE.format(
283
+ prefix=prefix,
284
+ id_template=id_template,
285
+ types=types_text.strip() if types_text else " (no types configured)",
286
+ )
287
+ print(output)
288
+ return 0
289
+
290
+
291
+ def show_full_spec(args: argparse.Namespace) -> int:
292
+ """Display the full requirements-spec.md if it exists."""
293
+ from elspais.config import load_config
294
+
295
+ try:
296
+ config = load_config(args.config if hasattr(args, "config") else None)
297
+ except Exception:
298
+ config = {"directories": {"spec": "spec"}}
299
+
300
+ spec_dir = config.get("directories", {}).get("spec", "spec")
301
+ spec_path = Path.cwd() / spec_dir / "requirements-spec.md"
302
+
303
+ # Also check for requirements-format.md (alternative name)
304
+ alt_path = Path.cwd() / spec_dir / "requirements-format.md"
305
+
306
+ if spec_path.exists():
307
+ print(spec_path.read_text())
308
+ return 0
309
+ elif alt_path.exists():
310
+ print(alt_path.read_text())
311
+ return 0
312
+ else:
313
+ print("No requirements specification found.")
314
+ print("Searched:")
315
+ print(f" - {spec_path}")
316
+ print(f" - {alt_path}")
317
+ print()
318
+ print("Use `elspais format requirement` for a template instead.")
319
+ return 1