fips-agents-cli 0.1.9__tar.gz → 0.2.0__tar.gz
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.
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/.github/workflows/test.yml +2 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/.github/workflows/workflow.yaml +1 -1
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/PKG-INFO +17 -1
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/README.md +16 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/pyproject.toml +1 -1
- fips_agents_cli-0.2.0/src/fips_agents_cli/commands/create.py +447 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/commands/patch.py +15 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/git.py +60 -0
- fips_agents_cli-0.2.0/src/fips_agents_cli/tools/github.py +193 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/project.py +12 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/version.py +1 -1
- fips_agents_cli-0.2.0/tests/test_create.py +559 -0
- fips_agents_cli-0.2.0/tests/test_github.py +274 -0
- fips_agents_cli-0.1.9/src/fips_agents_cli/commands/create.py +0 -192
- fips_agents_cli-0.1.9/tests/test_create.py +0 -193
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/.claude/commands/create-release.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/.github/agents/README.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/.github/agents/create-release.agent.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/.gitignore +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/AGENT_FRAMEWORK_PLAN.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/BAML_RESEARCH_REPORT.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/CLAUDE.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/GENERATOR_IMPLEMENTATION_PLAN.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/IMPLEMENTATION_SUMMARY.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/Ignite-CLI-Architecture-Analysis.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/LICENSE +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/MVP-PLAN.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/PLAN.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/PROMPT_ISSUE.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/PUBLISHING.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/QUICK_START_PUBLISHING.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/RELEASE_CHECKLIST.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/scripts/README.md +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/scripts/release.sh +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/__init__.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/__main__.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/cli.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/commands/__init__.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/commands/generate.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/commands/model_car.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/__init__.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/filesystem.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/generators.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/patching.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/src/fips_agents_cli/tools/validation.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/__init__.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/conftest.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/test_filesystem.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/test_generate.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/test_generators.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/test_model_car.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/test_project.py +0 -0
- {fips_agents_cli-0.1.9 → fips_agents_cli-0.2.0}/tests/test_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fips-agents-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: CLI tool for creating and managing FIPS-compliant AI agent projects
|
|
5
5
|
Project-URL: Homepage, https://github.com/rdwj/fips-agents-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/rdwj/fips-agents-cli
|
|
@@ -528,6 +528,22 @@ MIT License - see LICENSE file for details
|
|
|
528
528
|
|
|
529
529
|
## Changelog
|
|
530
530
|
|
|
531
|
+
### Version 0.2.0
|
|
532
|
+
|
|
533
|
+
- Feature: GitHub integration for `create mcp-server` command
|
|
534
|
+
- Feature: New `--github` flag to create GitHub repository and push code
|
|
535
|
+
- Feature: New `--local` flag to skip GitHub and create local-only project
|
|
536
|
+
- Feature: Non-interactive mode (`--yes`) for agent/CI workflows
|
|
537
|
+
- Feature: New `--private` flag to create private GitHub repositories
|
|
538
|
+
- Feature: New `--org` option to create repositories in GitHub organizations
|
|
539
|
+
- Feature: New `--description` option for GitHub repository descriptions
|
|
540
|
+
- Feature: New `--remote-only` flag to create GitHub repo without local clone
|
|
541
|
+
- Feature: Added missing `patch build` subcommand for updating build/deployment files
|
|
542
|
+
- Feature: GitHub metadata tracking in `.template-info` file
|
|
543
|
+
- Feature: New git utilities for remote management (`add_remote`, `push_to_remote`)
|
|
544
|
+
- Improvement: Auto-detects `gh` CLI and prompts user when available
|
|
545
|
+
- Improvement: Clean git history - customizes project before initial push
|
|
546
|
+
|
|
531
547
|
### Version 0.1.9
|
|
532
548
|
|
|
533
549
|
- Feature: Added `.fips-agents-cli` directory to ModelCar projects with generation metadata
|
|
@@ -495,6 +495,22 @@ MIT License - see LICENSE file for details
|
|
|
495
495
|
|
|
496
496
|
## Changelog
|
|
497
497
|
|
|
498
|
+
### Version 0.2.0
|
|
499
|
+
|
|
500
|
+
- Feature: GitHub integration for `create mcp-server` command
|
|
501
|
+
- Feature: New `--github` flag to create GitHub repository and push code
|
|
502
|
+
- Feature: New `--local` flag to skip GitHub and create local-only project
|
|
503
|
+
- Feature: Non-interactive mode (`--yes`) for agent/CI workflows
|
|
504
|
+
- Feature: New `--private` flag to create private GitHub repositories
|
|
505
|
+
- Feature: New `--org` option to create repositories in GitHub organizations
|
|
506
|
+
- Feature: New `--description` option for GitHub repository descriptions
|
|
507
|
+
- Feature: New `--remote-only` flag to create GitHub repo without local clone
|
|
508
|
+
- Feature: Added missing `patch build` subcommand for updating build/deployment files
|
|
509
|
+
- Feature: GitHub metadata tracking in `.template-info` file
|
|
510
|
+
- Feature: New git utilities for remote management (`add_remote`, `push_to_remote`)
|
|
511
|
+
- Improvement: Auto-detects `gh` CLI and prompts user when available
|
|
512
|
+
- Improvement: Clean git history - customizes project before initial push
|
|
513
|
+
|
|
498
514
|
### Version 0.1.9
|
|
499
515
|
|
|
500
516
|
- Feature: Added `.fips-agents-cli` directory to ModelCar projects with generation metadata
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
"""Create command for generating new projects from templates."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.panel import Panel
|
|
8
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
9
|
+
|
|
10
|
+
from fips_agents_cli.commands.model_car import model_car
|
|
11
|
+
from fips_agents_cli.tools.filesystem import resolve_target_path, validate_target_directory
|
|
12
|
+
from fips_agents_cli.tools.git import (
|
|
13
|
+
add_remote,
|
|
14
|
+
clone_template,
|
|
15
|
+
init_repository,
|
|
16
|
+
is_git_installed,
|
|
17
|
+
push_to_remote,
|
|
18
|
+
)
|
|
19
|
+
from fips_agents_cli.tools.github import (
|
|
20
|
+
check_gh_prerequisites,
|
|
21
|
+
create_github_repo,
|
|
22
|
+
get_github_username,
|
|
23
|
+
is_gh_authenticated,
|
|
24
|
+
is_gh_installed,
|
|
25
|
+
)
|
|
26
|
+
from fips_agents_cli.tools.project import (
|
|
27
|
+
cleanup_template_files,
|
|
28
|
+
to_module_name,
|
|
29
|
+
update_project_name,
|
|
30
|
+
validate_project_name,
|
|
31
|
+
write_template_info,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
console = Console()
|
|
35
|
+
|
|
36
|
+
# Template URL for MCP server projects
|
|
37
|
+
MCP_SERVER_TEMPLATE_URL = "https://github.com/rdwj/mcp-server-template"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@click.group()
|
|
41
|
+
def create():
|
|
42
|
+
"""Create new projects from templates."""
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Register subcommands
|
|
47
|
+
create.add_command(model_car)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@create.command("mcp-server")
|
|
51
|
+
@click.argument("project_name")
|
|
52
|
+
@click.option(
|
|
53
|
+
"--target-dir",
|
|
54
|
+
"-t",
|
|
55
|
+
default=None,
|
|
56
|
+
help="Target directory for the project (default: current directory)",
|
|
57
|
+
)
|
|
58
|
+
@click.option(
|
|
59
|
+
"--no-git",
|
|
60
|
+
is_flag=True,
|
|
61
|
+
default=False,
|
|
62
|
+
help="Skip git repository initialization",
|
|
63
|
+
)
|
|
64
|
+
@click.option(
|
|
65
|
+
"--github",
|
|
66
|
+
"use_github",
|
|
67
|
+
is_flag=True,
|
|
68
|
+
default=False,
|
|
69
|
+
help="Create GitHub repository and push code",
|
|
70
|
+
)
|
|
71
|
+
@click.option(
|
|
72
|
+
"--local",
|
|
73
|
+
"use_local",
|
|
74
|
+
is_flag=True,
|
|
75
|
+
default=False,
|
|
76
|
+
help="Create local project only (skip GitHub)",
|
|
77
|
+
)
|
|
78
|
+
@click.option(
|
|
79
|
+
"--yes",
|
|
80
|
+
"-y",
|
|
81
|
+
is_flag=True,
|
|
82
|
+
default=False,
|
|
83
|
+
help="Non-interactive mode (use defaults, skip prompts)",
|
|
84
|
+
)
|
|
85
|
+
@click.option(
|
|
86
|
+
"--private",
|
|
87
|
+
is_flag=True,
|
|
88
|
+
default=False,
|
|
89
|
+
help="Make GitHub repository private (default: public)",
|
|
90
|
+
)
|
|
91
|
+
@click.option(
|
|
92
|
+
"--org",
|
|
93
|
+
default=None,
|
|
94
|
+
help="GitHub organization to create repository in",
|
|
95
|
+
)
|
|
96
|
+
@click.option(
|
|
97
|
+
"--description",
|
|
98
|
+
"-d",
|
|
99
|
+
"repo_description",
|
|
100
|
+
default=None,
|
|
101
|
+
help="GitHub repository description",
|
|
102
|
+
)
|
|
103
|
+
@click.option(
|
|
104
|
+
"--remote-only",
|
|
105
|
+
is_flag=True,
|
|
106
|
+
default=False,
|
|
107
|
+
help="Create GitHub repo only, don't clone locally",
|
|
108
|
+
)
|
|
109
|
+
def mcp_server(
|
|
110
|
+
project_name: str,
|
|
111
|
+
target_dir: str | None,
|
|
112
|
+
no_git: bool,
|
|
113
|
+
use_github: bool,
|
|
114
|
+
use_local: bool,
|
|
115
|
+
yes: bool,
|
|
116
|
+
private: bool,
|
|
117
|
+
org: str | None,
|
|
118
|
+
repo_description: str | None,
|
|
119
|
+
remote_only: bool,
|
|
120
|
+
):
|
|
121
|
+
"""
|
|
122
|
+
Create a new MCP server project from template.
|
|
123
|
+
|
|
124
|
+
PROJECT_NAME must start with a lowercase letter and contain only
|
|
125
|
+
lowercase letters, numbers, hyphens, and underscores.
|
|
126
|
+
|
|
127
|
+
By default, if GitHub CLI (gh) is installed and authenticated, prompts
|
|
128
|
+
to create a GitHub repository. Use --local to skip this, or --github
|
|
129
|
+
to require it. Use --yes for non-interactive mode (agents/CI).
|
|
130
|
+
|
|
131
|
+
Examples:
|
|
132
|
+
|
|
133
|
+
fips-agents create mcp-server my-mcp-server
|
|
134
|
+
|
|
135
|
+
fips-agents create mcp-server my-mcp-server --github --private
|
|
136
|
+
|
|
137
|
+
fips-agents create mcp-server my-mcp-server --local
|
|
138
|
+
|
|
139
|
+
fips-agents create mcp-server my-mcp-server --yes # Non-interactive
|
|
140
|
+
"""
|
|
141
|
+
try:
|
|
142
|
+
# Step 1: Validate options
|
|
143
|
+
if use_github and use_local:
|
|
144
|
+
console.print("[red]✗[/red] Cannot use --github and --local together")
|
|
145
|
+
sys.exit(1)
|
|
146
|
+
|
|
147
|
+
if remote_only and use_local:
|
|
148
|
+
console.print("[red]✗[/red] Cannot use --remote-only with --local")
|
|
149
|
+
sys.exit(1)
|
|
150
|
+
|
|
151
|
+
# Step 2: Validate project name
|
|
152
|
+
console.print("\n[bold cyan]Creating MCP Server Project[/bold cyan]\n")
|
|
153
|
+
|
|
154
|
+
is_valid, error_msg = validate_project_name(project_name)
|
|
155
|
+
if not is_valid:
|
|
156
|
+
console.print(f"[red]✗[/red] Invalid project name: {error_msg}")
|
|
157
|
+
sys.exit(1)
|
|
158
|
+
|
|
159
|
+
console.print(f"[green]✓[/green] Project name '{project_name}' is valid")
|
|
160
|
+
|
|
161
|
+
# Step 3: Determine mode (GitHub or local)
|
|
162
|
+
create_github = _determine_github_mode(use_github, use_local, yes)
|
|
163
|
+
|
|
164
|
+
# Step 4: Check prerequisites
|
|
165
|
+
if not is_git_installed():
|
|
166
|
+
console.print(
|
|
167
|
+
"[yellow]⚠[/yellow] Git is not installed. This is required for cloning templates."
|
|
168
|
+
)
|
|
169
|
+
console.print("[yellow]Hint:[/yellow] Install git from https://git-scm.com/downloads")
|
|
170
|
+
sys.exit(1)
|
|
171
|
+
|
|
172
|
+
if create_github:
|
|
173
|
+
ready, error_msg = check_gh_prerequisites()
|
|
174
|
+
if not ready:
|
|
175
|
+
console.print(f"[red]✗[/red] {error_msg}")
|
|
176
|
+
sys.exit(1)
|
|
177
|
+
|
|
178
|
+
# Step 5: Resolve and validate target directory (skip for remote-only)
|
|
179
|
+
target_path = None
|
|
180
|
+
if not remote_only:
|
|
181
|
+
target_path = resolve_target_path(project_name, target_dir)
|
|
182
|
+
|
|
183
|
+
is_valid, error_msg = validate_target_directory(target_path, allow_existing=False)
|
|
184
|
+
if not is_valid:
|
|
185
|
+
console.print(f"[red]✗[/red] {error_msg}")
|
|
186
|
+
console.print(
|
|
187
|
+
"\n[yellow]Hint:[/yellow] Choose a different name or remove the existing "
|
|
188
|
+
"directory"
|
|
189
|
+
)
|
|
190
|
+
sys.exit(1)
|
|
191
|
+
|
|
192
|
+
console.print(f"[green]✓[/green] Target directory: {target_path}")
|
|
193
|
+
|
|
194
|
+
# Step 6: Create GitHub repo first (if GitHub mode)
|
|
195
|
+
github_repo = None
|
|
196
|
+
github_url = None
|
|
197
|
+
if create_github:
|
|
198
|
+
success, github_url, error_msg = create_github_repo(
|
|
199
|
+
name=project_name,
|
|
200
|
+
private=private,
|
|
201
|
+
org=org,
|
|
202
|
+
description=repo_description,
|
|
203
|
+
)
|
|
204
|
+
if not success:
|
|
205
|
+
console.print(f"[red]✗[/red] {error_msg}")
|
|
206
|
+
sys.exit(1)
|
|
207
|
+
|
|
208
|
+
# Construct repo identifier
|
|
209
|
+
owner = org if org else get_github_username()
|
|
210
|
+
github_repo = f"{owner}/{project_name}"
|
|
211
|
+
|
|
212
|
+
# Step 7: Handle remote-only mode
|
|
213
|
+
if remote_only:
|
|
214
|
+
_show_remote_only_success(project_name, github_url, github_repo)
|
|
215
|
+
return
|
|
216
|
+
|
|
217
|
+
# Step 8: Clone template repository
|
|
218
|
+
template_commit = None
|
|
219
|
+
with Progress(
|
|
220
|
+
SpinnerColumn(),
|
|
221
|
+
TextColumn("[progress.description]{task.description}"),
|
|
222
|
+
console=console,
|
|
223
|
+
) as progress:
|
|
224
|
+
progress.add_task(description="Cloning template repository...", total=None)
|
|
225
|
+
try:
|
|
226
|
+
template_commit = clone_template(MCP_SERVER_TEMPLATE_URL, target_path)
|
|
227
|
+
except Exception as e:
|
|
228
|
+
console.print("\n[red]✗[/red] Failed to clone template repository")
|
|
229
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
230
|
+
console.print(
|
|
231
|
+
f"\n[yellow]Hint:[/yellow] Check your internet connection and verify "
|
|
232
|
+
f"the template URL is accessible:\n{MCP_SERVER_TEMPLATE_URL}"
|
|
233
|
+
)
|
|
234
|
+
sys.exit(1)
|
|
235
|
+
|
|
236
|
+
# Step 9: Customize project
|
|
237
|
+
with Progress(
|
|
238
|
+
SpinnerColumn(),
|
|
239
|
+
TextColumn("[progress.description]{task.description}"),
|
|
240
|
+
console=console,
|
|
241
|
+
) as progress:
|
|
242
|
+
progress.add_task(description="Customizing project...", total=None)
|
|
243
|
+
try:
|
|
244
|
+
update_project_name(target_path, project_name)
|
|
245
|
+
cleanup_template_files(target_path)
|
|
246
|
+
if template_commit:
|
|
247
|
+
write_template_info(
|
|
248
|
+
target_path,
|
|
249
|
+
project_name,
|
|
250
|
+
MCP_SERVER_TEMPLATE_URL,
|
|
251
|
+
template_commit,
|
|
252
|
+
github_repo=github_repo,
|
|
253
|
+
github_url=github_url,
|
|
254
|
+
)
|
|
255
|
+
except Exception as e:
|
|
256
|
+
console.print("\n[red]✗[/red] Failed to customize project")
|
|
257
|
+
console.print(f"[red]Error:[/red] {e}")
|
|
258
|
+
sys.exit(1)
|
|
259
|
+
|
|
260
|
+
# Step 10: Initialize git repository
|
|
261
|
+
if not no_git:
|
|
262
|
+
with Progress(
|
|
263
|
+
SpinnerColumn(),
|
|
264
|
+
TextColumn("[progress.description]{task.description}"),
|
|
265
|
+
console=console,
|
|
266
|
+
) as progress:
|
|
267
|
+
progress.add_task(description="Initializing git repository...", total=None)
|
|
268
|
+
try:
|
|
269
|
+
init_repository(target_path, initial_commit=True)
|
|
270
|
+
except Exception as e:
|
|
271
|
+
console.print("\n[yellow]⚠[/yellow] Failed to initialize git repository")
|
|
272
|
+
console.print(f"[yellow]Warning:[/yellow] {e}")
|
|
273
|
+
console.print(
|
|
274
|
+
"[yellow]You can initialize git manually later with:[/yellow] git init"
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
# Step 11: Push to GitHub (if GitHub mode)
|
|
278
|
+
if create_github and not no_git:
|
|
279
|
+
try:
|
|
280
|
+
add_remote(target_path, "origin", github_url)
|
|
281
|
+
push_success = push_to_remote(target_path, "origin", "main")
|
|
282
|
+
if not push_success:
|
|
283
|
+
console.print(
|
|
284
|
+
"\n[yellow]⚠[/yellow] Failed to push to GitHub. "
|
|
285
|
+
"You can push manually with: git push -u origin main"
|
|
286
|
+
)
|
|
287
|
+
except Exception as e:
|
|
288
|
+
console.print(f"\n[yellow]⚠[/yellow] Failed to set up GitHub remote: {e}")
|
|
289
|
+
console.print("[yellow]You can add the remote manually with:[/yellow]")
|
|
290
|
+
console.print(f" git remote add origin {github_url}")
|
|
291
|
+
console.print(" git push -u origin main")
|
|
292
|
+
|
|
293
|
+
# Step 12: Success message
|
|
294
|
+
_show_success_message(
|
|
295
|
+
project_name=project_name,
|
|
296
|
+
target_path=target_path,
|
|
297
|
+
github_url=github_url,
|
|
298
|
+
github_repo=github_repo,
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
except KeyboardInterrupt:
|
|
302
|
+
console.print("\n[yellow]⚠[/yellow] Operation cancelled by user")
|
|
303
|
+
sys.exit(130)
|
|
304
|
+
except Exception as e:
|
|
305
|
+
console.print(f"\n[red]✗[/red] Unexpected error: {e}")
|
|
306
|
+
sys.exit(1)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def _determine_github_mode(use_github: bool, use_local: bool, yes: bool) -> bool:
|
|
310
|
+
"""
|
|
311
|
+
Determine whether to create a GitHub repository.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
use_github: --github flag was set
|
|
315
|
+
use_local: --local flag was set
|
|
316
|
+
yes: --yes flag was set (non-interactive mode)
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
bool: True if GitHub repository should be created
|
|
320
|
+
"""
|
|
321
|
+
# Explicit flags take precedence
|
|
322
|
+
if use_local:
|
|
323
|
+
console.print("[dim]Mode: Local only (--local)[/dim]")
|
|
324
|
+
return False
|
|
325
|
+
|
|
326
|
+
if use_github:
|
|
327
|
+
console.print("[dim]Mode: GitHub (--github)[/dim]")
|
|
328
|
+
return True
|
|
329
|
+
|
|
330
|
+
# Check if gh is available
|
|
331
|
+
if not is_gh_installed():
|
|
332
|
+
console.print("[dim]Mode: Local only (GitHub CLI not installed)[/dim]")
|
|
333
|
+
return False
|
|
334
|
+
|
|
335
|
+
if not is_gh_authenticated():
|
|
336
|
+
console.print("[dim]Mode: Local only (GitHub CLI not authenticated)[/dim]")
|
|
337
|
+
return False
|
|
338
|
+
|
|
339
|
+
# gh is available - decide based on interactive mode
|
|
340
|
+
if yes:
|
|
341
|
+
# Non-interactive: default to GitHub
|
|
342
|
+
console.print("[dim]Mode: GitHub (--yes with gh available)[/dim]")
|
|
343
|
+
return True
|
|
344
|
+
|
|
345
|
+
# Interactive: prompt user
|
|
346
|
+
console.print("[cyan]GitHub CLI detected and authenticated.[/cyan]")
|
|
347
|
+
return click.confirm("Create GitHub repository?", default=True)
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _show_success_message(
|
|
351
|
+
project_name: str,
|
|
352
|
+
target_path,
|
|
353
|
+
github_url: str | None,
|
|
354
|
+
github_repo: str | None,
|
|
355
|
+
) -> None:
|
|
356
|
+
"""Display success message with next steps."""
|
|
357
|
+
module_name = to_module_name(project_name)
|
|
358
|
+
|
|
359
|
+
# Build project details section
|
|
360
|
+
details = f""" • Name: {project_name}
|
|
361
|
+
• Module: {module_name}
|
|
362
|
+
• Location: {target_path}"""
|
|
363
|
+
|
|
364
|
+
if github_url:
|
|
365
|
+
details += f"\n • GitHub: {github_url}"
|
|
366
|
+
|
|
367
|
+
# Build next steps based on mode
|
|
368
|
+
if github_url:
|
|
369
|
+
next_steps = f"""
|
|
370
|
+
1. Navigate to your project:
|
|
371
|
+
[dim]cd {target_path.name}[/dim]
|
|
372
|
+
|
|
373
|
+
2. Create and activate a virtual environment:
|
|
374
|
+
[dim]python -m venv venv[/dim]
|
|
375
|
+
[dim]source venv/bin/activate[/dim] # On Windows: venv\\Scripts\\activate
|
|
376
|
+
|
|
377
|
+
3. Install the project in editable mode:
|
|
378
|
+
[dim]pip install -e .[dev][/dim]
|
|
379
|
+
|
|
380
|
+
4. Start developing your MCP server!
|
|
381
|
+
[dim]Your code is already pushed to GitHub[/dim]
|
|
382
|
+
|
|
383
|
+
5. Run tests:
|
|
384
|
+
[dim]pytest[/dim]"""
|
|
385
|
+
else:
|
|
386
|
+
next_steps = f"""
|
|
387
|
+
1. Navigate to your project:
|
|
388
|
+
[dim]cd {target_path.name}[/dim]
|
|
389
|
+
|
|
390
|
+
2. Create and activate a virtual environment:
|
|
391
|
+
[dim]python -m venv venv[/dim]
|
|
392
|
+
[dim]source venv/bin/activate[/dim] # On Windows: venv\\Scripts\\activate
|
|
393
|
+
|
|
394
|
+
3. Install the project in editable mode:
|
|
395
|
+
[dim]pip install -e .[dev][/dim]
|
|
396
|
+
|
|
397
|
+
4. Start developing your MCP server!
|
|
398
|
+
[dim]Edit src/ files to add your functionality[/dim]
|
|
399
|
+
|
|
400
|
+
5. Run tests:
|
|
401
|
+
[dim]pytest[/dim]"""
|
|
402
|
+
|
|
403
|
+
success_message = f"""
|
|
404
|
+
[bold green]✓ Successfully created MCP server project![/bold green]
|
|
405
|
+
|
|
406
|
+
[bold cyan]Project Details:[/bold cyan]
|
|
407
|
+
{details}
|
|
408
|
+
|
|
409
|
+
[bold cyan]Next Steps:[/bold cyan]
|
|
410
|
+
{next_steps}
|
|
411
|
+
|
|
412
|
+
[bold cyan]Documentation:[/bold cyan]
|
|
413
|
+
• Check the README.md in your project for detailed instructions
|
|
414
|
+
• MCP Protocol docs: https://modelcontextprotocol.io/
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
console.print(Panel(success_message, border_style="green", padding=(1, 2)))
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def _show_remote_only_success(
|
|
421
|
+
project_name: str,
|
|
422
|
+
github_url: str,
|
|
423
|
+
github_repo: str,
|
|
424
|
+
) -> None:
|
|
425
|
+
"""Display success message for remote-only mode."""
|
|
426
|
+
success_message = f"""
|
|
427
|
+
[bold green]✓ Successfully created GitHub repository![/bold green]
|
|
428
|
+
|
|
429
|
+
[bold cyan]Repository Details:[/bold cyan]
|
|
430
|
+
• Name: {project_name}
|
|
431
|
+
• GitHub: {github_url}
|
|
432
|
+
|
|
433
|
+
[bold cyan]Next Steps:[/bold cyan]
|
|
434
|
+
|
|
435
|
+
1. Clone the repository:
|
|
436
|
+
[dim]git clone {github_url}[/dim]
|
|
437
|
+
[dim]cd {project_name}[/dim]
|
|
438
|
+
|
|
439
|
+
2. The repository contains the MCP server template.
|
|
440
|
+
Customize it for your project.
|
|
441
|
+
|
|
442
|
+
[bold cyan]Note:[/bold cyan]
|
|
443
|
+
The repository contains the raw template.
|
|
444
|
+
You may want to customize project names and paths.
|
|
445
|
+
"""
|
|
446
|
+
|
|
447
|
+
console.print(Panel(success_message, border_style="green", padding=(1, 2)))
|
|
@@ -119,6 +119,21 @@ def docs(dry_run: bool):
|
|
|
119
119
|
_patch_category("docs", dry_run)
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
@patch.command("build")
|
|
123
|
+
@click.option(
|
|
124
|
+
"--dry-run",
|
|
125
|
+
is_flag=True,
|
|
126
|
+
help="Show what would be updated without making changes",
|
|
127
|
+
)
|
|
128
|
+
def build(dry_run: bool):
|
|
129
|
+
"""
|
|
130
|
+
Update build and deployment files (Makefile, Containerfile, etc).
|
|
131
|
+
|
|
132
|
+
Shows diffs and asks for confirmation before applying changes.
|
|
133
|
+
"""
|
|
134
|
+
_patch_category("build", dry_run)
|
|
135
|
+
|
|
136
|
+
|
|
122
137
|
@patch.command("all")
|
|
123
138
|
@click.option(
|
|
124
139
|
"--dry-run",
|
|
@@ -106,3 +106,63 @@ def is_git_installed() -> bool:
|
|
|
106
106
|
return True
|
|
107
107
|
except (git.GitCommandNotFound, git.GitCommandError):
|
|
108
108
|
return False
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def add_remote(project_path: Path, name: str, url: str) -> None:
|
|
112
|
+
"""
|
|
113
|
+
Add a remote to an existing git repository.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
project_path: Path to the project directory
|
|
117
|
+
name: Name of the remote (e.g., "origin")
|
|
118
|
+
url: URL of the remote repository
|
|
119
|
+
|
|
120
|
+
Raises:
|
|
121
|
+
git.GitCommandError: If the remote operation fails
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
repo = git.Repo(str(project_path))
|
|
125
|
+
repo.create_remote(name, url)
|
|
126
|
+
console.print(f"[green]✓[/green] Added remote '{name}': {url}")
|
|
127
|
+
except git.GitCommandError as e:
|
|
128
|
+
console.print(f"[red]✗[/red] Failed to add remote: {e}")
|
|
129
|
+
raise
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def push_to_remote(
|
|
133
|
+
project_path: Path,
|
|
134
|
+
remote: str = "origin",
|
|
135
|
+
branch: str = "main",
|
|
136
|
+
set_upstream: bool = True,
|
|
137
|
+
) -> bool:
|
|
138
|
+
"""
|
|
139
|
+
Push the current branch to a remote repository.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
project_path: Path to the project directory
|
|
143
|
+
remote: Name of the remote (default: "origin")
|
|
144
|
+
branch: Name of the branch to push (default: "main")
|
|
145
|
+
set_upstream: Whether to set the upstream tracking branch (default: True)
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
bool: True if push was successful, False otherwise
|
|
149
|
+
"""
|
|
150
|
+
try:
|
|
151
|
+
repo = git.Repo(str(project_path))
|
|
152
|
+
remote_obj = repo.remote(remote)
|
|
153
|
+
|
|
154
|
+
console.print(f"[cyan]Pushing to {remote}/{branch}...[/cyan]")
|
|
155
|
+
|
|
156
|
+
if set_upstream:
|
|
157
|
+
remote_obj.push(branch, set_upstream=True)
|
|
158
|
+
else:
|
|
159
|
+
remote_obj.push(branch)
|
|
160
|
+
|
|
161
|
+
console.print(f"[green]✓[/green] Pushed to {remote}/{branch}")
|
|
162
|
+
return True
|
|
163
|
+
except git.GitCommandError as e:
|
|
164
|
+
console.print(f"[red]✗[/red] Failed to push: {e}")
|
|
165
|
+
return False
|
|
166
|
+
except Exception as e:
|
|
167
|
+
console.print(f"[red]✗[/red] Unexpected error during push: {e}")
|
|
168
|
+
return False
|