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
elspais/__init__.py CHANGED
@@ -10,7 +10,7 @@ and supports multi-repository requirement management with configurable
10
10
  ID patterns and validation rules.
11
11
  """
12
12
 
13
- from importlib.metadata import version, PackageNotFoundError
13
+ from importlib.metadata import PackageNotFoundError, version
14
14
 
15
15
  try:
16
16
  __version__ = version("elspais")
@@ -19,18 +19,9 @@ except PackageNotFoundError:
19
19
  __author__ = "Anspar"
20
20
  __license__ = "MIT"
21
21
 
22
- from elspais.core.models import Assertion, ContentRule, ParsedRequirement, Requirement
23
- from elspais.core.patterns import PatternValidator
24
- from elspais.core.rules import RuleEngine, RuleViolation, Severity
22
+ from elspais.utilities.patterns import PatternValidator
25
23
 
26
24
  __all__ = [
27
25
  "__version__",
28
- "Assertion",
29
- "ContentRule",
30
- "Requirement",
31
- "ParsedRequirement",
32
26
  "PatternValidator",
33
- "RuleEngine",
34
- "RuleViolation",
35
- "Severity",
36
27
  ]
@@ -1,8 +1,8 @@
1
1
  """
2
- elspais.sponsors - Sponsor/associated repository configuration loading.
2
+ elspais.associates - Associate repository configuration loading.
3
3
 
4
- Provides functions for loading sponsor configurations from YAML files
5
- and resolving sponsor spec directories.
4
+ Provides functions for loading associate configurations from YAML files
5
+ and resolving associate spec directories.
6
6
  """
7
7
 
8
8
  import re
@@ -12,16 +12,16 @@ from typing import Any, Dict, List, Optional
12
12
 
13
13
 
14
14
  @dataclass
15
- class Sponsor:
15
+ class Associate:
16
16
  """
17
- Represents a sponsor/associated repository configuration.
17
+ Represents an associate repository configuration.
18
18
 
19
19
  Attributes:
20
- name: Sponsor name (e.g., "callisto")
20
+ name: Associate name (e.g., "callisto")
21
21
  code: Short code used in requirement IDs (e.g., "CAL")
22
- enabled: Whether this sponsor is enabled for scanning
22
+ enabled: Whether this associate is enabled for scanning
23
23
  path: Default path relative to project root
24
- spec_path: Spec directory within sponsor path (e.g., "spec")
24
+ spec_path: Spec directory within associate path (e.g., "spec")
25
25
  local_path: Override path for local development (from .local.yml)
26
26
  """
27
27
 
@@ -33,21 +33,34 @@ class Sponsor:
33
33
  local_path: Optional[str] = None
34
34
 
35
35
 
36
+ # Alias for backwards compatibility
37
+ Sponsor = Associate
38
+
39
+
36
40
  @dataclass
37
- class SponsorsConfig:
41
+ class AssociatesConfig:
38
42
  """
39
- Container for sponsor configuration.
43
+ Container for associate configuration.
40
44
 
41
45
  Attributes:
42
- sponsors: List of Sponsor objects
43
- config_file: Path to the sponsors config file
44
- local_dir: Default base directory for sponsor repos
46
+ associates: List of Associate objects
47
+ config_file: Path to the associates config file
48
+ local_dir: Default base directory for associate repos
45
49
  """
46
50
 
47
- sponsors: List[Sponsor] = field(default_factory=list)
51
+ associates: List[Associate] = field(default_factory=list)
48
52
  config_file: str = ""
49
53
  local_dir: str = "sponsor"
50
54
 
55
+ # Alias property for backwards compatibility
56
+ @property
57
+ def sponsors(self) -> List[Associate]:
58
+ return self.associates
59
+
60
+
61
+ # Alias for backwards compatibility
62
+ SponsorsConfig = AssociatesConfig
63
+
51
64
 
52
65
  def parse_yaml(content: str) -> Dict[str, Any]:
53
66
  """
@@ -69,8 +82,6 @@ def parse_yaml(content: str) -> Dict[str, Any]:
69
82
  current_key: Optional[str] = None
70
83
  current_list: Optional[List[Dict]] = None
71
84
  current_dict: Optional[Dict[str, Any]] = None
72
- list_key: Optional[str] = None
73
- indent_stack: List[tuple] = [] # (indent_level, container)
74
85
 
75
86
  lines = content.split("\n")
76
87
 
@@ -158,9 +169,9 @@ def _parse_yaml_value(value: str) -> Any:
158
169
  return value
159
170
 
160
171
 
161
- def load_sponsors_yaml(yaml_path: Path) -> Dict[str, Any]:
172
+ def load_associates_yaml(yaml_path: Path) -> Dict[str, Any]:
162
173
  """
163
- Load sponsors configuration from a YAML file.
174
+ Load associates configuration from a YAML file.
164
175
 
165
176
  Handles the nested structure:
166
177
  ```yaml
@@ -174,27 +185,31 @@ def load_sponsors_yaml(yaml_path: Path) -> Dict[str, Any]:
174
185
  ```
175
186
 
176
187
  Args:
177
- yaml_path: Path to the sponsors YAML file
188
+ yaml_path: Path to the associates YAML file
178
189
 
179
190
  Returns:
180
- Dictionary with sponsor configuration
191
+ Dictionary with associate configuration
181
192
  """
182
193
  if not yaml_path.exists():
183
194
  return {}
184
195
 
185
196
  content = yaml_path.read_text(encoding="utf-8")
186
- return _parse_sponsors_yaml(content)
197
+ return _parse_associates_yaml(content)
198
+
199
+
200
+ # Alias for backwards compatibility
201
+ load_sponsors_yaml = load_associates_yaml
187
202
 
188
203
 
189
- def _parse_sponsors_yaml(content: str) -> Dict[str, Any]:
204
+ def _parse_associates_yaml(content: str) -> Dict[str, Any]:
190
205
  """
191
- Parse sponsors YAML content with proper handling of nested lists.
206
+ Parse associates YAML content with proper handling of nested lists.
192
207
 
193
208
  Args:
194
209
  content: YAML file content
195
210
 
196
211
  Returns:
197
- Parsed dictionary with sponsors configuration
212
+ Parsed dictionary with associates configuration
198
213
  """
199
214
  result: Dict[str, Any] = {"sponsors": {}}
200
215
  current_section = None
@@ -282,43 +297,43 @@ def _parse_sponsors_yaml(content: str) -> Dict[str, Any]:
282
297
  return result
283
298
 
284
299
 
285
- def load_sponsors_config(
300
+ def load_associates_config(
286
301
  config: Dict[str, Any],
287
302
  base_path: Optional[Path] = None,
288
- ) -> SponsorsConfig:
303
+ ) -> AssociatesConfig:
289
304
  """
290
- Load sponsor configurations from config files.
305
+ Load associate configurations from config files.
291
306
 
292
- Reads the main sponsors config file and applies local overrides.
307
+ Reads the main associates config file and applies local overrides.
293
308
 
294
309
  Args:
295
310
  config: Main elspais configuration dictionary
296
311
  base_path: Base path to resolve relative paths (defaults to cwd)
297
312
 
298
313
  Returns:
299
- SponsorsConfig with loaded sponsors
314
+ AssociatesConfig with loaded associates
300
315
  """
301
316
  if base_path is None:
302
317
  base_path = Path.cwd()
303
318
 
304
- sponsors_config = SponsorsConfig()
319
+ associates_config = AssociatesConfig()
305
320
 
306
- # Get sponsors section from config
321
+ # Get sponsors section from config (keeping "sponsors" key for compatibility)
307
322
  sponsors_section = config.get("sponsors", {})
308
323
  config_file = sponsors_section.get("config_file", "")
309
- sponsors_config.config_file = config_file
310
- sponsors_config.local_dir = sponsors_section.get("local_dir", "sponsor")
324
+ associates_config.config_file = config_file
325
+ associates_config.local_dir = sponsors_section.get("local_dir", "sponsor")
311
326
 
312
327
  if not config_file:
313
- return sponsors_config
328
+ return associates_config
314
329
 
315
330
  # Load main sponsors config
316
331
  config_path = base_path / config_file
317
- main_config = load_sponsors_yaml(config_path)
332
+ main_config = load_associates_yaml(config_path)
318
333
 
319
334
  # Load local overrides if present
320
335
  local_config_path = config_path.with_suffix(".local.yml")
321
- local_overrides = load_sponsors_yaml(local_config_path)
336
+ local_overrides = load_associates_yaml(local_config_path)
322
337
 
323
338
  # Parse sponsors from config
324
339
  sponsors_data = main_config.get("sponsors", {})
@@ -345,7 +360,7 @@ def load_sponsors_config(
345
360
  if isinstance(local_override, dict):
346
361
  local_path = local_override.get("local_path")
347
362
 
348
- sponsor = Sponsor(
363
+ associate = Associate(
349
364
  name=name,
350
365
  code=sponsor_data.get("code", ""),
351
366
  enabled=sponsor_data.get("enabled", True),
@@ -353,80 +368,109 @@ def load_sponsors_config(
353
368
  spec_path=sponsor_data.get("spec_path", "spec"),
354
369
  local_path=local_path,
355
370
  )
356
- sponsors_config.sponsors.append(sponsor)
371
+ associates_config.associates.append(associate)
357
372
 
358
- return sponsors_config
373
+ return associates_config
359
374
 
360
375
 
361
- def resolve_sponsor_spec_dir(
362
- sponsor: Sponsor,
363
- config: SponsorsConfig,
376
+ # Alias for backwards compatibility
377
+ load_sponsors_config = load_associates_config
378
+
379
+
380
+ def resolve_associate_spec_dir(
381
+ associate: Associate,
382
+ config: AssociatesConfig,
364
383
  base_path: Optional[Path] = None,
365
384
  ) -> Optional[Path]:
366
385
  """
367
- Resolve the spec directory path for a sponsor.
386
+ Resolve the spec directory path for an associate.
368
387
 
369
388
  Checks local_path override first, then default path.
370
389
 
371
390
  Args:
372
- sponsor: Sponsor configuration
373
- config: Overall sponsors configuration
391
+ associate: Associate configuration
392
+ config: Overall associates configuration
374
393
  base_path: Base path to resolve relative paths (defaults to cwd)
375
394
 
376
395
  Returns:
377
- Path to sponsor spec directory, or None if not found
396
+ Path to associate spec directory, or None if not found
378
397
  """
379
398
  if base_path is None:
380
399
  base_path = Path.cwd()
381
400
 
382
- if not sponsor.enabled:
401
+ if not associate.enabled:
383
402
  return None
384
403
 
385
404
  # Check local_path override first
386
- if sponsor.local_path:
387
- spec_dir = Path(sponsor.local_path) / sponsor.spec_path
405
+ if associate.local_path:
406
+ spec_dir = Path(associate.local_path) / associate.spec_path
388
407
  if not spec_dir.is_absolute():
389
408
  spec_dir = base_path / spec_dir
390
409
  if spec_dir.exists() and spec_dir.is_dir():
391
410
  return spec_dir
392
411
 
393
412
  # Fall back to default path
394
- if sponsor.path:
395
- spec_dir = base_path / sponsor.path / sponsor.spec_path
413
+ if associate.path:
414
+ spec_dir = base_path / associate.path / associate.spec_path
396
415
  if spec_dir.exists() and spec_dir.is_dir():
397
416
  return spec_dir
398
417
 
399
418
  # Try local_dir / name / spec_path
400
- spec_dir = base_path / config.local_dir / sponsor.name / sponsor.spec_path
419
+ spec_dir = base_path / config.local_dir / associate.name / associate.spec_path
401
420
  if spec_dir.exists() and spec_dir.is_dir():
402
421
  return spec_dir
403
422
 
404
423
  return None
405
424
 
406
425
 
407
- def get_sponsor_spec_directories(
426
+ # Alias for backwards compatibility
427
+ resolve_sponsor_spec_dir = resolve_associate_spec_dir
428
+
429
+
430
+ def get_associate_spec_directories(
408
431
  config: Dict[str, Any],
409
432
  base_path: Optional[Path] = None,
410
433
  ) -> List[Path]:
411
434
  """
412
- Get all sponsor spec directories from configuration.
435
+ Get all associate spec directories from configuration.
413
436
 
414
437
  Args:
415
438
  config: Main elspais configuration dictionary
416
439
  base_path: Base path to resolve relative paths (defaults to cwd)
417
440
 
418
441
  Returns:
419
- List of existing sponsor spec directory paths
442
+ List of existing associate spec directory paths
420
443
  """
421
444
  if base_path is None:
422
445
  base_path = Path.cwd()
423
446
 
424
- sponsors_config = load_sponsors_config(config, base_path)
447
+ associates_config = load_associates_config(config, base_path)
425
448
  spec_dirs = []
426
449
 
427
- for sponsor in sponsors_config.sponsors:
428
- spec_dir = resolve_sponsor_spec_dir(sponsor, sponsors_config, base_path)
450
+ for associate in associates_config.associates:
451
+ spec_dir = resolve_associate_spec_dir(associate, associates_config, base_path)
429
452
  if spec_dir:
430
453
  spec_dirs.append(spec_dir)
431
454
 
432
455
  return spec_dirs
456
+
457
+
458
+ # Alias for backwards compatibility
459
+ get_sponsor_spec_directories = get_associate_spec_directories
460
+
461
+
462
+ __all__ = [
463
+ "Associate",
464
+ "Sponsor", # alias
465
+ "AssociatesConfig",
466
+ "SponsorsConfig", # alias
467
+ "parse_yaml",
468
+ "load_associates_yaml",
469
+ "load_sponsors_yaml", # alias
470
+ "load_associates_config",
471
+ "load_sponsors_config", # alias
472
+ "resolve_associate_spec_dir",
473
+ "resolve_sponsor_spec_dir", # alias
474
+ "get_associate_spec_directories",
475
+ "get_sponsor_spec_directories", # alias
476
+ ]