Skip to content

Commit f244c61

Browse files
author
LittleCoinCoin
committed
feat: add user feedback reporting to package add/sync commands
- Integrate MCPServerConfigOmni and HOST_MODEL_REGISTRY into package add handler - Integrate MCPServerConfigOmni and HOST_MODEL_REGISTRY into package sync handler - Generate and display conversion reports for each package-host combination - Add dry-run mode conversion report preview for package sync - Convert MCPServerConfig to Omni model before host-specific conversion - Pass host-specific models to MCPHostConfigurationManager - Maintain backward compatibility with existing package management workflow All tests passing (248/248, 100% success rate)
1 parent 5a98b64 commit f244c61

File tree

1 file changed

+172
-70
lines changed

1 file changed

+172
-70
lines changed

hatch/cli_hatch.py

Lines changed: 172 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,45 +1569,80 @@ def main():
15691569
# Configure on each host
15701570
success_count = 0
15711571
for host in hosts: # 'host', here, is a string
1572-
host_success_count = 0
1573-
for i, server_config in enumerate(server_configs):
1574-
pkg_name = package_names[i]
1575-
try:
1576-
result = mcp_manager.configure_server(
1577-
hostname=host,
1578-
server_config=server_config,
1579-
no_backup=False # Always backup when adding packages
1580-
)
1581-
1582-
if result.success:
1583-
print(f"✓ Configured {server_config.name} ({pkg_name}) on {host}")
1584-
host_success_count += 1
1585-
1586-
# Update package metadata with host configuration tracking
1587-
try:
1588-
server_config_dict = {
1589-
"name": server_config.name,
1590-
"command": server_config.command,
1591-
"args": server_config.args
1592-
}
1572+
try:
1573+
# Convert string to MCPHostType enum
1574+
host_type = MCPHostType(host)
1575+
host_model_class = HOST_MODEL_REGISTRY.get(host_type)
1576+
if not host_model_class:
1577+
print(f"✗ Error: No model registered for host '{host}'")
1578+
continue
1579+
1580+
host_success_count = 0
1581+
for i, server_config in enumerate(server_configs):
1582+
pkg_name = package_names[i]
1583+
try:
1584+
# Convert MCPServerConfig to Omni model
1585+
omni_config = MCPServerConfigOmni(
1586+
name=server_config.name,
1587+
command=server_config.command,
1588+
args=server_config.args,
1589+
env=server_config.env,
1590+
url=server_config.url,
1591+
headers=getattr(server_config, 'headers', None)
1592+
)
1593+
1594+
# Convert to host-specific model
1595+
host_config = host_model_class.from_omni(omni_config)
1596+
1597+
# Generate and display conversion report
1598+
report = generate_conversion_report(
1599+
operation='create',
1600+
server_name=server_config.name,
1601+
target_host=host_type,
1602+
omni=omni_config,
1603+
dry_run=False
1604+
)
1605+
display_report(report)
1606+
1607+
result = mcp_manager.configure_server(
1608+
hostname=host,
1609+
server_config=host_config,
1610+
no_backup=False # Always backup when adding packages
1611+
)
1612+
1613+
if result.success:
1614+
print(f"✓ Configured {server_config.name} ({pkg_name}) on {host}")
1615+
host_success_count += 1
1616+
1617+
# Update package metadata with host configuration tracking
1618+
try:
1619+
server_config_dict = {
1620+
"name": server_config.name,
1621+
"command": server_config.command,
1622+
"args": server_config.args
1623+
}
1624+
1625+
env_manager.update_package_host_configuration(
1626+
env_name=env_name,
1627+
package_name=pkg_name,
1628+
hostname=host,
1629+
server_config=server_config_dict
1630+
)
1631+
except Exception as e:
1632+
# Log but don't fail the configuration operation
1633+
print(f"[WARNING] Failed to update package metadata for {pkg_name}: {e}")
1634+
else:
1635+
print(f"✗ Failed to configure {server_config.name} ({pkg_name}) on {host}: {result.error_message}")
15931636

1594-
env_manager.update_package_host_configuration(
1595-
env_name=env_name,
1596-
package_name=pkg_name,
1597-
hostname=host,
1598-
server_config=server_config_dict
1599-
)
1600-
except Exception as e:
1601-
# Log but don't fail the configuration operation
1602-
print(f"[WARNING] Failed to update package metadata for {pkg_name}: {e}")
1603-
else:
1604-
print(f"✗ Failed to configure {server_config.name} ({pkg_name}) on {host}: {result.error_message}")
1637+
except Exception as e:
1638+
print(f"✗ Error configuring {server_config.name} ({pkg_name}) on {host}: {e}")
16051639

1606-
except Exception as e:
1607-
print(f"✗ Error configuring {server_config.name} ({pkg_name}) on {host}: {e}")
1640+
if host_success_count == len(server_configs):
1641+
success_count += 1
16081642

1609-
if host_success_count == len(server_configs):
1610-
success_count += 1
1643+
except ValueError as e:
1644+
print(f"✗ Invalid host '{host}': {e}")
1645+
continue
16111646

16121647
if success_count > 0:
16131648
print(f"MCP configuration completed: {success_count}/{len(hosts)} hosts configured")
@@ -1703,6 +1738,38 @@ def main():
17031738
print(f"[DRY RUN] Would synchronize MCP servers for {len(server_configs)} package(s) to hosts: {[h for h in hosts]}")
17041739
for pkg_name, config in server_configs:
17051740
print(f"[DRY RUN] - {pkg_name}: {config.name} -> {' '.join(config.args)}")
1741+
1742+
# Generate and display conversion reports for dry-run mode
1743+
for host in hosts:
1744+
try:
1745+
host_type = MCPHostType(host)
1746+
host_model_class = HOST_MODEL_REGISTRY.get(host_type)
1747+
if not host_model_class:
1748+
print(f"[DRY RUN] ✗ Error: No model registered for host '{host}'")
1749+
continue
1750+
1751+
# Convert to Omni model
1752+
omni_config = MCPServerConfigOmni(
1753+
name=config.name,
1754+
command=config.command,
1755+
args=config.args,
1756+
env=config.env,
1757+
url=config.url,
1758+
headers=getattr(config, 'headers', None)
1759+
)
1760+
1761+
# Generate report
1762+
report = generate_conversion_report(
1763+
operation='create',
1764+
server_name=config.name,
1765+
target_host=host_type,
1766+
omni=omni_config,
1767+
dry_run=True
1768+
)
1769+
print(f"[DRY RUN] Preview for {pkg_name} on {host}:")
1770+
display_report(report)
1771+
except ValueError as e:
1772+
print(f"[DRY RUN] ✗ Invalid host '{host}': {e}")
17061773
return 0
17071774

17081775
# Confirm operation unless auto-approved
@@ -1719,40 +1786,75 @@ def main():
17191786
success_count = 0
17201787

17211788
for host in hosts:
1722-
for pkg_name, server_config in server_configs:
1723-
try:
1724-
result = mcp_manager.configure_server(
1725-
hostname=host,
1726-
server_config=server_config,
1727-
no_backup=args.no_backup
1728-
)
1729-
1730-
if result.success:
1731-
print(f"[SUCCESS] Successfully configured {server_config.name} ({pkg_name}) on {host}")
1732-
success_count += 1
1733-
1734-
# Update package metadata with host configuration tracking
1735-
try:
1736-
server_config_dict = {
1737-
"name": server_config.name,
1738-
"command": server_config.command,
1739-
"args": server_config.args
1740-
}
1741-
1742-
env_manager.update_package_host_configuration(
1743-
env_name=env_name,
1744-
package_name=pkg_name,
1745-
hostname=host,
1746-
server_config=server_config_dict
1747-
)
1748-
except Exception as e:
1749-
# Log but don't fail the sync operation
1750-
print(f"[WARNING] Failed to update package metadata for {pkg_name}: {e}")
1751-
else:
1752-
print(f"[ERROR] Failed to configure {server_config.name} ({pkg_name}) on {host}: {result.error_message}")
1753-
1754-
except Exception as e:
1755-
print(f"[ERROR] Error configuring {server_config.name} ({pkg_name}) on {host}: {e}")
1789+
try:
1790+
# Convert string to MCPHostType enum
1791+
host_type = MCPHostType(host)
1792+
host_model_class = HOST_MODEL_REGISTRY.get(host_type)
1793+
if not host_model_class:
1794+
print(f"✗ Error: No model registered for host '{host}'")
1795+
continue
1796+
1797+
for pkg_name, server_config in server_configs:
1798+
try:
1799+
# Convert MCPServerConfig to Omni model
1800+
omni_config = MCPServerConfigOmni(
1801+
name=server_config.name,
1802+
command=server_config.command,
1803+
args=server_config.args,
1804+
env=server_config.env,
1805+
url=server_config.url,
1806+
headers=getattr(server_config, 'headers', None)
1807+
)
1808+
1809+
# Convert to host-specific model
1810+
host_config = host_model_class.from_omni(omni_config)
1811+
1812+
# Generate and display conversion report
1813+
report = generate_conversion_report(
1814+
operation='create',
1815+
server_name=server_config.name,
1816+
target_host=host_type,
1817+
omni=omni_config,
1818+
dry_run=False
1819+
)
1820+
display_report(report)
1821+
1822+
result = mcp_manager.configure_server(
1823+
hostname=host,
1824+
server_config=host_config,
1825+
no_backup=args.no_backup
1826+
)
1827+
1828+
if result.success:
1829+
print(f"[SUCCESS] Successfully configured {server_config.name} ({pkg_name}) on {host}")
1830+
success_count += 1
1831+
1832+
# Update package metadata with host configuration tracking
1833+
try:
1834+
server_config_dict = {
1835+
"name": server_config.name,
1836+
"command": server_config.command,
1837+
"args": server_config.args
1838+
}
1839+
1840+
env_manager.update_package_host_configuration(
1841+
env_name=env_name,
1842+
package_name=pkg_name,
1843+
hostname=host,
1844+
server_config=server_config_dict
1845+
)
1846+
except Exception as e:
1847+
# Log but don't fail the sync operation
1848+
print(f"[WARNING] Failed to update package metadata for {pkg_name}: {e}")
1849+
else:
1850+
print(f"[ERROR] Failed to configure {server_config.name} ({pkg_name}) on {host}: {result.error_message}")
1851+
1852+
except Exception as e:
1853+
print(f"[ERROR] Error configuring {server_config.name} ({pkg_name}) on {host}: {e}")
1854+
1855+
except ValueError as e:
1856+
print(f"✗ Invalid host '{host}': {e}")
1857+
continue
17561858

17571859
# Report results
17581860
if success_count == total_operations:

0 commit comments

Comments
 (0)