hatch-xclam 0.7.0.dev13__py3-none-any.whl → 0.7.1.dev1__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.
- hatch/cli_hatch.py +31 -0
- hatch/mcp_host_config/__init__.py +2 -2
- hatch/mcp_host_config/backup.py +1 -1
- hatch/mcp_host_config/models.py +32 -1
- hatch/mcp_host_config/strategies.py +96 -0
- {hatch_xclam-0.7.0.dev13.dist-info → hatch_xclam-0.7.1.dev1.dist-info}/METADATA +4 -3
- {hatch_xclam-0.7.0.dev13.dist-info → hatch_xclam-0.7.1.dev1.dist-info}/RECORD +21 -12
- tests/integration/__init__.py +5 -0
- tests/integration/test_mcp_kiro_integration.py +153 -0
- tests/regression/__init__.py +5 -0
- tests/regression/test_mcp_kiro_backup_integration.py +241 -0
- tests/regression/test_mcp_kiro_cli_integration.py +141 -0
- tests/regression/test_mcp_kiro_decorator_registration.py +71 -0
- tests/regression/test_mcp_kiro_host_strategy.py +214 -0
- tests/regression/test_mcp_kiro_model_validation.py +116 -0
- tests/regression/test_mcp_kiro_omni_conversion.py +104 -0
- tests/test_data_utils.py +108 -0
- {hatch_xclam-0.7.0.dev13.dist-info → hatch_xclam-0.7.1.dev1.dist-info}/WHEEL +0 -0
- {hatch_xclam-0.7.0.dev13.dist-info → hatch_xclam-0.7.1.dev1.dist-info}/entry_points.txt +0 -0
- {hatch_xclam-0.7.0.dev13.dist-info → hatch_xclam-0.7.1.dev1.dist-info}/licenses/LICENSE +0 -0
- {hatch_xclam-0.7.0.dev13.dist-info → hatch_xclam-0.7.1.dev1.dist-info}/top_level.txt +0 -0
hatch/cli_hatch.py
CHANGED
|
@@ -713,6 +713,9 @@ def handle_mcp_configure(
|
|
|
713
713
|
include_tools: Optional[list] = None,
|
|
714
714
|
exclude_tools: Optional[list] = None,
|
|
715
715
|
input: Optional[list] = None,
|
|
716
|
+
disabled: Optional[bool] = None,
|
|
717
|
+
auto_approve_tools: Optional[list] = None,
|
|
718
|
+
disable_tools: Optional[list] = None,
|
|
716
719
|
no_backup: bool = False,
|
|
717
720
|
dry_run: bool = False,
|
|
718
721
|
auto_approve: bool = False,
|
|
@@ -826,6 +829,14 @@ def handle_mcp_configure(
|
|
|
826
829
|
if inputs_list is not None:
|
|
827
830
|
omni_config_data["inputs"] = inputs_list
|
|
828
831
|
|
|
832
|
+
# Host-specific fields (Kiro)
|
|
833
|
+
if disabled is not None:
|
|
834
|
+
omni_config_data["disabled"] = disabled
|
|
835
|
+
if auto_approve_tools is not None:
|
|
836
|
+
omni_config_data["autoApprove"] = auto_approve_tools
|
|
837
|
+
if disable_tools is not None:
|
|
838
|
+
omni_config_data["disabledTools"] = disable_tools
|
|
839
|
+
|
|
829
840
|
# Partial update merge logic
|
|
830
841
|
if is_update:
|
|
831
842
|
# Merge with existing configuration
|
|
@@ -1625,6 +1636,23 @@ def main():
|
|
|
1625
1636
|
help="Input variable definitions in format: type,id,description[,password=true] (VS Code)",
|
|
1626
1637
|
)
|
|
1627
1638
|
|
|
1639
|
+
# Host-specific arguments (Kiro)
|
|
1640
|
+
mcp_configure_parser.add_argument(
|
|
1641
|
+
"--disabled",
|
|
1642
|
+
action="store_true",
|
|
1643
|
+
help="Disable the MCP server (Kiro)"
|
|
1644
|
+
)
|
|
1645
|
+
mcp_configure_parser.add_argument(
|
|
1646
|
+
"--auto-approve-tools",
|
|
1647
|
+
action="append",
|
|
1648
|
+
help="Tool names to auto-approve without prompting (Kiro)"
|
|
1649
|
+
)
|
|
1650
|
+
mcp_configure_parser.add_argument(
|
|
1651
|
+
"--disable-tools",
|
|
1652
|
+
action="append",
|
|
1653
|
+
help="Tool names to disable (Kiro)"
|
|
1654
|
+
)
|
|
1655
|
+
|
|
1628
1656
|
mcp_configure_parser.add_argument(
|
|
1629
1657
|
"--no-backup",
|
|
1630
1658
|
action="store_true",
|
|
@@ -2693,6 +2721,9 @@ def main():
|
|
|
2693
2721
|
getattr(args, "include_tools", None),
|
|
2694
2722
|
getattr(args, "exclude_tools", None),
|
|
2695
2723
|
getattr(args, "input", None),
|
|
2724
|
+
getattr(args, "disabled", None),
|
|
2725
|
+
getattr(args, "auto_approve_tools", None),
|
|
2726
|
+
getattr(args, "disable_tools", None),
|
|
2696
2727
|
args.no_backup,
|
|
2697
2728
|
args.dry_run,
|
|
2698
2729
|
args.auto_approve,
|
|
@@ -11,7 +11,7 @@ from .models import (
|
|
|
11
11
|
PackageHostConfiguration, EnvironmentPackageEntry, ConfigurationResult, SyncResult,
|
|
12
12
|
# Host-specific configuration models
|
|
13
13
|
MCPServerConfigBase, MCPServerConfigGemini, MCPServerConfigVSCode,
|
|
14
|
-
MCPServerConfigCursor, MCPServerConfigClaude, MCPServerConfigOmni,
|
|
14
|
+
MCPServerConfigCursor, MCPServerConfigClaude, MCPServerConfigKiro, MCPServerConfigOmni,
|
|
15
15
|
HOST_MODEL_REGISTRY
|
|
16
16
|
)
|
|
17
17
|
from .host_management import (
|
|
@@ -30,7 +30,7 @@ __all__ = [
|
|
|
30
30
|
'PackageHostConfiguration', 'EnvironmentPackageEntry', 'ConfigurationResult', 'SyncResult',
|
|
31
31
|
# Host-specific configuration models
|
|
32
32
|
'MCPServerConfigBase', 'MCPServerConfigGemini', 'MCPServerConfigVSCode',
|
|
33
|
-
'MCPServerConfigCursor', 'MCPServerConfigClaude', 'MCPServerConfigOmni',
|
|
33
|
+
'MCPServerConfigCursor', 'MCPServerConfigClaude', 'MCPServerConfigKiro', 'MCPServerConfigOmni',
|
|
34
34
|
'HOST_MODEL_REGISTRY',
|
|
35
35
|
# User feedback reporting
|
|
36
36
|
'FieldOperation', 'ConversionReport', 'generate_conversion_report', 'display_report',
|
hatch/mcp_host_config/backup.py
CHANGED
|
@@ -37,7 +37,7 @@ class BackupInfo(BaseModel):
|
|
|
37
37
|
"""Validate hostname is supported."""
|
|
38
38
|
supported_hosts = {
|
|
39
39
|
'claude-desktop', 'claude-code', 'vscode',
|
|
40
|
-
'cursor', 'lmstudio', 'gemini'
|
|
40
|
+
'cursor', 'lmstudio', 'gemini', 'kiro'
|
|
41
41
|
}
|
|
42
42
|
if v not in supported_hosts:
|
|
43
43
|
raise ValueError(f"Unsupported hostname: {v}. Supported: {supported_hosts}")
|
hatch/mcp_host_config/models.py
CHANGED
|
@@ -24,6 +24,7 @@ class MCPHostType(str, Enum):
|
|
|
24
24
|
CURSOR = "cursor"
|
|
25
25
|
LMSTUDIO = "lmstudio"
|
|
26
26
|
GEMINI = "gemini"
|
|
27
|
+
KIRO = "kiro"
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
class MCPServerConfig(BaseModel):
|
|
@@ -192,7 +193,7 @@ class EnvironmentPackageEntry(BaseModel):
|
|
|
192
193
|
"""Validate host names are supported."""
|
|
193
194
|
supported_hosts = {
|
|
194
195
|
'claude-desktop', 'claude-code', 'vscode',
|
|
195
|
-
'cursor', 'lmstudio', 'gemini'
|
|
196
|
+
'cursor', 'lmstudio', 'gemini', 'kiro'
|
|
196
197
|
}
|
|
197
198
|
for host_name in v.keys():
|
|
198
199
|
if host_name not in supported_hosts:
|
|
@@ -538,6 +539,30 @@ class MCPServerConfigClaude(MCPServerConfigBase):
|
|
|
538
539
|
return cls.model_validate(claude_data)
|
|
539
540
|
|
|
540
541
|
|
|
542
|
+
class MCPServerConfigKiro(MCPServerConfigBase):
|
|
543
|
+
"""Kiro IDE-specific MCP server configuration.
|
|
544
|
+
|
|
545
|
+
Extends base model with Kiro-specific fields for server management
|
|
546
|
+
and tool control.
|
|
547
|
+
"""
|
|
548
|
+
|
|
549
|
+
# Kiro-specific fields
|
|
550
|
+
disabled: Optional[bool] = Field(None, description="Whether server is disabled")
|
|
551
|
+
autoApprove: Optional[List[str]] = Field(None, description="Auto-approved tool names")
|
|
552
|
+
disabledTools: Optional[List[str]] = Field(None, description="Disabled tool names")
|
|
553
|
+
|
|
554
|
+
@classmethod
|
|
555
|
+
def from_omni(cls, omni: 'MCPServerConfigOmni') -> 'MCPServerConfigKiro':
|
|
556
|
+
"""Convert Omni model to Kiro-specific model."""
|
|
557
|
+
# Get supported fields dynamically
|
|
558
|
+
supported_fields = set(cls.model_fields.keys())
|
|
559
|
+
|
|
560
|
+
# Single-call field filtering
|
|
561
|
+
kiro_data = omni.model_dump(include=supported_fields, exclude_unset=True)
|
|
562
|
+
|
|
563
|
+
return cls.model_validate(kiro_data)
|
|
564
|
+
|
|
565
|
+
|
|
541
566
|
class MCPServerConfigOmni(BaseModel):
|
|
542
567
|
"""Omni configuration supporting all host-specific fields.
|
|
543
568
|
|
|
@@ -580,6 +605,11 @@ class MCPServerConfigOmni(BaseModel):
|
|
|
580
605
|
# VS Code specific
|
|
581
606
|
envFile: Optional[str] = None
|
|
582
607
|
inputs: Optional[List[Dict]] = None
|
|
608
|
+
|
|
609
|
+
# Kiro specific
|
|
610
|
+
disabled: Optional[bool] = None
|
|
611
|
+
autoApprove: Optional[List[str]] = None
|
|
612
|
+
disabledTools: Optional[List[str]] = None
|
|
583
613
|
|
|
584
614
|
@field_validator('url')
|
|
585
615
|
@classmethod
|
|
@@ -599,4 +629,5 @@ HOST_MODEL_REGISTRY: Dict[MCPHostType, type[MCPServerConfigBase]] = {
|
|
|
599
629
|
MCPHostType.VSCODE: MCPServerConfigVSCode,
|
|
600
630
|
MCPHostType.CURSOR: MCPServerConfigCursor,
|
|
601
631
|
MCPHostType.LMSTUDIO: MCPServerConfigCursor, # Same as CURSOR
|
|
632
|
+
MCPHostType.KIRO: MCPServerConfigKiro,
|
|
602
633
|
}
|
|
@@ -14,6 +14,7 @@ import logging
|
|
|
14
14
|
|
|
15
15
|
from .host_management import MCPHostStrategy, register_host_strategy
|
|
16
16
|
from .models import MCPHostType, MCPServerConfig, HostConfiguration
|
|
17
|
+
from .backup import MCPHostConfigBackupManager, AtomicFileOperations
|
|
17
18
|
|
|
18
19
|
logger = logging.getLogger(__name__)
|
|
19
20
|
|
|
@@ -409,6 +410,101 @@ class VSCodeHostStrategy(MCPHostStrategy):
|
|
|
409
410
|
return False
|
|
410
411
|
|
|
411
412
|
|
|
413
|
+
@register_host_strategy(MCPHostType.KIRO)
|
|
414
|
+
class KiroHostStrategy(MCPHostStrategy):
|
|
415
|
+
"""Configuration strategy for Kiro IDE."""
|
|
416
|
+
|
|
417
|
+
def get_config_path(self) -> Optional[Path]:
|
|
418
|
+
"""Get Kiro configuration path (user-level only per constraint)."""
|
|
419
|
+
return Path.home() / ".kiro" / "settings" / "mcp.json"
|
|
420
|
+
|
|
421
|
+
def get_config_key(self) -> str:
|
|
422
|
+
"""Kiro uses 'mcpServers' key."""
|
|
423
|
+
return "mcpServers"
|
|
424
|
+
|
|
425
|
+
def is_host_available(self) -> bool:
|
|
426
|
+
"""Check if Kiro is available by checking for settings directory."""
|
|
427
|
+
kiro_dir = Path.home() / ".kiro" / "settings"
|
|
428
|
+
return kiro_dir.exists()
|
|
429
|
+
|
|
430
|
+
def validate_server_config(self, server_config: MCPServerConfig) -> bool:
|
|
431
|
+
"""Kiro validation - supports both local and remote servers."""
|
|
432
|
+
return server_config.command is not None or server_config.url is not None
|
|
433
|
+
|
|
434
|
+
def read_configuration(self) -> HostConfiguration:
|
|
435
|
+
"""Read Kiro configuration file."""
|
|
436
|
+
config_path_str = self.get_config_path()
|
|
437
|
+
if not config_path_str:
|
|
438
|
+
return HostConfiguration(servers={})
|
|
439
|
+
|
|
440
|
+
config_path = Path(config_path_str)
|
|
441
|
+
if not config_path.exists():
|
|
442
|
+
return HostConfiguration(servers={})
|
|
443
|
+
|
|
444
|
+
try:
|
|
445
|
+
with open(config_path, 'r', encoding='utf-8') as f:
|
|
446
|
+
data = json.load(f)
|
|
447
|
+
|
|
448
|
+
servers = {}
|
|
449
|
+
mcp_servers = data.get(self.get_config_key(), {})
|
|
450
|
+
|
|
451
|
+
for name, config in mcp_servers.items():
|
|
452
|
+
try:
|
|
453
|
+
servers[name] = MCPServerConfig(**config)
|
|
454
|
+
except Exception as e:
|
|
455
|
+
logger.warning(f"Invalid server config for {name}: {e}")
|
|
456
|
+
continue
|
|
457
|
+
|
|
458
|
+
return HostConfiguration(servers=servers)
|
|
459
|
+
|
|
460
|
+
except Exception as e:
|
|
461
|
+
logger.error(f"Failed to read Kiro configuration: {e}")
|
|
462
|
+
return HostConfiguration(servers={})
|
|
463
|
+
|
|
464
|
+
def write_configuration(self, config: HostConfiguration, no_backup: bool = False) -> bool:
|
|
465
|
+
"""Write configuration to Kiro with backup support."""
|
|
466
|
+
config_path_str = self.get_config_path()
|
|
467
|
+
if not config_path_str:
|
|
468
|
+
return False
|
|
469
|
+
|
|
470
|
+
config_path = Path(config_path_str)
|
|
471
|
+
|
|
472
|
+
try:
|
|
473
|
+
# Ensure directory exists
|
|
474
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
475
|
+
|
|
476
|
+
# Read existing configuration to preserve other settings
|
|
477
|
+
existing_data = {}
|
|
478
|
+
if config_path.exists():
|
|
479
|
+
with open(config_path, 'r', encoding='utf-8') as f:
|
|
480
|
+
existing_data = json.load(f)
|
|
481
|
+
|
|
482
|
+
# Update MCP servers section
|
|
483
|
+
servers_data = {}
|
|
484
|
+
for name, server_config in config.servers.items():
|
|
485
|
+
servers_data[name] = server_config.model_dump(exclude_unset=True)
|
|
486
|
+
|
|
487
|
+
existing_data[self.get_config_key()] = servers_data
|
|
488
|
+
|
|
489
|
+
# Use atomic write with backup support
|
|
490
|
+
backup_manager = MCPHostConfigBackupManager()
|
|
491
|
+
atomic_ops = AtomicFileOperations()
|
|
492
|
+
|
|
493
|
+
atomic_ops.atomic_write_with_backup(
|
|
494
|
+
file_path=config_path,
|
|
495
|
+
data=existing_data,
|
|
496
|
+
backup_manager=backup_manager,
|
|
497
|
+
hostname="kiro",
|
|
498
|
+
skip_backup=no_backup
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
return True
|
|
502
|
+
|
|
503
|
+
except Exception as e:
|
|
504
|
+
logger.error(f"Failed to write Kiro configuration: {e}")
|
|
505
|
+
return False
|
|
506
|
+
|
|
507
|
+
|
|
412
508
|
@register_host_strategy(MCPHostType.GEMINI)
|
|
413
509
|
class GeminiHostStrategy(MCPHostStrategy):
|
|
414
510
|
"""Configuration strategy for Google Gemini CLI MCP integration."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: hatch-xclam
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1.dev1
|
|
4
4
|
Summary: Package manager for the Cracking Shells ecosystem
|
|
5
5
|
Author: Cracking Shells Team
|
|
6
6
|
Project-URL: Homepage, https://github.com/CrackingShells/Hatch
|
|
@@ -30,7 +30,7 @@ Dynamic: license-file
|
|
|
30
30
|
|
|
31
31
|
## Introduction
|
|
32
32
|
|
|
33
|
-
Hatch is the package manager for managing Model Context Protocol (MCP) servers with environment isolation, multi-type dependency resolution, and multi-host deployment. Deploy MCP servers to Claude Desktop, VS Code, Cursor, and other platforms with automatic dependency management.
|
|
33
|
+
Hatch is the package manager for managing Model Context Protocol (MCP) servers with environment isolation, multi-type dependency resolution, and multi-host deployment. Deploy MCP servers to Claude Desktop, VS Code, Cursor, Kiro, and other platforms with automatic dependency management.
|
|
34
34
|
|
|
35
35
|
The canonical documentation is at `docs/index.md` and published at <https://hatch.readthedocs.io/en/latest/>.
|
|
36
36
|
|
|
@@ -38,7 +38,7 @@ The canonical documentation is at `docs/index.md` and published at <https://hatc
|
|
|
38
38
|
|
|
39
39
|
- **Environment Isolation** — Create separate, isolated workspaces for different projects without conflicts
|
|
40
40
|
- **Multi-Type Dependency Resolution** — Automatically resolve and install system packages, Python packages, Docker containers, and Hatch packages
|
|
41
|
-
- **Multi-Host Deployment** — Deploy MCP servers to Claude Desktop, Claude Code, VS Code, Cursor, LM Studio, and Google Gemini CLI
|
|
41
|
+
- **Multi-Host Deployment** — Deploy MCP servers to Claude Desktop, Claude Code, VS Code, Cursor, Kiro, LM Studio, and Google Gemini CLI
|
|
42
42
|
- **Package Validation** — Ensure packages meet schema requirements before distribution
|
|
43
43
|
- **Development-Focused** — Optimized for rapid development and testing of MCP server ecosystems
|
|
44
44
|
|
|
@@ -50,6 +50,7 @@ Hatch supports deployment to the following MCP host platforms:
|
|
|
50
50
|
- **Claude Code** — Claude integration for VS Code with MCP capabilities
|
|
51
51
|
- **VS Code** — Visual Studio Code with the MCP extension for tool integration
|
|
52
52
|
- **Cursor** — AI-first code editor with built-in MCP server support
|
|
53
|
+
- **Kiro** — Kiro IDE with MCP support
|
|
53
54
|
- **LM Studio** — Local LLM inference platform with MCP server integration
|
|
54
55
|
- **Google Gemini CLI** — Command-line interface for Google's Gemini model with MCP support
|
|
55
56
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
hatch/__init__.py,sha256=5JFQZiaZQewEWg8WktQKEdT8IeH0KstndZf27VH7sq4,594
|
|
2
|
-
hatch/cli_hatch.py,sha256=
|
|
2
|
+
hatch/cli_hatch.py,sha256=mDWKVA8Cg8lpXElkJbj8-7xyzI1AiJk3nlp2kOtpwPk,109150
|
|
3
3
|
hatch/environment_manager.py,sha256=9R9PJYPKQLmWeGXBrOzXxty20la33LgCCYY8o2aMFBQ,60757
|
|
4
4
|
hatch/package_loader.py,sha256=Sa2JIoio1QlMT2tOGwZhC6pFJIs419cYyoodzyaTDl4,11269
|
|
5
5
|
hatch/python_environment_manager.py,sha256=guU3zz4_WG3ptuX_ATGCRIi_fDxNHlaQtMv3kiRSo8k,28894
|
|
@@ -15,17 +15,17 @@ hatch/installers/installer_base.py,sha256=mId6Q_DLOQPZriq3wu3BCU-ckouom3EZgbWJQq
|
|
|
15
15
|
hatch/installers/python_installer.py,sha256=MS9Q8wKjMAy7MEWk7zcAAiFgN0KzOVJFmMzXt1MSH8g,13632
|
|
16
16
|
hatch/installers/registry.py,sha256=ZOEEMJy_kL5LVj5Mf7s1_CIovDnUVag6nB01dEU9Xeg,6831
|
|
17
17
|
hatch/installers/system_installer.py,sha256=bdrmw3I9g2EU2E94-4vtJj01RhmekX9GxylU1RPT3Lk,22869
|
|
18
|
-
hatch/mcp_host_config/__init__.py,sha256=
|
|
19
|
-
hatch/mcp_host_config/backup.py,sha256=
|
|
18
|
+
hatch/mcp_host_config/__init__.py,sha256=YZ9LEbR5E5p6padhPt114wvcsLCz16c2RPduhvvsj9I,1727
|
|
19
|
+
hatch/mcp_host_config/backup.py,sha256=vl2YLL0P0bobGvx5moSAe4wI47vp25d-NpwNO95J3zU,16875
|
|
20
20
|
hatch/mcp_host_config/host_management.py,sha256=sXyGluFQpfXKggxAVvV9riGRis29JnoEM2dTWSIwb24,23905
|
|
21
|
-
hatch/mcp_host_config/models.py,sha256=
|
|
21
|
+
hatch/mcp_host_config/models.py,sha256=OM5sKtQF-1hylXijNNRctKpHFQbPA88C3DorwyhGv20,25710
|
|
22
22
|
hatch/mcp_host_config/reporting.py,sha256=Q8UKBJRfvJTbb5PM9xwLEOh3OJjf19AKpWKxs-2622k,6889
|
|
23
|
-
hatch/mcp_host_config/strategies.py,sha256=
|
|
24
|
-
hatch_xclam-0.7.
|
|
23
|
+
hatch/mcp_host_config/strategies.py,sha256=WyelujfNtP0Y-KP5hS6u5Z9QSbMWcIxSv30nBQ1Ug7o,23998
|
|
24
|
+
hatch_xclam-0.7.1.dev1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
25
25
|
tests/__init__.py,sha256=4I3aQWv143Y1QY_nRIBWnY9MIL-aoQOJuVlpoPQz24E,53
|
|
26
26
|
tests/run_environment_tests.py,sha256=bWCr8UsPgU80SM8f_VSi0TCwDI6JNqZpvZ2W9-b2Lqk,7302
|
|
27
27
|
tests/test_cli_version.py,sha256=lU8TBZfzn_8AenFNXYrLMARht91fI5twBN13L-iJebc,4778
|
|
28
|
-
tests/test_data_utils.py,sha256=
|
|
28
|
+
tests/test_data_utils.py,sha256=ROexE3H4Cjk8maR-r6x8s5507d0vWF5xJteO_YN78SU,21876
|
|
29
29
|
tests/test_dependency_orchestrator_consent.py,sha256=lA9Qu-3dFdXKmU8mzOS0tjM8j0yy9qMQXJJcgEoy12g,12652
|
|
30
30
|
tests/test_docker_installer.py,sha256=pcWev4fGf1p-pR5T8tDswGVZqIprC86puLEl6t8yY2w,22305
|
|
31
31
|
tests/test_env_manip.py,sha256=f3LjBX0y0wzTDjc52QDan3Fgcgtld7CvuzH5gYKxGhs,47941
|
|
@@ -56,6 +56,15 @@ tests/test_python_installer.py,sha256=DXBy7hNJk5313_dDXiHTLEH7UJSPUnyGs4IEr7Hn_5
|
|
|
56
56
|
tests/test_registry.py,sha256=nFHwRIx9n8y0nHwW9j8X3DZ07Y0BLYZMKduTXo-xXTc,2261
|
|
57
57
|
tests/test_registry_retriever.py,sha256=6mQQuqy2tQdw4j3VOkC_DxWqtKwaCjGPgXsdL-w48Yw,10775
|
|
58
58
|
tests/test_system_installer.py,sha256=bWuyEKakhvi51iM8xHJh62zv83HUTd8QnPlqUUMWx9c,28102
|
|
59
|
+
tests/integration/__init__.py,sha256=2mG53dv1VqjxZYHuglneK9VgDMoWCxpfmPByXXd3zVM,125
|
|
60
|
+
tests/integration/test_mcp_kiro_integration.py,sha256=9y2XPacd3Y6zkqUUcCDjzj8Jv2Humby2LZ5CLSeFYCg,5566
|
|
61
|
+
tests/regression/__init__.py,sha256=0pFnFuEaMf7gPFFXMv-b_vNRNyLV-wU2lYspZHFH_Uo,127
|
|
62
|
+
tests/regression/test_mcp_kiro_backup_integration.py,sha256=oBEnSSLrnHIurkrBtjSG-HT6DyODV2z9tZeZotnsR1k,9584
|
|
63
|
+
tests/regression/test_mcp_kiro_cli_integration.py,sha256=jDQE73yJTRb2e6MPShxLHmLDtN5VBMHMAUBojPEnVBI,5123
|
|
64
|
+
tests/regression/test_mcp_kiro_decorator_registration.py,sha256=_H9FdKdKCv__IYBS0tfnZGUP574KoDjqKInmFiDEKPc,2556
|
|
65
|
+
tests/regression/test_mcp_kiro_host_strategy.py,sha256=t3EbNgUkDC-tF_Ztrjlrx8aDkmML2zZiPnl3iLvKWcg,8235
|
|
66
|
+
tests/regression/test_mcp_kiro_model_validation.py,sha256=bCWzkP6gDxD4tJ6bXnyC6BNGPk3FwX5MQVJt_kK-Hsg,3877
|
|
67
|
+
tests/regression/test_mcp_kiro_omni_conversion.py,sha256=u0g-NFKDpyVxguNHc_RxJXhBvUvABljx-IZqeOjpJZw,3559
|
|
59
68
|
tests/test_data/packages/basic/base_pkg/hatch_mcp_server.py,sha256=nn9XJQz7Owq_AKZ35bUV-l5eThauxTvIQZdQmcZqbQg,350
|
|
60
69
|
tests/test_data/packages/basic/base_pkg/mcp_server.py,sha256=gzXj-n0NbcS1TF-ebKOdXQRyuVIC0Gn_b8ZB-9RckrM,422
|
|
61
70
|
tests/test_data/packages/basic/base_pkg_v2/hatch_mcp_server.py,sha256=VmGpeLPpsNyFyePNtcRQCSscLOHdZgXsGDulA4_9CJA,356
|
|
@@ -86,8 +95,8 @@ tests/test_data/packages/schema_versions/schema_v1_1_0_pkg/main.py,sha256=_B5aqX
|
|
|
86
95
|
tests/test_data/packages/schema_versions/schema_v1_2_0_pkg/main.py,sha256=rinhVySJpjXKd2sRCS0ps7xTrVqImWcZ8l4aYbidYR8,238
|
|
87
96
|
tests/test_data/packages/schema_versions/schema_v1_2_1_pkg/hatch_mcp_server.py,sha256=FT14llzHlA4i8I__8GugzBRowhg_CbLmsOwjq0IWFsY,368
|
|
88
97
|
tests/test_data/packages/schema_versions/schema_v1_2_1_pkg/mcp_server.py,sha256=BRPAyyAseE2CGR3W647SwjlluYfi7ejhZck0An5581I,467
|
|
89
|
-
hatch_xclam-0.7.
|
|
90
|
-
hatch_xclam-0.7.
|
|
91
|
-
hatch_xclam-0.7.
|
|
92
|
-
hatch_xclam-0.7.
|
|
93
|
-
hatch_xclam-0.7.
|
|
98
|
+
hatch_xclam-0.7.1.dev1.dist-info/METADATA,sha256=SMSh9ptwXOL_vYr8I881UViJS5LbPXXh6B9nXGsmfek,5901
|
|
99
|
+
hatch_xclam-0.7.1.dev1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
100
|
+
hatch_xclam-0.7.1.dev1.dist-info/entry_points.txt,sha256=6xbkwFUtr7nRa56vUFMyJk2wjwFQ_XVaU53ruecWKI0,47
|
|
101
|
+
hatch_xclam-0.7.1.dev1.dist-info/top_level.txt,sha256=GZP3Ivciwal8jVITQkQr7dSNlLJRzfNOhA76VN7Jp4Y,12
|
|
102
|
+
hatch_xclam-0.7.1.dev1.dist-info/RECORD,,
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Kiro MCP Integration Tests
|
|
3
|
+
|
|
4
|
+
End-to-end integration tests combining CLI, model conversion, and strategy operations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import unittest
|
|
8
|
+
from unittest.mock import patch, MagicMock
|
|
9
|
+
|
|
10
|
+
from wobble.decorators import integration_test
|
|
11
|
+
|
|
12
|
+
from hatch.cli_hatch import handle_mcp_configure
|
|
13
|
+
from hatch.mcp_host_config.models import (
|
|
14
|
+
HOST_MODEL_REGISTRY,
|
|
15
|
+
MCPHostType,
|
|
16
|
+
MCPServerConfigKiro
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestKiroIntegration(unittest.TestCase):
|
|
21
|
+
"""Test suite for end-to-end Kiro integration."""
|
|
22
|
+
|
|
23
|
+
@integration_test(scope="component")
|
|
24
|
+
@patch('hatch.cli_hatch.MCPHostConfigurationManager')
|
|
25
|
+
def test_kiro_end_to_end_configuration(self, mock_manager_class):
|
|
26
|
+
"""Test complete Kiro configuration workflow."""
|
|
27
|
+
# Setup mocks
|
|
28
|
+
mock_manager = MagicMock()
|
|
29
|
+
mock_manager_class.return_value = mock_manager
|
|
30
|
+
|
|
31
|
+
mock_result = MagicMock()
|
|
32
|
+
mock_result.success = True
|
|
33
|
+
mock_manager.configure_server.return_value = mock_result
|
|
34
|
+
|
|
35
|
+
# Execute CLI command with Kiro-specific arguments
|
|
36
|
+
result = handle_mcp_configure(
|
|
37
|
+
host='kiro',
|
|
38
|
+
server_name='augment-server',
|
|
39
|
+
command='auggie',
|
|
40
|
+
args=['--mcp', '-m', 'default'],
|
|
41
|
+
disabled=False,
|
|
42
|
+
auto_approve_tools=['codebase-retrieval', 'fetch'],
|
|
43
|
+
disable_tools=['dangerous-tool'],
|
|
44
|
+
auto_approve=True
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Verify success
|
|
48
|
+
self.assertEqual(result, 0)
|
|
49
|
+
|
|
50
|
+
# Verify configuration manager was called
|
|
51
|
+
mock_manager.configure_server.assert_called_once()
|
|
52
|
+
|
|
53
|
+
# Verify server configuration
|
|
54
|
+
call_args = mock_manager.configure_server.call_args
|
|
55
|
+
server_config = call_args.kwargs['server_config']
|
|
56
|
+
|
|
57
|
+
# Verify all Kiro-specific fields
|
|
58
|
+
self.assertFalse(server_config.disabled)
|
|
59
|
+
self.assertEqual(len(server_config.autoApprove), 2)
|
|
60
|
+
self.assertEqual(len(server_config.disabledTools), 1)
|
|
61
|
+
self.assertIn('codebase-retrieval', server_config.autoApprove)
|
|
62
|
+
self.assertIn('dangerous-tool', server_config.disabledTools)
|
|
63
|
+
|
|
64
|
+
@integration_test(scope="system")
|
|
65
|
+
def test_kiro_host_model_registry_integration(self):
|
|
66
|
+
"""Test Kiro integration with HOST_MODEL_REGISTRY."""
|
|
67
|
+
# Verify Kiro is in registry
|
|
68
|
+
self.assertIn(MCPHostType.KIRO, HOST_MODEL_REGISTRY)
|
|
69
|
+
|
|
70
|
+
# Verify correct model class
|
|
71
|
+
model_class = HOST_MODEL_REGISTRY[MCPHostType.KIRO]
|
|
72
|
+
self.assertEqual(model_class.__name__, "MCPServerConfigKiro")
|
|
73
|
+
|
|
74
|
+
# Test model instantiation
|
|
75
|
+
model_instance = model_class(
|
|
76
|
+
name="test-server",
|
|
77
|
+
command="auggie",
|
|
78
|
+
disabled=True
|
|
79
|
+
)
|
|
80
|
+
self.assertTrue(model_instance.disabled)
|
|
81
|
+
|
|
82
|
+
@integration_test(scope="component")
|
|
83
|
+
def test_kiro_model_to_strategy_workflow(self):
|
|
84
|
+
"""Test workflow from model creation to strategy operations."""
|
|
85
|
+
# Import to trigger registration
|
|
86
|
+
import hatch.mcp_host_config.strategies
|
|
87
|
+
from hatch.mcp_host_config.host_management import MCPHostRegistry
|
|
88
|
+
|
|
89
|
+
# Create Kiro model
|
|
90
|
+
kiro_model = MCPServerConfigKiro(
|
|
91
|
+
name="workflow-test",
|
|
92
|
+
command="auggie",
|
|
93
|
+
args=["--mcp"],
|
|
94
|
+
disabled=False,
|
|
95
|
+
autoApprove=["codebase-retrieval"]
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# Get Kiro strategy
|
|
99
|
+
strategy = MCPHostRegistry.get_strategy(MCPHostType.KIRO)
|
|
100
|
+
|
|
101
|
+
# Verify strategy can validate the model
|
|
102
|
+
self.assertTrue(strategy.validate_server_config(kiro_model))
|
|
103
|
+
|
|
104
|
+
# Verify model fields are accessible
|
|
105
|
+
self.assertEqual(kiro_model.command, "auggie")
|
|
106
|
+
self.assertFalse(kiro_model.disabled)
|
|
107
|
+
self.assertIn("codebase-retrieval", kiro_model.autoApprove)
|
|
108
|
+
|
|
109
|
+
@integration_test(scope="end_to_end")
|
|
110
|
+
@patch('hatch.cli_hatch.MCPHostConfigurationManager')
|
|
111
|
+
def test_kiro_complete_lifecycle(self, mock_manager_class):
|
|
112
|
+
"""Test complete Kiro server lifecycle: create, configure, validate."""
|
|
113
|
+
# Setup mocks
|
|
114
|
+
mock_manager = MagicMock()
|
|
115
|
+
mock_manager_class.return_value = mock_manager
|
|
116
|
+
|
|
117
|
+
mock_result = MagicMock()
|
|
118
|
+
mock_result.success = True
|
|
119
|
+
mock_manager.configure_server.return_value = mock_result
|
|
120
|
+
|
|
121
|
+
# Step 1: Configure server via CLI
|
|
122
|
+
result = handle_mcp_configure(
|
|
123
|
+
host='kiro',
|
|
124
|
+
server_name='lifecycle-test',
|
|
125
|
+
command='auggie',
|
|
126
|
+
args=['--mcp', '-w', '.'],
|
|
127
|
+
disabled=False,
|
|
128
|
+
auto_approve_tools=['codebase-retrieval'],
|
|
129
|
+
auto_approve=True
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Verify CLI success
|
|
133
|
+
self.assertEqual(result, 0)
|
|
134
|
+
|
|
135
|
+
# Step 2: Verify configuration manager interaction
|
|
136
|
+
mock_manager.configure_server.assert_called_once()
|
|
137
|
+
call_args = mock_manager.configure_server.call_args
|
|
138
|
+
|
|
139
|
+
# Step 3: Verify server configuration structure
|
|
140
|
+
server_config = call_args.kwargs['server_config']
|
|
141
|
+
self.assertEqual(server_config.name, 'lifecycle-test')
|
|
142
|
+
self.assertEqual(server_config.command, 'auggie')
|
|
143
|
+
self.assertIn('--mcp', server_config.args)
|
|
144
|
+
self.assertIn('-w', server_config.args)
|
|
145
|
+
self.assertFalse(server_config.disabled)
|
|
146
|
+
self.assertIn('codebase-retrieval', server_config.autoApprove)
|
|
147
|
+
|
|
148
|
+
# Step 4: Verify model type
|
|
149
|
+
self.assertIsInstance(server_config, MCPServerConfigKiro)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
if __name__ == '__main__':
|
|
153
|
+
unittest.main()
|