Skip to content

Commit eb40511

Browse files
niechenclaude
andcommitted
fix: resolve linting errors and test failures after AI-agent CLI updates
- Fix unused variable in generate_llm_txt.py - Clean up whitespace in docstrings throughout non_interactive.py - Fix edit command to properly exit with return codes using sys.exit() - Update tests to correctly mock non-interactive detection - Fix client edit test to avoid non-interactive mode for external editor test - Update test assertions to match new simplified help text All tests now pass (113 passed, 6 skipped) and linting is clean. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 2d8b46a commit eb40511

File tree

9 files changed

+320
-305
lines changed

9 files changed

+320
-305
lines changed

scripts/generate_llm_txt.py

Lines changed: 114 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
from pathlib import Path
1313

1414
# Add src to path so we can import mcpm modules
15-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
15+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src"))
1616

1717
import click
18+
1819
from mcpm.cli import main as mcpm_cli
1920

2021
# Try to import version, fallback to a default if not available
@@ -27,75 +28,75 @@
2728
def extract_command_info(cmd, parent_name=""):
2829
"""Extract information from a Click command."""
2930
info = {
30-
'name': cmd.name,
31-
'full_name': f"{parent_name} {cmd.name}".strip(),
32-
'help': cmd.help or "No description available",
33-
'params': [],
34-
'subcommands': {}
31+
"name": cmd.name,
32+
"full_name": f"{parent_name} {cmd.name}".strip(),
33+
"help": cmd.help or "No description available",
34+
"params": [],
35+
"subcommands": {}
3536
}
36-
37+
3738
# Extract parameters
3839
for param in cmd.params:
3940
param_info = {
40-
'name': param.name,
41-
'opts': getattr(param, 'opts', None) or [param.name],
42-
'type': str(param.type),
43-
'help': getattr(param, 'help', "") or "",
44-
'required': getattr(param, 'required', False),
45-
'is_flag': isinstance(param, click.Option) and param.is_flag,
46-
'default': getattr(param, 'default', None)
41+
"name": param.name,
42+
"opts": getattr(param, "opts", None) or [param.name],
43+
"type": str(param.type),
44+
"help": getattr(param, "help", "") or "",
45+
"required": getattr(param, "required", False),
46+
"is_flag": isinstance(param, click.Option) and param.is_flag,
47+
"default": getattr(param, "default", None)
4748
}
48-
info['params'].append(param_info)
49-
49+
info["params"].append(param_info)
50+
5051
# Extract subcommands if this is a group
5152
if isinstance(cmd, click.Group):
5253
for subcommand_name, subcommand in cmd.commands.items():
53-
info['subcommands'][subcommand_name] = extract_command_info(
54-
subcommand,
55-
info['full_name']
54+
info["subcommands"][subcommand_name] = extract_command_info(
55+
subcommand,
56+
info["full_name"]
5657
)
57-
58+
5859
return info
5960

6061

6162
def format_command_section(cmd_info, level=2):
6263
"""Format a command's information for the LLM.txt file."""
6364
lines = []
64-
65+
6566
# Command header
6667
header = "#" * level + f" {cmd_info['full_name']}"
6768
lines.append(header)
6869
lines.append("")
69-
70+
7071
# Description
71-
lines.append(cmd_info['help'])
72+
lines.append(cmd_info["help"])
7273
lines.append("")
73-
74+
7475
# Parameters
75-
if cmd_info['params']:
76+
if cmd_info["params"]:
7677
lines.append("**Parameters:**")
7778
lines.append("")
78-
79+
7980
# Separate arguments from options
80-
args = [p for p in cmd_info['params'] if not p['opts'][0].startswith('-')]
81-
opts = [p for p in cmd_info['params'] if p['opts'][0].startswith('-')]
82-
81+
args = [p for p in cmd_info["params"] if not p["opts"][0].startswith("-")]
82+
opts = [p for p in cmd_info["params"] if p["opts"][0].startswith("-")]
83+
8384
if args:
8485
for param in args:
85-
req = "REQUIRED" if param['required'] else "OPTIONAL"
86+
req = "REQUIRED" if param["required"] else "OPTIONAL"
8687
lines.append(f"- `{param['name']}` ({req}): {param['help']}")
8788
lines.append("")
88-
89+
8990
if opts:
9091
for param in opts:
91-
opt_str = ", ".join(f"`{opt}`" for opt in param['opts'])
92-
if param['is_flag']:
92+
opt_str = ", ".join(f"`{opt}`" for opt in param["opts"])
93+
if param["is_flag"]:
9394
lines.append(f"- {opt_str}: {param['help']} (flag)")
9495
else:
95-
default_str = f" (default: {param['default']})" if param['default'] is not None else ""
96+
default_str = f" (default: {param['default']})" if param["default"] is not None else ""
9697
lines.append(f"- {opt_str}: {param['help']}{default_str}")
9798
lines.append("")
98-
99+
99100
# Examples section
100101
examples = generate_examples_for_command(cmd_info)
101102
if examples:
@@ -105,101 +106,100 @@ def format_command_section(cmd_info, level=2):
105106
lines.extend(examples)
106107
lines.append("```")
107108
lines.append("")
108-
109+
109110
# Subcommands
110-
for subcmd_info in cmd_info['subcommands'].values():
111+
for subcmd_info in cmd_info["subcommands"].values():
111112
lines.extend(format_command_section(subcmd_info, level + 1))
112-
113+
113114
return lines
114115

115116

116117
def generate_examples_for_command(cmd_info):
117118
"""Generate relevant examples for a command based on its name and parameters."""
118-
examples = []
119-
cmd = cmd_info['full_name']
120-
119+
cmd = cmd_info["full_name"]
120+
121121
# Map of command patterns to example sets
122122
example_map = {
123-
'mcpm new': [
124-
'# Create a stdio server',
123+
"mcpm new": [
124+
"# Create a stdio server",
125125
'mcpm new myserver --type stdio --command "python -m myserver"',
126-
'',
127-
'# Create a remote server',
126+
"",
127+
"# Create a remote server",
128128
'mcpm new apiserver --type remote --url "https://api.example.com"',
129-
'',
130-
'# Create server with environment variables',
129+
"",
130+
"# Create server with environment variables",
131131
'mcpm new myserver --type stdio --command "python server.py" --env "API_KEY=secret,PORT=8080"',
132132
],
133-
'mcpm edit': [
134-
'# Update server name',
133+
"mcpm edit": [
134+
"# Update server name",
135135
'mcpm edit myserver --name "new-name"',
136-
'',
137-
'# Update command and arguments',
136+
"",
137+
"# Update command and arguments",
138138
'mcpm edit myserver --command "python -m updated_server" --args "--port 8080"',
139-
'',
140-
'# Update environment variables',
139+
"",
140+
"# Update environment variables",
141141
'mcpm edit myserver --env "API_KEY=new-secret,DEBUG=true"',
142142
],
143-
'mcpm install': [
144-
'# Install a server',
145-
'mcpm install sqlite',
146-
'',
147-
'# Install with environment variables',
148-
'ANTHROPIC_API_KEY=sk-ant-... mcpm install claude',
149-
'',
150-
'# Force installation',
151-
'mcpm install filesystem --force',
143+
"mcpm install": [
144+
"# Install a server",
145+
"mcpm install sqlite",
146+
"",
147+
"# Install with environment variables",
148+
"ANTHROPIC_API_KEY=sk-ant-... mcpm install claude",
149+
"",
150+
"# Force installation",
151+
"mcpm install filesystem --force",
152152
],
153-
'mcpm profile edit': [
154-
'# Add server to profile',
155-
'mcpm profile edit web-dev --add-server sqlite',
156-
'',
157-
'# Remove server from profile',
158-
'mcpm profile edit web-dev --remove-server old-server',
159-
'',
160-
'# Set profile servers (replaces all)',
153+
"mcpm profile edit": [
154+
"# Add server to profile",
155+
"mcpm profile edit web-dev --add-server sqlite",
156+
"",
157+
"# Remove server from profile",
158+
"mcpm profile edit web-dev --remove-server old-server",
159+
"",
160+
"# Set profile servers (replaces all)",
161161
'mcpm profile edit web-dev --set-servers "sqlite,filesystem,git"',
162-
'',
163-
'# Rename profile',
164-
'mcpm profile edit old-name --name new-name',
162+
"",
163+
"# Rename profile",
164+
"mcpm profile edit old-name --name new-name",
165165
],
166-
'mcpm client edit': [
167-
'# Add server to client',
168-
'mcpm client edit cursor --add-server sqlite',
169-
'',
170-
'# Add profile to client',
171-
'mcpm client edit cursor --add-profile web-dev',
172-
'',
173-
'# Set all servers for client',
166+
"mcpm client edit": [
167+
"# Add server to client",
168+
"mcpm client edit cursor --add-server sqlite",
169+
"",
170+
"# Add profile to client",
171+
"mcpm client edit cursor --add-profile web-dev",
172+
"",
173+
"# Set all servers for client",
174174
'mcpm client edit claude-desktop --set-servers "sqlite,filesystem"',
175-
'',
176-
'# Remove profile from client',
177-
'mcpm client edit cursor --remove-profile old-profile',
175+
"",
176+
"# Remove profile from client",
177+
"mcpm client edit cursor --remove-profile old-profile",
178178
],
179-
'mcpm run': [
180-
'# Run a server',
181-
'mcpm run sqlite',
182-
'',
183-
'# Run with HTTP transport',
184-
'mcpm run myserver --http --port 8080',
179+
"mcpm run": [
180+
"# Run a server",
181+
"mcpm run sqlite",
182+
"",
183+
"# Run with HTTP transport",
184+
"mcpm run myserver --http --port 8080",
185185
],
186-
'mcpm profile run': [
187-
'# Run all servers in a profile',
188-
'mcpm profile run web-dev',
189-
'',
190-
'# Run profile with custom port',
191-
'mcpm profile run web-dev --port 8080 --http',
186+
"mcpm profile run": [
187+
"# Run all servers in a profile",
188+
"mcpm profile run web-dev",
189+
"",
190+
"# Run profile with custom port",
191+
"mcpm profile run web-dev --port 8080 --http",
192192
],
193193
}
194-
194+
195195
# Return examples if we have them for this command
196196
if cmd in example_map:
197197
return example_map[cmd]
198-
198+
199199
# Generate basic example if no specific examples
200-
if cmd_info['params']:
201-
return [f"# Basic usage", f"{cmd} <arguments>"]
202-
200+
if cmd_info["params"]:
201+
return ["# Basic usage", f"{cmd} <arguments>"]
202+
203203
return []
204204

205205

@@ -241,15 +241,15 @@ def generate_llm_txt():
241241
"## Command Reference",
242242
"",
243243
]
244-
244+
245245
# Extract command structure
246246
cmd_info = extract_command_info(mcpm_cli)
247-
247+
248248
# Format main commands
249-
for subcmd_name in sorted(cmd_info['subcommands'].keys()):
250-
subcmd_info = cmd_info['subcommands'][subcmd_name]
249+
for subcmd_name in sorted(cmd_info["subcommands"].keys()):
250+
subcmd_info = cmd_info["subcommands"][subcmd_name]
251251
lines.extend(format_command_section(subcmd_info))
252-
252+
253253
# Add best practices section
254254
lines.extend([
255255
"## Best Practices for AI Agents",
@@ -318,10 +318,10 @@ def generate_llm_txt():
318318
"",
319319
"```bash",
320320
"# Add multiple servers at once",
321-
"mcpm profile edit myprofile --add-server \"server1,server2,server3\"",
321+
'mcpm profile edit myprofile --add-server "server1,server2,server3"',
322322
"",
323323
"# Remove multiple servers",
324-
"mcpm client edit cursor --remove-server \"old1,old2\"",
324+
'mcpm client edit cursor --remove-server "old1,old2"',
325325
"```",
326326
"",
327327
"### Using Environment Variables for Secrets",
@@ -374,27 +374,27 @@ def generate_llm_txt():
374374
"- Use `mcpm doctor` to diagnose system issues",
375375
"",
376376
])
377-
377+
378378
return "\n".join(lines)
379379

380380

381381
def main():
382382
"""Generate and save the LLM.txt file."""
383383
content = generate_llm_txt()
384-
384+
385385
# Determine output path
386386
script_dir = Path(__file__).parent
387387
project_root = script_dir.parent
388388
output_path = project_root / "llm.txt"
389-
389+
390390
# Write the file
391-
with open(output_path, 'w', encoding='utf-8') as f:
391+
with open(output_path, "w", encoding="utf-8") as f:
392392
f.write(content)
393-
393+
394394
print(f"✅ Generated llm.txt at: {output_path}")
395395
print(f"📄 File size: {len(content):,} bytes")
396396
print(f"📝 Lines: {content.count(chr(10)):,}")
397397

398398

399399
if __name__ == "__main__":
400-
main()
400+
main()

0 commit comments

Comments
 (0)