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.
- elspais/__init__.py +1 -10
- elspais/{sponsors/__init__.py → associates.py} +102 -56
- elspais/cli.py +366 -69
- elspais/commands/__init__.py +9 -3
- elspais/commands/analyze.py +118 -169
- elspais/commands/changed.py +12 -23
- elspais/commands/config_cmd.py +10 -13
- elspais/commands/edit.py +33 -13
- elspais/commands/example_cmd.py +319 -0
- elspais/commands/hash_cmd.py +161 -183
- elspais/commands/health.py +1177 -0
- elspais/commands/index.py +98 -115
- elspais/commands/init.py +99 -22
- elspais/commands/reformat_cmd.py +41 -433
- elspais/commands/rules_cmd.py +2 -2
- elspais/commands/trace.py +443 -324
- elspais/commands/validate.py +193 -411
- elspais/config/__init__.py +799 -5
- elspais/{core/content_rules.py → content_rules.py} +20 -2
- elspais/docs/cli/assertions.md +67 -0
- elspais/docs/cli/commands.md +304 -0
- elspais/docs/cli/config.md +262 -0
- elspais/docs/cli/format.md +66 -0
- elspais/docs/cli/git.md +45 -0
- elspais/docs/cli/health.md +190 -0
- elspais/docs/cli/hierarchy.md +60 -0
- elspais/docs/cli/ignore.md +72 -0
- elspais/docs/cli/mcp.md +245 -0
- elspais/docs/cli/quickstart.md +58 -0
- elspais/docs/cli/traceability.md +89 -0
- elspais/docs/cli/validation.md +96 -0
- elspais/graph/GraphNode.py +383 -0
- elspais/graph/__init__.py +40 -0
- elspais/graph/annotators.py +927 -0
- elspais/graph/builder.py +1886 -0
- elspais/graph/deserializer.py +248 -0
- elspais/graph/factory.py +284 -0
- elspais/graph/metrics.py +127 -0
- elspais/graph/mutations.py +161 -0
- elspais/graph/parsers/__init__.py +156 -0
- elspais/graph/parsers/code.py +213 -0
- elspais/graph/parsers/comments.py +112 -0
- elspais/graph/parsers/config_helpers.py +29 -0
- elspais/graph/parsers/heredocs.py +225 -0
- elspais/graph/parsers/journey.py +131 -0
- elspais/graph/parsers/remainder.py +79 -0
- elspais/graph/parsers/requirement.py +347 -0
- elspais/graph/parsers/results/__init__.py +6 -0
- elspais/graph/parsers/results/junit_xml.py +229 -0
- elspais/graph/parsers/results/pytest_json.py +313 -0
- elspais/graph/parsers/test.py +305 -0
- elspais/graph/relations.py +78 -0
- elspais/graph/serialize.py +216 -0
- elspais/html/__init__.py +8 -0
- elspais/html/generator.py +731 -0
- elspais/html/templates/trace_view.html.j2 +2151 -0
- elspais/mcp/__init__.py +45 -29
- elspais/mcp/__main__.py +5 -1
- elspais/mcp/file_mutations.py +138 -0
- elspais/mcp/server.py +1998 -244
- elspais/testing/__init__.py +3 -3
- elspais/testing/config.py +3 -0
- elspais/testing/mapper.py +1 -1
- elspais/testing/scanner.py +301 -12
- elspais/utilities/__init__.py +1 -0
- elspais/utilities/docs_loader.py +115 -0
- elspais/utilities/git.py +607 -0
- elspais/{core → utilities}/hasher.py +8 -22
- elspais/utilities/md_renderer.py +189 -0
- elspais/{core → utilities}/patterns.py +56 -51
- elspais/utilities/reference_config.py +626 -0
- elspais/validation/__init__.py +19 -0
- elspais/validation/format.py +264 -0
- {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/METADATA +7 -4
- elspais-0.43.5.dist-info/RECORD +80 -0
- elspais/config/defaults.py +0 -179
- elspais/config/loader.py +0 -494
- elspais/core/__init__.py +0 -21
- elspais/core/git.py +0 -346
- elspais/core/models.py +0 -320
- elspais/core/parser.py +0 -639
- elspais/core/rules.py +0 -509
- elspais/mcp/context.py +0 -172
- elspais/mcp/serializers.py +0 -112
- elspais/reformat/__init__.py +0 -50
- elspais/reformat/detector.py +0 -112
- elspais/reformat/hierarchy.py +0 -247
- elspais/reformat/line_breaks.py +0 -218
- elspais/reformat/prompts.py +0 -133
- elspais/reformat/transformer.py +0 -266
- elspais/trace_view/__init__.py +0 -55
- elspais/trace_view/coverage.py +0 -183
- elspais/trace_view/generators/__init__.py +0 -12
- elspais/trace_view/generators/base.py +0 -334
- elspais/trace_view/generators/csv.py +0 -118
- elspais/trace_view/generators/markdown.py +0 -170
- elspais/trace_view/html/__init__.py +0 -33
- elspais/trace_view/html/generator.py +0 -1140
- elspais/trace_view/html/templates/base.html +0 -283
- elspais/trace_view/html/templates/components/code_viewer_modal.html +0 -14
- elspais/trace_view/html/templates/components/file_picker_modal.html +0 -20
- elspais/trace_view/html/templates/components/legend_modal.html +0 -69
- elspais/trace_view/html/templates/components/review_panel.html +0 -118
- elspais/trace_view/html/templates/partials/review/help/help-panel.json +0 -244
- elspais/trace_view/html/templates/partials/review/help/onboarding.json +0 -77
- elspais/trace_view/html/templates/partials/review/help/tooltips.json +0 -237
- elspais/trace_view/html/templates/partials/review/review-comments.js +0 -928
- elspais/trace_view/html/templates/partials/review/review-data.js +0 -961
- elspais/trace_view/html/templates/partials/review/review-help.js +0 -679
- elspais/trace_view/html/templates/partials/review/review-init.js +0 -177
- elspais/trace_view/html/templates/partials/review/review-line-numbers.js +0 -429
- elspais/trace_view/html/templates/partials/review/review-packages.js +0 -1029
- elspais/trace_view/html/templates/partials/review/review-position.js +0 -540
- elspais/trace_view/html/templates/partials/review/review-resize.js +0 -115
- elspais/trace_view/html/templates/partials/review/review-status.js +0 -659
- elspais/trace_view/html/templates/partials/review/review-sync.js +0 -992
- elspais/trace_view/html/templates/partials/review-styles.css +0 -2238
- elspais/trace_view/html/templates/partials/scripts.js +0 -1741
- elspais/trace_view/html/templates/partials/styles.css +0 -1756
- elspais/trace_view/models.py +0 -378
- elspais/trace_view/review/__init__.py +0 -63
- elspais/trace_view/review/branches.py +0 -1142
- elspais/trace_view/review/models.py +0 -1200
- elspais/trace_view/review/position.py +0 -591
- elspais/trace_view/review/server.py +0 -1032
- elspais/trace_view/review/status.py +0 -455
- elspais/trace_view/review/storage.py +0 -1343
- elspais/trace_view/scanning.py +0 -213
- elspais/trace_view/specs/README.md +0 -84
- elspais/trace_view/specs/tv-d00001-template-architecture.md +0 -36
- elspais/trace_view/specs/tv-d00002-css-extraction.md +0 -37
- elspais/trace_view/specs/tv-d00003-js-extraction.md +0 -43
- elspais/trace_view/specs/tv-d00004-build-embedding.md +0 -40
- elspais/trace_view/specs/tv-d00005-test-format.md +0 -78
- elspais/trace_view/specs/tv-d00010-review-data-models.md +0 -33
- elspais/trace_view/specs/tv-d00011-review-storage.md +0 -33
- elspais/trace_view/specs/tv-d00012-position-resolution.md +0 -33
- elspais/trace_view/specs/tv-d00013-git-branches.md +0 -31
- elspais/trace_view/specs/tv-d00014-review-api-server.md +0 -31
- elspais/trace_view/specs/tv-d00015-status-modifier.md +0 -27
- elspais/trace_view/specs/tv-d00016-js-integration.md +0 -33
- elspais/trace_view/specs/tv-p00001-html-generator.md +0 -33
- elspais/trace_view/specs/tv-p00002-review-system.md +0 -29
- elspais-0.11.2.dist-info/RECORD +0 -101
- {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/WHEEL +0 -0
- {elspais-0.11.2.dist-info → elspais-0.43.5.dist-info}/entry_points.txt +0 -0
- {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
|