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.
- elspais/__init__.py +2 -11
- elspais/{sponsors/__init__.py → associates.py} +102 -58
- elspais/cli.py +395 -79
- elspais/commands/__init__.py +9 -3
- elspais/commands/analyze.py +121 -173
- elspais/commands/changed.py +15 -30
- elspais/commands/config_cmd.py +13 -16
- elspais/commands/edit.py +60 -44
- elspais/commands/example_cmd.py +319 -0
- elspais/commands/hash_cmd.py +167 -183
- elspais/commands/health.py +1177 -0
- elspais/commands/index.py +98 -114
- elspais/commands/init.py +103 -26
- elspais/commands/reformat_cmd.py +41 -444
- elspais/commands/rules_cmd.py +7 -3
- elspais/commands/trace.py +444 -321
- elspais/commands/validate.py +195 -415
- elspais/config/__init__.py +799 -5
- elspais/{core/content_rules.py → content_rules.py} +20 -3
- 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 +47 -29
- elspais/mcp/__main__.py +5 -1
- elspais/mcp/file_mutations.py +138 -0
- elspais/mcp/server.py +2016 -247
- elspais/testing/__init__.py +4 -4
- elspais/testing/config.py +3 -0
- elspais/testing/mapper.py +1 -1
- elspais/testing/result_parser.py +25 -21
- 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 +58 -57
- elspais/utilities/reference_config.py +626 -0
- elspais/validation/__init__.py +19 -0
- elspais/validation/format.py +264 -0
- {elspais-0.11.1.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 -173
- elspais/config/loader.py +0 -494
- elspais/core/__init__.py +0 -21
- elspais/core/git.py +0 -352
- elspais/core/models.py +0 -320
- elspais/core/parser.py +0 -640
- elspais/core/rules.py +0 -514
- elspais/mcp/context.py +0 -171
- elspais/mcp/serializers.py +0 -112
- elspais/reformat/__init__.py +0 -50
- elspais/reformat/detector.py +0 -119
- elspais/reformat/hierarchy.py +0 -246
- elspais/reformat/line_breaks.py +0 -220
- elspais/reformat/prompts.py +0 -123
- elspais/reformat/transformer.py +0 -264
- elspais/trace_view/__init__.py +0 -54
- elspais/trace_view/coverage.py +0 -183
- elspais/trace_view/generators/__init__.py +0 -12
- elspais/trace_view/generators/base.py +0 -329
- elspais/trace_view/generators/csv.py +0 -122
- elspais/trace_view/generators/markdown.py +0 -175
- elspais/trace_view/html/__init__.py +0 -31
- elspais/trace_view/html/generator.py +0 -1006
- 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 -353
- elspais/trace_view/review/__init__.py +0 -60
- elspais/trace_view/review/branches.py +0 -1149
- elspais/trace_view/review/models.py +0 -1205
- elspais/trace_view/review/position.py +0 -609
- elspais/trace_view/review/server.py +0 -1056
- elspais/trace_view/review/status.py +0 -470
- elspais/trace_view/review/storage.py +0 -1367
- 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.1.dist-info/RECORD +0 -101
- {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/WHEEL +0 -0
- {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/entry_points.txt +0 -0
- {elspais-0.11.1.dist-info → elspais-0.43.5.dist-info}/licenses/LICENSE +0 -0
elspais/cli.py
CHANGED
|
@@ -10,7 +10,21 @@ from pathlib import Path
|
|
|
10
10
|
from typing import List, Optional
|
|
11
11
|
|
|
12
12
|
from elspais import __version__
|
|
13
|
-
from elspais.commands import
|
|
13
|
+
from elspais.commands import (
|
|
14
|
+
analyze,
|
|
15
|
+
changed,
|
|
16
|
+
config_cmd,
|
|
17
|
+
edit,
|
|
18
|
+
example_cmd,
|
|
19
|
+
hash_cmd,
|
|
20
|
+
health,
|
|
21
|
+
index,
|
|
22
|
+
init,
|
|
23
|
+
reformat_cmd,
|
|
24
|
+
rules_cmd,
|
|
25
|
+
trace,
|
|
26
|
+
validate,
|
|
27
|
+
)
|
|
14
28
|
|
|
15
29
|
|
|
16
30
|
def create_parser() -> argparse.ArgumentParser:
|
|
@@ -28,8 +42,17 @@ Examples:
|
|
|
28
42
|
elspais hash update # Update all requirement hashes
|
|
29
43
|
elspais changed # Show uncommitted spec changes
|
|
30
44
|
elspais analyze hierarchy # Show requirement hierarchy tree
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
|
|
46
|
+
Configuration:
|
|
47
|
+
elspais init # Create .elspais.toml in current directory
|
|
48
|
+
elspais config path # Show config file location
|
|
49
|
+
elspais config show # View all settings
|
|
50
|
+
elspais config --help # Configuration guide with examples
|
|
51
|
+
|
|
52
|
+
Documentation:
|
|
53
|
+
elspais example # Quick requirement format reference
|
|
54
|
+
elspais example --full # Full specification document
|
|
55
|
+
elspais completion # Shell tab-completion setup
|
|
33
56
|
|
|
34
57
|
For detailed command help: elspais <command> --help
|
|
35
58
|
""",
|
|
@@ -54,12 +77,14 @@ For detailed command help: elspais <command> --help
|
|
|
54
77
|
metavar="PATH",
|
|
55
78
|
)
|
|
56
79
|
parser.add_argument(
|
|
57
|
-
"-v",
|
|
80
|
+
"-v",
|
|
81
|
+
"--verbose",
|
|
58
82
|
action="store_true",
|
|
59
83
|
help="Verbose output",
|
|
60
84
|
)
|
|
61
85
|
parser.add_argument(
|
|
62
|
-
"-q",
|
|
86
|
+
"-q",
|
|
87
|
+
"--quiet",
|
|
63
88
|
action="store_true",
|
|
64
89
|
help="Suppress non-error output",
|
|
65
90
|
)
|
|
@@ -90,13 +115,12 @@ Common rules to skip:
|
|
|
90
115
|
validate_parser.add_argument(
|
|
91
116
|
"--fix",
|
|
92
117
|
action="store_true",
|
|
93
|
-
help="Auto-fix
|
|
118
|
+
help="Auto-fix issues that can be corrected programmatically (hashes, status)",
|
|
94
119
|
)
|
|
95
120
|
validate_parser.add_argument(
|
|
96
|
-
"--
|
|
97
|
-
|
|
98
|
-
help="
|
|
99
|
-
metavar="PATH",
|
|
121
|
+
"--dry-run",
|
|
122
|
+
action="store_true",
|
|
123
|
+
help="Show what would be fixed without making changes (use with --fix)",
|
|
100
124
|
)
|
|
101
125
|
validate_parser.add_argument(
|
|
102
126
|
"--skip-rule",
|
|
@@ -105,25 +129,64 @@ Common rules to skip:
|
|
|
105
129
|
metavar="RULE",
|
|
106
130
|
)
|
|
107
131
|
validate_parser.add_argument(
|
|
108
|
-
"-j",
|
|
132
|
+
"-j",
|
|
133
|
+
"--json",
|
|
109
134
|
action="store_true",
|
|
110
135
|
help="Output requirements as JSON (hht_diary compatible format)",
|
|
111
136
|
)
|
|
112
|
-
|
|
113
|
-
|
|
137
|
+
# NOTE: --tests, --no-tests, --mode removed (dead code - never implemented)
|
|
138
|
+
|
|
139
|
+
# health command
|
|
140
|
+
health_parser = subparsers.add_parser(
|
|
141
|
+
"health",
|
|
142
|
+
help="Check repository and configuration health",
|
|
143
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
144
|
+
epilog="""
|
|
145
|
+
Examples:
|
|
146
|
+
elspais health # Run all health checks
|
|
147
|
+
elspais health --config # Check config only
|
|
148
|
+
elspais health --spec # Check spec files only
|
|
149
|
+
elspais health --code # Check code references only
|
|
150
|
+
elspais health --tests # Check test mappings only
|
|
151
|
+
elspais health -j # Output JSON for tooling
|
|
152
|
+
elspais health -v # Verbose output with details
|
|
153
|
+
|
|
154
|
+
Checks performed:
|
|
155
|
+
CONFIG: TOML syntax, required fields, pattern tokens, hierarchy rules, paths
|
|
156
|
+
SPEC: File parsing, duplicate IDs, reference resolution, orphans
|
|
157
|
+
CODE: Code→REQ reference validation, coverage statistics
|
|
158
|
+
TESTS: Test→REQ mappings, result status, coverage statistics
|
|
159
|
+
""",
|
|
160
|
+
)
|
|
161
|
+
health_parser.add_argument(
|
|
162
|
+
"--config",
|
|
163
|
+
dest="config_only",
|
|
114
164
|
action="store_true",
|
|
115
|
-
help="
|
|
165
|
+
help="Run configuration checks only",
|
|
116
166
|
)
|
|
117
|
-
|
|
118
|
-
"--
|
|
167
|
+
health_parser.add_argument(
|
|
168
|
+
"--spec",
|
|
169
|
+
dest="spec_only",
|
|
119
170
|
action="store_true",
|
|
120
|
-
help="
|
|
171
|
+
help="Run spec file checks only",
|
|
121
172
|
)
|
|
122
|
-
|
|
123
|
-
"--
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
help="
|
|
173
|
+
health_parser.add_argument(
|
|
174
|
+
"--code",
|
|
175
|
+
dest="code_only",
|
|
176
|
+
action="store_true",
|
|
177
|
+
help="Run code reference checks only",
|
|
178
|
+
)
|
|
179
|
+
health_parser.add_argument(
|
|
180
|
+
"--tests",
|
|
181
|
+
dest="tests_only",
|
|
182
|
+
action="store_true",
|
|
183
|
+
help="Run test mapping checks only",
|
|
184
|
+
)
|
|
185
|
+
health_parser.add_argument(
|
|
186
|
+
"-j",
|
|
187
|
+
"--json",
|
|
188
|
+
action="store_true",
|
|
189
|
+
help="Output as JSON",
|
|
127
190
|
)
|
|
128
191
|
|
|
129
192
|
# trace command
|
|
@@ -169,23 +232,19 @@ Common rules to skip:
|
|
|
169
232
|
action="store_true",
|
|
170
233
|
help="Start review server (requires trace-review extra)",
|
|
171
234
|
)
|
|
235
|
+
# NOTE: --port, --mode, --sponsor, --graph removed (dead code - never implemented)
|
|
236
|
+
# Graph-based trace options
|
|
172
237
|
trace_parser.add_argument(
|
|
173
|
-
"--
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
help="Port for review server (default: 8080)",
|
|
177
|
-
)
|
|
178
|
-
trace_parser.add_argument(
|
|
179
|
-
"--mode",
|
|
180
|
-
choices=["core", "sponsor", "combined"],
|
|
181
|
-
default="core",
|
|
182
|
-
help="Report mode: core, sponsor, or combined (default: core)",
|
|
238
|
+
"--graph-json",
|
|
239
|
+
action="store_true",
|
|
240
|
+
help="Output graph structure as JSON",
|
|
183
241
|
)
|
|
184
242
|
trace_parser.add_argument(
|
|
185
|
-
"--
|
|
186
|
-
|
|
187
|
-
|
|
243
|
+
"--report",
|
|
244
|
+
choices=["minimal", "standard", "full"],
|
|
245
|
+
help="Report preset to use (default: standard)",
|
|
188
246
|
)
|
|
247
|
+
# NOTE: --depth removed (dead code - never implemented)
|
|
189
248
|
|
|
190
249
|
# hash command
|
|
191
250
|
hash_parser = subparsers.add_parser(
|
|
@@ -262,12 +321,14 @@ Common rules to skip:
|
|
|
262
321
|
metavar="BRANCH",
|
|
263
322
|
)
|
|
264
323
|
changed_parser.add_argument(
|
|
265
|
-
"-j",
|
|
324
|
+
"-j",
|
|
325
|
+
"--json",
|
|
266
326
|
action="store_true",
|
|
267
327
|
help="Output as JSON",
|
|
268
328
|
)
|
|
269
329
|
changed_parser.add_argument(
|
|
270
|
-
"-a",
|
|
330
|
+
"-a",
|
|
331
|
+
"--all",
|
|
271
332
|
action="store_true",
|
|
272
333
|
help="Include all changed files (not just spec)",
|
|
273
334
|
)
|
|
@@ -303,6 +364,38 @@ Common rules to skip:
|
|
|
303
364
|
action="store_true",
|
|
304
365
|
help="Overwrite existing configuration",
|
|
305
366
|
)
|
|
367
|
+
init_parser.add_argument(
|
|
368
|
+
"--template",
|
|
369
|
+
action="store_true",
|
|
370
|
+
help="Create an example requirement file in spec/",
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
# example command
|
|
374
|
+
example_parser = subparsers.add_parser(
|
|
375
|
+
"example",
|
|
376
|
+
help="Display requirement format examples and templates",
|
|
377
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
378
|
+
epilog="""
|
|
379
|
+
Subcommands:
|
|
380
|
+
elspais example Quick reference (default)
|
|
381
|
+
elspais example requirement Full requirement template with all sections
|
|
382
|
+
elspais example journey User journey template
|
|
383
|
+
elspais example assertion Assertion rules and examples
|
|
384
|
+
elspais example ids Show ID patterns from current config
|
|
385
|
+
elspais example --full Display spec/requirements-spec.md (if exists)
|
|
386
|
+
""",
|
|
387
|
+
)
|
|
388
|
+
example_parser.add_argument(
|
|
389
|
+
"example_type",
|
|
390
|
+
nargs="?",
|
|
391
|
+
choices=["requirement", "journey", "assertion", "ids"],
|
|
392
|
+
help="Example type to display",
|
|
393
|
+
)
|
|
394
|
+
example_parser.add_argument(
|
|
395
|
+
"--full",
|
|
396
|
+
action="store_true",
|
|
397
|
+
help="Display the full requirements specification file",
|
|
398
|
+
)
|
|
306
399
|
|
|
307
400
|
# edit command
|
|
308
401
|
edit_parser = subparsers.add_parser(
|
|
@@ -317,7 +410,7 @@ Examples:
|
|
|
317
410
|
elspais edit --from-json edits.json
|
|
318
411
|
|
|
319
412
|
JSON batch format:
|
|
320
|
-
|
|
413
|
+
[{"req_id": "...", "status": "...", "implements": [...]}]
|
|
321
414
|
""",
|
|
322
415
|
)
|
|
323
416
|
edit_parser.add_argument(
|
|
@@ -360,6 +453,39 @@ JSON batch format:
|
|
|
360
453
|
config_parser = subparsers.add_parser(
|
|
361
454
|
"config",
|
|
362
455
|
help="View and modify configuration (show, get, set, ...)",
|
|
456
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
457
|
+
epilog="""
|
|
458
|
+
Configuration File:
|
|
459
|
+
elspais looks for .elspais.toml in the current directory or parent directories.
|
|
460
|
+
Create one with: elspais init
|
|
461
|
+
|
|
462
|
+
Location: elspais config path
|
|
463
|
+
View all: elspais config show
|
|
464
|
+
|
|
465
|
+
Quick Start (.elspais.toml):
|
|
466
|
+
[project]
|
|
467
|
+
name = "my-project"
|
|
468
|
+
spec_dir = "spec" # Where requirement files live
|
|
469
|
+
|
|
470
|
+
[patterns]
|
|
471
|
+
prefix = "REQ" # Requirement ID prefix
|
|
472
|
+
separator = "-" # ID separator (REQ-p00001)
|
|
473
|
+
|
|
474
|
+
[rules]
|
|
475
|
+
strict_mode = false # Strict implements semantics
|
|
476
|
+
|
|
477
|
+
[rules.hierarchy]
|
|
478
|
+
allowed = ["dev -> ops, prd", "ops -> prd"]
|
|
479
|
+
|
|
480
|
+
Common Commands:
|
|
481
|
+
elspais config show # View current config
|
|
482
|
+
elspais config get patterns.prefix
|
|
483
|
+
elspais config set project.name "MyApp"
|
|
484
|
+
elspais config path # Show config file location
|
|
485
|
+
|
|
486
|
+
Full Documentation:
|
|
487
|
+
See docs/configuration.md for all options.
|
|
488
|
+
""",
|
|
363
489
|
)
|
|
364
490
|
config_subparsers = config_parser.add_subparsers(dest="config_action")
|
|
365
491
|
|
|
@@ -374,7 +500,8 @@ JSON batch format:
|
|
|
374
500
|
metavar="SECTION",
|
|
375
501
|
)
|
|
376
502
|
config_show.add_argument(
|
|
377
|
-
"-j",
|
|
503
|
+
"-j",
|
|
504
|
+
"--json",
|
|
378
505
|
action="store_true",
|
|
379
506
|
help="Output as JSON",
|
|
380
507
|
)
|
|
@@ -389,7 +516,8 @@ JSON batch format:
|
|
|
389
516
|
help="Configuration key (dot-notation, e.g., 'patterns.prefix')",
|
|
390
517
|
)
|
|
391
518
|
config_get.add_argument(
|
|
392
|
-
"-j",
|
|
519
|
+
"-j",
|
|
520
|
+
"--json",
|
|
393
521
|
action="store_true",
|
|
394
522
|
help="Output as JSON",
|
|
395
523
|
)
|
|
@@ -405,7 +533,7 @@ JSON batch format:
|
|
|
405
533
|
)
|
|
406
534
|
config_set.add_argument(
|
|
407
535
|
"value",
|
|
408
|
-
help="Value to set (
|
|
536
|
+
help="Value to set (auto-detected: bool, number, JSON array/object, string)",
|
|
409
537
|
)
|
|
410
538
|
|
|
411
539
|
# config unset
|
|
@@ -475,51 +603,105 @@ JSON batch format:
|
|
|
475
603
|
help="Content rule file name (e.g., 'AI-AGENT.md')",
|
|
476
604
|
)
|
|
477
605
|
|
|
478
|
-
# reformat-with-claude command
|
|
479
|
-
|
|
606
|
+
# reformat-with-claude command (NOT YET IMPLEMENTED - placeholder for future feature)
|
|
607
|
+
subparsers.add_parser(
|
|
480
608
|
"reformat-with-claude",
|
|
481
|
-
help="Reformat requirements using AI (Acceptance Criteria -> Assertions)",
|
|
609
|
+
help="[NOT IMPLEMENTED] Reformat requirements using AI (Acceptance Criteria -> Assertions)",
|
|
482
610
|
)
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
"
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
611
|
+
# NOTE: All arguments removed - command not yet implemented
|
|
612
|
+
# See src/elspais/commands/reformat_cmd.py for planned features
|
|
613
|
+
|
|
614
|
+
# docs command - comprehensive user documentation
|
|
615
|
+
docs_parser = subparsers.add_parser(
|
|
616
|
+
"docs",
|
|
617
|
+
help="Read the user guide (topics: quickstart, format, hierarchy, ...)",
|
|
618
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
619
|
+
epilog="""
|
|
620
|
+
Available Topics:
|
|
621
|
+
quickstart Getting started with elspais (default)
|
|
622
|
+
format Requirement file format and structure
|
|
623
|
+
hierarchy PRD → OPS → DEV levels and implements
|
|
624
|
+
assertions Writing testable assertions with SHALL
|
|
625
|
+
traceability Linking requirements to code and tests
|
|
626
|
+
validation Running validation and fixing issues
|
|
627
|
+
git Change detection and git integration
|
|
628
|
+
config Configuration file reference
|
|
629
|
+
mcp MCP server for AI integration
|
|
630
|
+
all Show complete documentation
|
|
631
|
+
|
|
632
|
+
Examples:
|
|
633
|
+
elspais docs # Quick start guide
|
|
634
|
+
elspais docs format # Requirement format reference
|
|
635
|
+
elspais docs all # Complete documentation
|
|
636
|
+
elspais docs all --no-pager # Disable pager
|
|
637
|
+
""",
|
|
502
638
|
)
|
|
503
|
-
|
|
504
|
-
"
|
|
639
|
+
docs_parser.add_argument(
|
|
640
|
+
"topic",
|
|
641
|
+
nargs="?",
|
|
642
|
+
default="quickstart",
|
|
643
|
+
choices=[
|
|
644
|
+
"quickstart",
|
|
645
|
+
"format",
|
|
646
|
+
"hierarchy",
|
|
647
|
+
"assertions",
|
|
648
|
+
"traceability",
|
|
649
|
+
"validation",
|
|
650
|
+
"git",
|
|
651
|
+
"config",
|
|
652
|
+
"commands",
|
|
653
|
+
"health",
|
|
654
|
+
"mcp",
|
|
655
|
+
"all",
|
|
656
|
+
],
|
|
657
|
+
help="Documentation topic (default: quickstart)",
|
|
658
|
+
)
|
|
659
|
+
docs_parser.add_argument(
|
|
660
|
+
"--plain",
|
|
505
661
|
action="store_true",
|
|
506
|
-
help="
|
|
662
|
+
help="Plain text output (no ANSI colors)",
|
|
507
663
|
)
|
|
508
|
-
|
|
509
|
-
"--
|
|
664
|
+
docs_parser.add_argument(
|
|
665
|
+
"--no-pager",
|
|
510
666
|
action="store_true",
|
|
511
|
-
help="
|
|
667
|
+
help="Disable paging (print directly to stdout)",
|
|
512
668
|
)
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
669
|
+
|
|
670
|
+
# completion command - shell tab-completion setup
|
|
671
|
+
completion_parser = subparsers.add_parser(
|
|
672
|
+
"completion",
|
|
673
|
+
help="Generate shell tab-completion scripts",
|
|
674
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
675
|
+
epilog="""
|
|
676
|
+
Shell Completion Setup:
|
|
677
|
+
|
|
678
|
+
First, install the completion extra:
|
|
679
|
+
pip install elspais[completion]
|
|
680
|
+
|
|
681
|
+
Bash (add to ~/.bashrc):
|
|
682
|
+
eval "$(register-python-argcomplete elspais)"
|
|
683
|
+
|
|
684
|
+
Zsh (add to ~/.zshrc):
|
|
685
|
+
autoload -U bashcompinit
|
|
686
|
+
bashcompinit
|
|
687
|
+
eval "$(register-python-argcomplete elspais)"
|
|
688
|
+
|
|
689
|
+
Fish (add to ~/.config/fish/config.fish):
|
|
690
|
+
register-python-argcomplete --shell fish elspais | source
|
|
691
|
+
|
|
692
|
+
Tcsh (add to ~/.tcshrc):
|
|
693
|
+
eval `register-python-argcomplete --shell tcsh elspais`
|
|
694
|
+
|
|
695
|
+
Global activation (for all argcomplete-enabled tools):
|
|
696
|
+
activate-global-python-argcomplete
|
|
697
|
+
|
|
698
|
+
After adding the appropriate line, restart your shell or source the config file.
|
|
699
|
+
""",
|
|
517
700
|
)
|
|
518
|
-
|
|
519
|
-
"--
|
|
520
|
-
choices=["
|
|
521
|
-
|
|
522
|
-
help="Which repos to include in hierarchy (default: combined)",
|
|
701
|
+
completion_parser.add_argument(
|
|
702
|
+
"--shell",
|
|
703
|
+
choices=["bash", "zsh", "fish", "tcsh"],
|
|
704
|
+
help="Generate script for specific shell",
|
|
523
705
|
)
|
|
524
706
|
|
|
525
707
|
# mcp command
|
|
@@ -587,6 +769,17 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
587
769
|
Exit code (0 for success, non-zero for failure)
|
|
588
770
|
"""
|
|
589
771
|
parser = create_parser()
|
|
772
|
+
|
|
773
|
+
# Enable shell tab-completion if argcomplete is installed
|
|
774
|
+
# Install with: pip install elspais[completion]
|
|
775
|
+
# Then activate: eval "$(register-python-argcomplete elspais)"
|
|
776
|
+
try:
|
|
777
|
+
import argcomplete
|
|
778
|
+
|
|
779
|
+
argcomplete.autocomplete(parser)
|
|
780
|
+
except ImportError:
|
|
781
|
+
pass
|
|
782
|
+
|
|
590
783
|
args = parser.parse_args(argv)
|
|
591
784
|
|
|
592
785
|
# Handle no command
|
|
@@ -594,10 +787,28 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
594
787
|
parser.print_help()
|
|
595
788
|
return 0
|
|
596
789
|
|
|
790
|
+
# Auto-detect git repository root and change to it
|
|
791
|
+
# This ensures elspais works the same from any subdirectory
|
|
792
|
+
import os
|
|
793
|
+
|
|
794
|
+
from elspais.config import find_git_root
|
|
795
|
+
|
|
796
|
+
original_cwd = Path.cwd()
|
|
797
|
+
git_root = find_git_root(original_cwd)
|
|
798
|
+
|
|
799
|
+
if git_root and git_root != original_cwd:
|
|
800
|
+
os.chdir(git_root)
|
|
801
|
+
if args.verbose:
|
|
802
|
+
print(f"Working from repository root: {git_root}", file=sys.stderr)
|
|
803
|
+
elif not git_root and args.verbose:
|
|
804
|
+
print("Warning: Not in a git repository", file=sys.stderr)
|
|
805
|
+
|
|
597
806
|
try:
|
|
598
807
|
# Dispatch to command handlers
|
|
599
808
|
if args.command == "validate":
|
|
600
809
|
return validate.run(args)
|
|
810
|
+
elif args.command == "health":
|
|
811
|
+
return health.run(args)
|
|
601
812
|
elif args.command == "trace":
|
|
602
813
|
return trace.run(args)
|
|
603
814
|
elif args.command == "hash":
|
|
@@ -612,6 +823,8 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
612
823
|
return version_command(args)
|
|
613
824
|
elif args.command == "init":
|
|
614
825
|
return init.run(args)
|
|
826
|
+
elif args.command == "example":
|
|
827
|
+
return example_cmd.run(args)
|
|
615
828
|
elif args.command == "edit":
|
|
616
829
|
return edit.run(args)
|
|
617
830
|
elif args.command == "config":
|
|
@@ -620,6 +833,10 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
620
833
|
return rules_cmd.run(args)
|
|
621
834
|
elif args.command == "reformat-with-claude":
|
|
622
835
|
return reformat_cmd.run(args)
|
|
836
|
+
elif args.command == "docs":
|
|
837
|
+
return docs_command(args)
|
|
838
|
+
elif args.command == "completion":
|
|
839
|
+
return completion_command(args)
|
|
623
840
|
elif args.command == "mcp":
|
|
624
841
|
return mcp_command(args)
|
|
625
842
|
else:
|
|
@@ -636,6 +853,105 @@ def main(argv: Optional[List[str]] = None) -> int:
|
|
|
636
853
|
return 1
|
|
637
854
|
|
|
638
855
|
|
|
856
|
+
def docs_command(args: argparse.Namespace) -> int:
|
|
857
|
+
"""Handle docs command - display user documentation from markdown files."""
|
|
858
|
+
import pydoc
|
|
859
|
+
|
|
860
|
+
from elspais.utilities.docs_loader import load_all_topics, load_topic
|
|
861
|
+
from elspais.utilities.md_renderer import render_markdown
|
|
862
|
+
|
|
863
|
+
topic = args.topic
|
|
864
|
+
use_pager = not args.no_pager and sys.stdout.isatty()
|
|
865
|
+
use_color = not args.plain and sys.stdout.isatty()
|
|
866
|
+
|
|
867
|
+
# Load content from markdown files
|
|
868
|
+
if topic == "all":
|
|
869
|
+
content = load_all_topics()
|
|
870
|
+
else:
|
|
871
|
+
content = load_topic(topic)
|
|
872
|
+
|
|
873
|
+
if content is None:
|
|
874
|
+
print(f"Error: Documentation not found for topic '{topic}'", file=sys.stderr)
|
|
875
|
+
print("Documentation files may not be installed correctly.", file=sys.stderr)
|
|
876
|
+
return 1
|
|
877
|
+
|
|
878
|
+
# Render markdown to ANSI and display
|
|
879
|
+
output = render_markdown(content, use_color=use_color)
|
|
880
|
+
|
|
881
|
+
if use_pager:
|
|
882
|
+
pydoc.pager(output)
|
|
883
|
+
else:
|
|
884
|
+
print(output)
|
|
885
|
+
|
|
886
|
+
return 0
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
def completion_command(args: argparse.Namespace) -> int:
|
|
890
|
+
"""Handle completion command - generate shell completion scripts."""
|
|
891
|
+
import importlib.util
|
|
892
|
+
|
|
893
|
+
if importlib.util.find_spec("argcomplete") is None:
|
|
894
|
+
print("Error: argcomplete not installed.", file=sys.stderr)
|
|
895
|
+
print("Install with: pip install elspais[completion]", file=sys.stderr)
|
|
896
|
+
return 1
|
|
897
|
+
|
|
898
|
+
shell = args.shell
|
|
899
|
+
|
|
900
|
+
if shell:
|
|
901
|
+
# Generate script for specific shell
|
|
902
|
+
import subprocess
|
|
903
|
+
|
|
904
|
+
shell_flag = f"--shell={shell}" if shell in ("fish", "tcsh") else ""
|
|
905
|
+
cmd = ["register-python-argcomplete"]
|
|
906
|
+
if shell_flag:
|
|
907
|
+
cmd.append(shell_flag)
|
|
908
|
+
cmd.append("elspais")
|
|
909
|
+
|
|
910
|
+
try:
|
|
911
|
+
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
912
|
+
if result.returncode == 0:
|
|
913
|
+
print(result.stdout)
|
|
914
|
+
else:
|
|
915
|
+
print(f"Error generating completion script: {result.stderr}", file=sys.stderr)
|
|
916
|
+
return 1
|
|
917
|
+
except FileNotFoundError:
|
|
918
|
+
print("Error: register-python-argcomplete not found.", file=sys.stderr)
|
|
919
|
+
print("Make sure argcomplete is properly installed.", file=sys.stderr)
|
|
920
|
+
return 1
|
|
921
|
+
else:
|
|
922
|
+
# Show setup instructions
|
|
923
|
+
print(
|
|
924
|
+
"""
|
|
925
|
+
Shell Completion Setup for elspais
|
|
926
|
+
===================================
|
|
927
|
+
|
|
928
|
+
Bash (add to ~/.bashrc):
|
|
929
|
+
eval "$(register-python-argcomplete elspais)"
|
|
930
|
+
|
|
931
|
+
Zsh (add to ~/.zshrc):
|
|
932
|
+
autoload -U bashcompinit
|
|
933
|
+
bashcompinit
|
|
934
|
+
eval "$(register-python-argcomplete elspais)"
|
|
935
|
+
|
|
936
|
+
Fish (add to ~/.config/fish/config.fish):
|
|
937
|
+
register-python-argcomplete --shell fish elspais | source
|
|
938
|
+
|
|
939
|
+
Tcsh (add to ~/.tcshrc):
|
|
940
|
+
eval `register-python-argcomplete --shell tcsh elspais`
|
|
941
|
+
|
|
942
|
+
Generate script for a specific shell:
|
|
943
|
+
elspais completion --shell bash
|
|
944
|
+
elspais completion --shell zsh
|
|
945
|
+
elspais completion --shell fish
|
|
946
|
+
elspais completion --shell tcsh
|
|
947
|
+
|
|
948
|
+
After adding the line, restart your shell or source the config file.
|
|
949
|
+
"""
|
|
950
|
+
)
|
|
951
|
+
|
|
952
|
+
return 0
|
|
953
|
+
|
|
954
|
+
|
|
639
955
|
def version_command(args: argparse.Namespace) -> int:
|
|
640
956
|
"""Handle version command."""
|
|
641
957
|
print(f"elspais {__version__}")
|
|
@@ -662,7 +978,7 @@ def mcp_command(args: argparse.Namespace) -> int:
|
|
|
662
978
|
if hasattr(args, "spec_dir") and args.spec_dir:
|
|
663
979
|
working_dir = args.spec_dir.parent
|
|
664
980
|
|
|
665
|
-
print(
|
|
981
|
+
print("Starting elspais MCP server...")
|
|
666
982
|
print(f"Working directory: {working_dir}")
|
|
667
983
|
print(f"Transport: {args.transport}")
|
|
668
984
|
|
elspais/commands/__init__.py
CHANGED
|
@@ -3,10 +3,16 @@ elspais.commands - CLI command implementations
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
__all__ = [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
6
|
+
"analyze",
|
|
7
|
+
"changed",
|
|
8
|
+
"config_cmd",
|
|
9
|
+
"edit",
|
|
10
|
+
"example_cmd",
|
|
8
11
|
"hash_cmd",
|
|
9
12
|
"index",
|
|
10
|
-
"analyze",
|
|
11
13
|
"init",
|
|
14
|
+
"reformat_cmd",
|
|
15
|
+
"rules_cmd",
|
|
16
|
+
"trace",
|
|
17
|
+
"validate",
|
|
12
18
|
]
|