specfact-cli 0.6.3__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.
- specfact_cli/__init__.py +14 -0
- specfact_cli/agents/__init__.py +24 -0
- specfact_cli/agents/analyze_agent.py +391 -0
- specfact_cli/agents/base.py +95 -0
- specfact_cli/agents/plan_agent.py +202 -0
- specfact_cli/agents/registry.py +176 -0
- specfact_cli/agents/sync_agent.py +133 -0
- specfact_cli/analyzers/__init__.py +12 -0
- specfact_cli/analyzers/ambiguity_scanner.py +592 -0
- specfact_cli/analyzers/code_analyzer.py +1228 -0
- specfact_cli/analyzers/contract_extractor.py +419 -0
- specfact_cli/analyzers/control_flow_analyzer.py +281 -0
- specfact_cli/analyzers/requirement_extractor.py +337 -0
- specfact_cli/analyzers/test_pattern_extractor.py +330 -0
- specfact_cli/cli.py +264 -0
- specfact_cli/commands/__init__.py +7 -0
- specfact_cli/commands/constitution.py +261 -0
- specfact_cli/commands/enforce.py +96 -0
- specfact_cli/commands/import_cmd.py +694 -0
- specfact_cli/commands/init.py +143 -0
- specfact_cli/commands/plan.py +2398 -0
- specfact_cli/commands/repro.py +214 -0
- specfact_cli/commands/sync.py +744 -0
- specfact_cli/common/__init__.py +25 -0
- specfact_cli/common/logger_setup.py +654 -0
- specfact_cli/common/logging_utils.py +41 -0
- specfact_cli/common/text_utils.py +52 -0
- specfact_cli/common/utils.py +48 -0
- specfact_cli/comparators/__init__.py +11 -0
- specfact_cli/comparators/plan_comparator.py +391 -0
- specfact_cli/enrichers/constitution_enricher.py +765 -0
- specfact_cli/enrichers/plan_enricher.py +268 -0
- specfact_cli/generators/__init__.py +14 -0
- specfact_cli/generators/plan_generator.py +105 -0
- specfact_cli/generators/protocol_generator.py +115 -0
- specfact_cli/generators/report_generator.py +200 -0
- specfact_cli/generators/workflow_generator.py +120 -0
- specfact_cli/importers/__init__.py +7 -0
- specfact_cli/importers/speckit_converter.py +1051 -0
- specfact_cli/importers/speckit_scanner.py +776 -0
- specfact_cli/models/__init__.py +33 -0
- specfact_cli/models/deviation.py +105 -0
- specfact_cli/models/enforcement.py +150 -0
- specfact_cli/models/plan.py +139 -0
- specfact_cli/models/protocol.py +28 -0
- specfact_cli/modes/__init__.py +19 -0
- specfact_cli/modes/detector.py +126 -0
- specfact_cli/modes/router.py +153 -0
- specfact_cli/resources/mappings/node-async.yaml +49 -0
- specfact_cli/resources/mappings/python-async.yaml +47 -0
- specfact_cli/resources/mappings/speckit-default.yaml +82 -0
- specfact_cli/resources/prompts/specfact-enforce.md +185 -0
- specfact_cli/resources/prompts/specfact-import-from-code.md +597 -0
- specfact_cli/resources/prompts/specfact-plan-add-feature.md +188 -0
- specfact_cli/resources/prompts/specfact-plan-add-story.md +212 -0
- specfact_cli/resources/prompts/specfact-plan-compare.md +571 -0
- specfact_cli/resources/prompts/specfact-plan-init.md +531 -0
- specfact_cli/resources/prompts/specfact-plan-promote.md +352 -0
- specfact_cli/resources/prompts/specfact-plan-review.md +869 -0
- specfact_cli/resources/prompts/specfact-plan-select.md +401 -0
- specfact_cli/resources/prompts/specfact-plan-update-feature.md +234 -0
- specfact_cli/resources/prompts/specfact-plan-update-idea.md +211 -0
- specfact_cli/resources/prompts/specfact-repro.md +268 -0
- specfact_cli/resources/prompts/specfact-sync.md +457 -0
- specfact_cli/resources/schemas/deviation.schema.json +61 -0
- specfact_cli/resources/schemas/plan.schema.json +204 -0
- specfact_cli/resources/schemas/protocol.schema.json +53 -0
- specfact_cli/resources/semgrep/async.yml +285 -0
- specfact_cli/resources/templates/github-action.yml.j2 +140 -0
- specfact_cli/resources/templates/plan.bundle.yaml.j2 +141 -0
- specfact_cli/resources/templates/pr-template.md.j2 +58 -0
- specfact_cli/resources/templates/protocol.yaml.j2 +24 -0
- specfact_cli/resources/templates/telemetry.yaml.example +35 -0
- specfact_cli/sync/__init__.py +21 -0
- specfact_cli/sync/repository_sync.py +279 -0
- specfact_cli/sync/speckit_sync.py +388 -0
- specfact_cli/sync/watcher.py +268 -0
- specfact_cli/telemetry.py +440 -0
- specfact_cli/utils/__init__.py +58 -0
- specfact_cli/utils/console.py +70 -0
- specfact_cli/utils/enrichment_parser.py +445 -0
- specfact_cli/utils/feature_keys.py +212 -0
- specfact_cli/utils/git.py +241 -0
- specfact_cli/utils/github_annotations.py +399 -0
- specfact_cli/utils/ide_setup.py +389 -0
- specfact_cli/utils/prompts.py +180 -0
- specfact_cli/utils/structure.py +674 -0
- specfact_cli/utils/yaml_utils.py +200 -0
- specfact_cli/validators/__init__.py +20 -0
- specfact_cli/validators/fsm.py +262 -0
- specfact_cli/validators/repro_checker.py +780 -0
- specfact_cli/validators/schema.py +196 -0
- specfact_cli-0.6.3.dist-info/METADATA +456 -0
- specfact_cli-0.6.3.dist-info/RECORD +97 -0
- specfact_cli-0.6.3.dist-info/WHEEL +4 -0
- specfact_cli-0.6.3.dist-info/entry_points.txt +2 -0
- specfact_cli-0.6.3.dist-info/licenses/LICENSE.md +202 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Init command - Initialize SpecFact for IDE integration.
|
|
3
|
+
|
|
4
|
+
This module provides the `specfact init` command to copy prompt templates
|
|
5
|
+
to IDE-specific locations for slash command integration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
from beartype import beartype
|
|
14
|
+
from icontract import ensure, require
|
|
15
|
+
from rich.console import Console
|
|
16
|
+
from rich.panel import Panel
|
|
17
|
+
|
|
18
|
+
from specfact_cli.telemetry import telemetry
|
|
19
|
+
from specfact_cli.utils.ide_setup import IDE_CONFIG, copy_templates_to_ide, detect_ide
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
app = typer.Typer(help="Initialize SpecFact for IDE integration")
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _is_valid_repo_path(path: Path) -> bool:
|
|
27
|
+
"""Check if path exists and is a directory."""
|
|
28
|
+
return path.exists() and path.is_dir()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.callback(invoke_without_command=True)
|
|
32
|
+
@require(lambda ide: ide in IDE_CONFIG or ide == "auto", "IDE must be valid or 'auto'")
|
|
33
|
+
@require(lambda repo: _is_valid_repo_path(repo), "Repo path must exist and be directory")
|
|
34
|
+
@ensure(lambda result: result is None, "Command should return None")
|
|
35
|
+
@beartype
|
|
36
|
+
def init(
|
|
37
|
+
ide: str = typer.Option(
|
|
38
|
+
"auto",
|
|
39
|
+
"--ide",
|
|
40
|
+
help="IDE type (auto, cursor, vscode, copilot, claude, gemini, qwen, opencode, windsurf, kilocode, auggie, roo, codebuddy, amp, q)",
|
|
41
|
+
),
|
|
42
|
+
repo: Path = typer.Option(
|
|
43
|
+
Path("."),
|
|
44
|
+
"--repo",
|
|
45
|
+
help="Repository path (default: current directory)",
|
|
46
|
+
exists=True,
|
|
47
|
+
file_okay=False,
|
|
48
|
+
dir_okay=True,
|
|
49
|
+
),
|
|
50
|
+
force: bool = typer.Option(
|
|
51
|
+
False,
|
|
52
|
+
"--force",
|
|
53
|
+
help="Overwrite existing files",
|
|
54
|
+
),
|
|
55
|
+
) -> None:
|
|
56
|
+
"""
|
|
57
|
+
Initialize SpecFact for IDE integration.
|
|
58
|
+
|
|
59
|
+
Copies prompt templates to IDE-specific locations so slash commands work.
|
|
60
|
+
This command detects the IDE type (or uses --ide flag) and copies
|
|
61
|
+
SpecFact prompt templates to the appropriate directory.
|
|
62
|
+
|
|
63
|
+
Examples:
|
|
64
|
+
specfact init # Auto-detect IDE
|
|
65
|
+
specfact init --ide cursor # Initialize for Cursor
|
|
66
|
+
specfact init --ide vscode --force # Overwrite existing files
|
|
67
|
+
specfact init --repo /path/to/repo --ide copilot
|
|
68
|
+
"""
|
|
69
|
+
telemetry_metadata = {
|
|
70
|
+
"ide": ide,
|
|
71
|
+
"force": force,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
with telemetry.track_command("init", telemetry_metadata) as record:
|
|
75
|
+
# Resolve repo path
|
|
76
|
+
repo_path = repo.resolve()
|
|
77
|
+
|
|
78
|
+
# Detect IDE
|
|
79
|
+
detected_ide = detect_ide(ide)
|
|
80
|
+
ide_config = IDE_CONFIG[detected_ide]
|
|
81
|
+
ide_name = ide_config["name"]
|
|
82
|
+
|
|
83
|
+
console.print()
|
|
84
|
+
console.print(Panel("[bold cyan]SpecFact IDE Setup[/bold cyan]", border_style="cyan"))
|
|
85
|
+
console.print(f"[cyan]Repository:[/cyan] {repo_path}")
|
|
86
|
+
console.print(f"[cyan]IDE:[/cyan] {ide_name} ({detected_ide})")
|
|
87
|
+
console.print()
|
|
88
|
+
|
|
89
|
+
# Find templates directory
|
|
90
|
+
# Try relative to project root first (for development)
|
|
91
|
+
templates_dir = repo_path / "resources" / "prompts"
|
|
92
|
+
if not templates_dir.exists():
|
|
93
|
+
# Try relative to installed package (for distribution)
|
|
94
|
+
import importlib.util
|
|
95
|
+
|
|
96
|
+
spec = importlib.util.find_spec("specfact_cli")
|
|
97
|
+
if spec and spec.origin:
|
|
98
|
+
package_dir = Path(spec.origin) #.parent.parent
|
|
99
|
+
templates_dir = package_dir / "resources" / "prompts"
|
|
100
|
+
if not templates_dir.exists():
|
|
101
|
+
# Fallback: try resources/prompts in project root
|
|
102
|
+
templates_dir = Path(__file__).parent.parent.parent.parent / "resources" / "prompts"
|
|
103
|
+
|
|
104
|
+
if not templates_dir.exists():
|
|
105
|
+
console.print(f"[red]Error:[/red] Templates directory not found: {templates_dir}")
|
|
106
|
+
console.print("[yellow]Expected location:[/yellow] resources/prompts/")
|
|
107
|
+
console.print("[yellow]Please ensure SpecFact is properly installed.[/yellow]")
|
|
108
|
+
raise typer.Exit(1)
|
|
109
|
+
|
|
110
|
+
console.print(f"[cyan]Templates:[/cyan] {templates_dir}")
|
|
111
|
+
console.print()
|
|
112
|
+
|
|
113
|
+
# Copy templates to IDE location
|
|
114
|
+
try:
|
|
115
|
+
copied_files, settings_path = copy_templates_to_ide(repo_path, detected_ide, templates_dir, force)
|
|
116
|
+
|
|
117
|
+
if not copied_files:
|
|
118
|
+
console.print(
|
|
119
|
+
"[yellow]No templates copied (all files already exist, use --force to overwrite)[/yellow]"
|
|
120
|
+
)
|
|
121
|
+
record({"files_copied": 0, "already_exists": True})
|
|
122
|
+
raise typer.Exit(0)
|
|
123
|
+
|
|
124
|
+
record(
|
|
125
|
+
{
|
|
126
|
+
"detected_ide": detected_ide,
|
|
127
|
+
"files_copied": len(copied_files),
|
|
128
|
+
"settings_updated": settings_path is not None,
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
console.print()
|
|
133
|
+
console.print(Panel("[bold green]✓ Initialization Complete[/bold green]", border_style="green"))
|
|
134
|
+
console.print(f"[green]Copied {len(copied_files)} template(s) to {ide_config['folder']}[/green]")
|
|
135
|
+
if settings_path:
|
|
136
|
+
console.print(f"[green]Updated VS Code settings:[/green] {settings_path}")
|
|
137
|
+
console.print()
|
|
138
|
+
console.print("[dim]You can now use SpecFact slash commands in your IDE![/dim]")
|
|
139
|
+
console.print("[dim]Example: /specfact-import-from-code --repo . --confidence 0.7[/dim]")
|
|
140
|
+
|
|
141
|
+
except Exception as e:
|
|
142
|
+
console.print(f"[red]Error:[/red] Failed to initialize IDE integration: {e}")
|
|
143
|
+
raise typer.Exit(1) from e
|