mcp-souschef 3.2.0__py3-none-any.whl → 3.5.2__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.
@@ -1,33 +1,40 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-souschef
3
- Version: 3.2.0
3
+ Version: 3.5.2
4
4
  Summary: AI-powered MCP server for Chef to Ansible conversion
5
5
  License: MIT
6
6
  License-File: LICENSE
7
7
  Keywords: chef,ansible,migration,infrastructure,automation,mcp,ai,conversion
8
8
  Author: SousChef Contributors
9
- Requires-Python: >=3.13,<4.0
9
+ Requires-Python: >=3.10,<4.0
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Intended Audience :: System Administrators
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
16
19
  Classifier: Programming Language :: Python :: 3.13
17
20
  Classifier: Programming Language :: Python :: 3.14
18
21
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
22
  Classifier: Topic :: System :: Systems Administration
20
23
  Classifier: Topic :: Utilities
24
+ Provides-Extra: ai
25
+ Provides-Extra: all
21
26
  Provides-Extra: ui
22
- Requires-Dist: anthropic (>=0.75.0)
27
+ Requires-Dist: anthropic (>=0.75.0) ; extra == "ai" or extra == "all"
23
28
  Requires-Dist: click (>=8.1.0)
24
29
  Requires-Dist: mcp (>=1.25.0)
25
- Requires-Dist: openai (>=1.0.0)
26
- Requires-Dist: pandas (>=2.0.0) ; extra == "ui"
27
- Requires-Dist: plotly (>=5.0.0)
30
+ Requires-Dist: openai (>=1.0.0) ; extra == "ai" or extra == "all"
31
+ Requires-Dist: pandas (>=2.0.0) ; extra == "ui" or extra == "all"
32
+ Requires-Dist: plotly (>=5.17.0,<7.0) ; extra == "ui" or extra == "all"
33
+ Requires-Dist: pydantic (>=2.0.0)
28
34
  Requires-Dist: python-dotenv (>=1.2.1)
29
35
  Requires-Dist: pyyaml (>=6.0.0)
30
- Requires-Dist: streamlit (>=1.28.0)
36
+ Requires-Dist: requests (>=2.31.0)
37
+ Requires-Dist: streamlit (>=1.28.0) ; extra == "ui" or extra == "all"
31
38
  Project-URL: Documentation, https://kpeacocke.github.io/souschef/
32
39
  Project-URL: Homepage, https://github.com/kpeacocke/souschef
33
40
  Project-URL: Repository, https://github.com/kpeacocke/souschef
@@ -40,7 +47,7 @@ An AI-powered MCP (Model Context Protocol) server that provides comprehensive Ch
40
47
  [![GitHub release](https://img.shields.io/github/v/release/kpeacocke/souschef)](https://github.com/kpeacocke/souschef/releases)
41
48
  [![Python Version](https://img.shields.io/badge/python-3.14%2B-blue.svg)](https://www.python.org/downloads/)
42
49
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
43
- [![Test Coverage](https://img.shields.io/badge/coverage-91%25-brightgreen.svg)](htmlcov/index.html)
50
+ [![Test Coverage](https://img.shields.io/badge/coverage-83%25-green.svg)](htmlcov/index.html)
44
51
  [![Code style: Ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
45
52
  [![Type Checked: mypy](https://img.shields.io/badge/type%20checked-mypy-blue.svg)](http://mypy-lang.org/)
46
53
  [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=kpeacocke_souschef&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=kpeacocke_souschef)
@@ -49,17 +56,17 @@ An AI-powered MCP (Model Context Protocol) server that provides comprehensive Ch
49
56
 
50
57
  ## Overview - Chef to Ansible features
51
58
 
52
- SousChef is a complete enterprise-grade migration platform with **32 primary MCP tools** organised across **10 major capability areas** to facilitate Chef-to-Ansible AWX/AAP migrations. From cookbook analysis to deployment pattern conversion, including Chef Habitat to containerised deployments and CI/CD pipeline generation, SousChef provides everything needed for a successful infrastructure automation migration.
59
+ SousChef is a complete enterprise-grade migration platform with **35 primary MCP tools** organised across **11 major capability areas** to facilitate Chef-to-Ansible AWX/AAP migrations. From cookbook analysis to deployment pattern conversion, including Chef Habitat to containerised deployments, Chef Server integration, and CI/CD pipeline generation, SousChef provides everything needed for a successful infrastructure automation migration.
53
60
 
54
61
  ### About Tool Counts
55
62
 
56
- **Why 32 tools in the documentation but more in the server?**
63
+ **Why 35 tools in the documentation but more in the server?**
57
64
 
58
- The MCP server provides **37 total tools** (35 public + 2 internal). This documentation focuses on the **32 primary user-facing tools** that cover the main migration capabilities. The remaining 3 tools are low-level filesystem operations and helper utilities used internally by the main tools.
65
+ The MCP server provides **38 total tools**. This documentation focuses on the **35 primary user-facing tools** that cover the main migration capabilities. The remaining 3 tools are low-level filesystem operations used internally by the main tools.
59
66
 
60
- As a user, you'll primarily interact with the 27 documented tools. Your AI assistant may use the additional tools automatically when needed, but you don't need to know about them for successful migrations.
67
+ As a user, you'll primarily interact with the documented tools. Your AI assistant may use the additional tools automatically when needed, but you don't need to know about them for successful migrations.
61
68
 
62
- > **For developers:** See `souschef/server.py` for the complete list of all 37 registered tools.
69
+ > **For developers:** See `souschef/server.py` for the complete list of all 38 registered tools.
63
70
 
64
71
  ## Model Agnostic - Works with Any AI Model
65
72
 
@@ -72,7 +79,7 @@ As a user, you'll primarily interact with the 27 documented tools. Your AI assis
72
79
  - **Local Models** (Ollama, llama.cpp, etc.)
73
80
  - **Custom Enterprise Models**
74
81
 
75
- **How it works:** You choose your AI model provider in your MCP client. SousChef provides the Chef/Ansible expertise through 27 specialized tools. The model calls these tools to help with your migration.
82
+ **How it works:** You choose your AI model provider in your MCP client. SousChef provides the Chef/Ansible expertise through 35 specialized tools. The model calls these tools to help with your migration.
76
83
 
77
84
  > See [config/CONFIGURATION.md](config/CONFIGURATION.md) for configuration examples with different model providers.
78
85
 
@@ -83,6 +90,28 @@ As a user, you'll primarily interact with the 27 documented tools. Your AI assis
83
90
  - **[API Reference](docs/api-reference/)** - Detailed tool documentation
84
91
  - **[Migration Guide](docs/migration-guide/)** - Step-by-step migration process
85
92
 
93
+ ## What's New in v3.4.0-beta
94
+
95
+ **Chef Server Integration & AI-Enhanced Template Conversion** - New tools for dynamic inventory and intelligent template conversion:
96
+
97
+ - **Chef Server Connectivity**: Validate Chef Server connections and query nodes with `validate_chef_server_connection` and `get_chef_nodes`
98
+ - **AI-Enhanced Templates**: Convert ERB to Jinja2 with AI validation using `convert_template_with_ai` for complex Ruby logic
99
+ - **CLI Commands**: New commands `validate-chef-server`, `query-chef-nodes`, and `convert-template-ai` for command-line access
100
+ - **Streamlit UI**: Chef Server Settings page for managing server configuration and validation
101
+
102
+ ## What's New in v3.3.0
103
+
104
+ **AI-Assisted Effort Estimation** - SousChef now displays realistic migration effort comparisons directly in the Streamlit UI:
105
+
106
+ - **Manual Migration Estimates**: Full effort without AI assistance
107
+ - **SousChef-Assisted Estimates**: 50% time reduction through automated boilerplate conversion
108
+ - **Time Savings Display**: Instant visual comparison showing hours saved and efficiency gains
109
+ - **Interactive Metrics**: Summary and per-cookbook effort comparisons with clear deltas
110
+
111
+ Example: A cookbook estimated at 40 hours of manual work shows SousChef-assisted time as 20 hours, saving 20 hours (50%) and reducing team needs from 2 developers to 1.
112
+
113
+ See the [Assessment Guide](docs/migration-guide/assessment.md#effort-estimation-model) for details on the effort estimation model.
114
+
86
115
  ## Installation
87
116
 
88
117
  ```bash
@@ -299,6 +328,54 @@ Output formats:
299
328
  - **analyse_cookbook_dependencies** - Analyse dependencies and migration order
300
329
  - **generate_migration_report** - Generate executive and technical migration reports
301
330
 
331
+ ### 12. Chef Server Integration & Dynamic Inventory
332
+
333
+ Dynamic inventory generation and Chef Server connectivity for hybrid environments:
334
+
335
+ - **validate_chef_server_connection** - Test Chef Server REST API connectivity and authentication
336
+ - **get_chef_nodes** - Query Chef Server for nodes matching search criteria, extracting roles, environment, platform, and IP information
337
+ - **convert_template_with_ai** - Convert ERB templates to Jinja2 with AI-based validation for complex Ruby logic
338
+
339
+ #### Chef Server Features
340
+
341
+ - **Connection Validation**: Test Chef Server connectivity before migrations
342
+ - **Dynamic Node Queries**: Search Chef Server by role, environment, or custom attributes
343
+ - **Node Metadata Extraction**: Retrieve IP addresses, FQDNs, platforms, and roles for inventory
344
+ - **AI-Enhanced Conversion**: Intelligent ERB→Jinja2 conversion with validation for complex Ruby constructs
345
+ - **Fallback Handling**: Graceful degradation when Chef Server is unavailable
346
+
347
+ #### Usage Examples
348
+
349
+ ```bash
350
+ # Validate Chef Server connection
351
+ souschef validate-chef-server --server-url https://chef.example.com --node-name admin
352
+
353
+ # Query Chef Server for nodes
354
+ souschef query-chef-nodes --search-query "role:web_server" --json
355
+
356
+ # Convert template with AI assistance
357
+ souschef convert-template-ai /path/to/template.erb --ai --output /path/to/output.j2
358
+ ```
359
+
360
+ #### MCP Tool Usage
361
+
362
+ ```python
363
+ # Validate Chef Server from AI assistant
364
+ validate_chef_server_connection(
365
+ server_url="https://chef.example.com",
366
+ node_name="admin"
367
+ )
368
+
369
+ # Query nodes for dynamic inventory
370
+ get_chef_nodes(search_query="role:web_server AND environment:production")
371
+
372
+ # Convert template with AI validation
373
+ convert_template_with_ai(
374
+ erb_path="/path/to/template.erb",
375
+ use_ai_enhancement=True
376
+ )
377
+ ```
378
+
302
379
  ## Migration Workflow
303
380
 
304
381
  ### Phase 1: Discovery & Assessment
@@ -389,7 +466,12 @@ profile_parsing_operation recipe /path/to/recipe.rb --detailed
389
466
  Interactive web-based interface for Chef-to-Ansible migration planning and visualization:
390
467
 
391
468
  - **Cookbook Analysis Dashboard**: Interactive directory scanning with metadata parsing and complexity assessment
392
- - **Migration Planning Wizard**: Step-by-step migration planning with effort estimation and risk analysis
469
+ - **AI-Assisted Effort Estimation** (v3.3.0+):
470
+ - **Manual Migration Estimate**: Full effort without AI assistance
471
+ - **SousChef-Assisted Estimate**: 50% time reduction through automated boilerplate conversion
472
+ - **Time Savings Display**: Clear comparison showing hours saved and efficiency percentage
473
+ - **Visual Metrics**: Side-by-side metric cards for instant visual comparison
474
+ - **Migration Planning Wizard**: Step-by-step migration planning with dual effort scenarios and risk analysis
393
475
  - **Dependency Mapping**: Visual dependency graphs showing cookbook relationships and migration ordering
394
476
  - **Validation Reports**: Conversion validation results with syntax checking and best practice compliance
395
477
  - **Progress Tracking**: Real-time migration progress with completion metrics and bottleneck identification
@@ -420,6 +502,51 @@ docker run -p 9999:9999 souschef-ui
420
502
  docker-compose up
421
503
  ```
422
504
 
505
+ **Run Published Image from GitHub Container Registry:**
506
+
507
+ SousChef images are automatically published to GitHub Container Registry (GHCR) on each release:
508
+
509
+ ```bash
510
+ # Pull the latest released image
511
+ docker pull ghcr.io/mcp-souschef:latest
512
+
513
+ # Or pull a specific version
514
+ docker pull ghcr.io/mcp-souschef:3.2.0
515
+
516
+ # Run the image with your .env file
517
+ docker run -p 9999:9999 \
518
+ --env-file .env \
519
+ ghcr.io/mcp-souschef:latest
520
+
521
+ # Or with docker-compose
522
+ cat > docker-compose.override.yml << 'EOF'
523
+ version: '3.8'
524
+ services:
525
+ souschef-ui:
526
+ image: ghcr.io/mcp-souschef:latest
527
+ build: ~
528
+ EOF
529
+ docker-compose up
530
+ ```
531
+
532
+ **Container Images:**
533
+
534
+ - **Registry**: GitHub Container Registry (GHCR)
535
+ - **Image Name**: `mcp-souschef`
536
+ - **Full URL**: `ghcr.io/mcp-souschef`
537
+ - **Available Tags**:
538
+ - `latest` - Most recent release
539
+ - `3.2.0` - Specific version (semver)
540
+ - `3.2` - Latest patch of a minor version
541
+ - `3` - Latest patch of a major version
542
+
543
+ **Why use GHCR?**
544
+
545
+ - Integrated with GitHub releases and CI/CD
546
+ - Faster pulls for users in GitHub ecosystem
547
+ - Security scanning and SBOM included
548
+ - Multi-platform support (amd64, arm64)
549
+
423
550
  **Docker Environment Configuration:**
424
551
 
425
552
  SousChef supports AI configuration via environment variables in Docker containers. Create a `.env` file in your project root:
@@ -443,6 +570,7 @@ SOUSCHEF_AI_BASE_URL=
443
570
  SOUSCHEF_AI_PROJECT_ID=
444
571
  SOUSCHEF_AI_TEMPERATURE=0.7
445
572
  SOUSCHEF_AI_MAX_TOKENS=4000
573
+ SOUSCHEF_ALLOWED_HOSTNAMES=api.example.com,*.example.org
446
574
 
447
575
  # Streamlit Configuration (optional)
448
576
  STREAMLIT_SERVER_PORT=9999
@@ -465,6 +593,7 @@ STREAMLIT_SERVER_HEADLESS=true
465
593
  - `SOUSCHEF_AI_PROJECT_ID` - Project ID for Watsonx (optional)
466
594
  - `SOUSCHEF_AI_TEMPERATURE` - Model temperature 0.0-2.0 (optional, default: 0.7)
467
595
  - `SOUSCHEF_AI_MAX_TOKENS` - Maximum tokens to generate (optional, default: 4000)
596
+ - `SOUSCHEF_ALLOWED_HOSTNAMES` - Comma-separated list of allowed hostnames for outbound API requests (optional)
468
597
 
469
598
  **Docker Compose (recommended for development):**
470
599
 
@@ -506,7 +635,7 @@ The UI includes sophisticated dependency graph visualization powered by NetworkX
506
635
  - **Interactive Exploration**: Zoom, pan, and hover over nodes to explore complex dependency relationships
507
636
  - **Color Coding**: Visual distinction between cookbooks, dependencies, community cookbooks, and circular dependencies
508
637
  - **Static Export**: Matplotlib-based static graphs for reports and documentation
509
- - **Large Graph Support**: Optimized layouts for complex cookbook ecosystems
638
+ - **Large Graph Support**: Optimised layouts for complex cookbook ecosystems
510
639
 
511
640
  #### Real-Time Progress Tracking
512
641
 
@@ -699,7 +828,7 @@ Following enterprise-grade testing standards with comprehensive test coverage:
699
828
  - **Specialized Tests**: Enhanced guards (test_enhanced_guards.py), error handling (test_error_paths.py, test_error_recovery.py), real-world fixtures (test_real_world_fixtures.py)
700
829
  - **Performance Tests**: Benchmarking and optimization validation (test_performance.py)
701
830
  - **Snapshot Tests**: Regression testing for output stability (test_snapshots.py)
702
- - **92% Coverage**: Comprehensive test coverage exceeding the 90% target for production readiness
831
+ - **83% Coverage**: Comprehensive test coverage approaching the 90% target for production readiness
703
832
 
704
833
  ### Quality Assurance
705
834
 
@@ -1069,18 +1198,18 @@ poetry run pytest
1069
1198
  poetry run pytest --cov=souschef --cov-report=term-missing --cov-report=html
1070
1199
 
1071
1200
  # Run specific test suites
1072
- poetry run pytest tests/test_server.py # Core unit tests
1073
- poetry run pytest tests/test_cli.py # CLI tests
1074
- poetry run pytest tests/test_mcp.py # MCP protocol tests
1075
- poetry run pytest tests/test_integration.py # Integration tests
1076
- poetry run pytest tests/test_integration_accuracy.py # Accuracy validation
1077
- poetry run pytest tests/test_enhanced_guards.py # Guard conversion tests
1078
- poetry run pytest tests/test_error_paths.py # Error handling
1079
- poetry run pytest tests/test_error_recovery.py # Error recovery
1080
- poetry run pytest tests/test_real_world_fixtures.py # Real-world cookbooks
1081
- poetry run pytest tests/test_property_based.py # Hypothesis fuzz tests
1082
- poetry run pytest tests/test_performance.py # Performance benchmarks
1083
- poetry run pytest tests/test_snapshots.py # Snapshot regression tests
1201
+ poetry run pytest tests/unit/test_server.py # Core unit tests
1202
+ poetry run pytest tests/unit/test_cli.py # CLI tests
1203
+ poetry run pytest tests/e2e/test_mcp.py # MCP protocol tests
1204
+ poetry run pytest tests/integration/test_integration.py # Integration tests
1205
+ poetry run pytest tests/integration/test_integration_accuracy.py # Accuracy validation
1206
+ poetry run pytest tests/unit/test_enhanced_guards.py # Guard conversion tests
1207
+ poetry run pytest tests/unit/test_error_paths.py # Error handling
1208
+ poetry run pytest tests/unit/test_error_recovery.py # Error recovery
1209
+ poetry run pytest tests/integration/test_real_world_fixtures.py # Real-world cookbooks
1210
+ poetry run pytest tests/unit/test_property_based.py # Hypothesis fuzz tests
1211
+ poetry run pytest tests/integration/test_performance.py # Performance benchmarks
1212
+ poetry run pytest tests/unit/test_snapshots.py # Snapshot regression tests
1084
1213
 
1085
1214
  # Run with benchmarks
1086
1215
  poetry run pytest --benchmark-only
@@ -1120,7 +1249,7 @@ The project includes comprehensive test coverage across multiple dimensions:
1120
1249
  - **Snapshots** (`test_snapshots.py`): Regression testing for output stability
1121
1250
 
1122
1251
  5. **Test Fixtures**
1123
- - Sample Chef cookbooks in `tests/fixtures/`
1252
+ - Sample Chef cookbooks in `tests/integration/fixtures/`
1124
1253
  - Multiple cookbook types: apache2, docker, mysql, nodejs, legacy Chef 12, Habitat plans
1125
1254
  - Real-world metadata, recipes, attributes, and resources
1126
1255
  - Used across integration and accuracy testing
@@ -1,23 +1,27 @@
1
1
  souschef/__init__.py,sha256=EqHUtFUSPV2fOQO3lhmyhMPfX7cUso88I6rEjvG8PRA,1434
2
- souschef/assessment.py,sha256=zsgdnMvaHDN-3FSJ3W8q7a1lsDFS0qqklUg4G0n5IOs,98094
2
+ souschef/assessment.py,sha256=g_fxMjek_n5LgLlkZz_yWIADS9A3Z3qhFGGOz7lqm6M,100982
3
3
  souschef/ci/__init__.py,sha256=GHaqDk4auB2kI7_fQtF2FRg5nP-iX6wJchj_uTlXcYg,411
4
4
  souschef/ci/common.py,sha256=vHX1wtDNaTPiPfwW9If3aBm1hRmnTto2r3MkZGwYPTM,4757
5
5
  souschef/ci/github_actions.py,sha256=EVnnOPTLCeUmTfR-acpLp-c_dxapMfrrDWaK4SSBkdM,7818
6
6
  souschef/ci/gitlab_ci.py,sha256=4FcK8edci3ixuiUtYb6EFaAfsqjz0OBmW-lyPLH3YzY,6708
7
7
  souschef/ci/jenkins_pipeline.py,sha256=XEuZrVKVmOlQOKucgGcd3vhAFh5qT05ILNnjKjkqTPU,7362
8
- souschef/cli.py,sha256=8kxVkvg9eFOWIII29p9sQm9u2Z6kfhmdJThBlpxTdrA,38159
8
+ souschef/cli.py,sha256=O26NaN3HR6qfWDfWETkwQNqaIeWZh2VWNKATVoZBn1w,47702
9
9
  souschef/converters/__init__.py,sha256=kkPm758XiFDdUYvdVPAVjssFvf15LasJcob1EY1EMIs,681
10
10
  souschef/converters/cookbook_specific.py,sha256=ZvE9-bZtyXuf2E3HW4E9_GWzAqtm7e4YHj9qm1Xu_XI,3767
11
11
  souschef/converters/habitat.py,sha256=4eVGAcX0576zLXW9yqYvuaRxOK2g6BOIJo_ws-PonHU,22516
12
- souschef/converters/playbook.py,sha256=dyeAzcCyWcBUc6o9IcBTB4N4XVIX4cImNFsNe2TXTSU,94395
12
+ souschef/converters/playbook.py,sha256=F_6tSFyrlT55vLdi632g7Yd5rkNRPlq4pnb5HSMrs78,102773
13
13
  souschef/converters/resource.py,sha256=NYMcp1-obg_ad_XPuYDuUH_0j65agRbAeWzXPfbSi5c,13570
14
- souschef/converters/template.py,sha256=swX7LpWrKZgFtg6MaR7rltShBkPDbQAb65d1NF_nILo,5447
14
+ souschef/converters/template.py,sha256=sXMLm2egA2dSOY-SLoKjXOYH1dHK_ozj67YC89sg8dc,9268
15
15
  souschef/core/__init__.py,sha256=PXiZSEfXw77te3SvMRKy0_g0CwQqworbgFLca89u7wA,1969
16
+ souschef/core/ai_schemas.py,sha256=TJCLsZ_3l8ub2zcVuSE0h6usMqxnrce8o3n2fxAKjvM,2860
16
17
  souschef/core/constants.py,sha256=AyIpc9cJjQEDc1yOcoKc_2-cJB4PekSpPKEK2S9jDl8,5122
17
18
  souschef/core/errors.py,sha256=zj_LHDRxUvHmcs-nZjOWu4B_MhY5WVq2okyZOxyycCI,8605
18
- souschef/core/metrics.py,sha256=k56opuVmRorrBwErbxLgXu_GkfGZXA_rEfhcsHs1JHI,9850
19
+ souschef/core/http_client.py,sha256=f7laiNsIAX95-fVyAfnQXUdOL-Cv7ZWxi5xLnmTAkF4,12873
20
+ souschef/core/logging.py,sha256=3X6u6JUI5reIa7p1I4T22O69ME2ALrOxC8xacA6MKO0,9974
21
+ souschef/core/metrics.py,sha256=NuZNKi2o6UcrsJ52s8QQAoDeUiEi0HClZHNfPXsVRo4,12797
19
22
  souschef/core/path_utils.py,sha256=eU5lNujUX45MbMahstm4C0gJxKN14QIKaxmgD6O5l9U,8993
20
23
  souschef/core/ruby_utils.py,sha256=vUeFZBdjbFFFJlwo4fIboR23rXmbcYL2Tztt4RYhps0,1043
24
+ souschef/core/url_validation.py,sha256=AeUKNVN_AWBxkp5b5QskRgQ-4IB--A-D60ltRbN_chI,6169
21
25
  souschef/core/validation.py,sha256=DXfkm1p5prSAJ-Oruk5JekNiDFI49Dql1bGEzKymYXs,19158
22
26
  souschef/deployment.py,sha256=UKxq9G06b7de_5ioA7RdxdjwQaW2mJKf6WlNl0Sq5wk,62193
23
27
  souschef/filesystem/__init__.py,sha256=2H7Pdeedz0MfmgpRlmii_vx61qr0jtxFndT0APPm6Qs,142
@@ -33,15 +37,16 @@ souschef/parsers/recipe.py,sha256=PNGQKVv0wwqj_q8WYT2NjsSavLA9WXdo2C9bp6pY9qc,71
33
37
  souschef/parsers/resource.py,sha256=WcKsUjP3yZx2-2nsTUTLPxIxtfwEihHVNkv3OC6bBHs,5359
34
38
  souschef/parsers/template.py,sha256=v51BMUHmr9FYwE7zDNFA01dsClWHLrc_YD3rCM-2lqc,10543
35
39
  souschef/profiling.py,sha256=a6Pn57CZR3UPR1YIY8gfbuTPRuPkFrfIFBmctOcaZgY,17315
36
- souschef/server.py,sha256=jtNiPX9uWP5KoRCZj0nasBlxPooAy5AHKcW-HO0YWU4,122047
40
+ souschef/server.py,sha256=Mzf8hnoGd83C46fO99mCw_4dHS7KttXfOmlVn7MJQ9c,125886
37
41
  souschef/ui/__init__.py,sha256=U3W6X4ww7CxQVuetcocObWn5iY6lUFiNX7WoDBJeD34,195
38
- souschef/ui/app.py,sha256=0lFphbMTL21H_CpT9rO2tITj48b4_zK8YZqW2_sm8TU,101744
42
+ souschef/ui/app.py,sha256=ru1KDYqnEDQvq46HHLNu1JGwzIScr7Lm11BeqnXpvQs,102343
39
43
  souschef/ui/health_check.py,sha256=mEzec8L6XPRekOBAXngqQz5dnzal-a4p3D70mkPriiA,903
40
- souschef/ui/pages/ai_settings.py,sha256=tIwgWBqxCEqFykmrLRPiVQjl-m-I1Mbq0RoB1YA5faM,17774
41
- souschef/ui/pages/cookbook_analysis.py,sha256=qcCYtnk01XGD14wbQe5EzT3Fx_ETkIjMhz8r3ZOXwm8,146148
44
+ souschef/ui/pages/ai_settings.py,sha256=AevsSuiRcfYuQqtYcu1ijp8x3G3PYAUBXzxLmSSVp2c,22105
45
+ souschef/ui/pages/chef_server_settings.py,sha256=_ch7qvZ02luwNRFqWN6ATMbVUuenYlrbCpRGEFjr-40,8585
46
+ souschef/ui/pages/cookbook_analysis.py,sha256=ilAQTzFQyJsH6Mk65jjQbk5LKIsBkj9XibF4q648tpg,148623
42
47
  souschef/ui/pages/validation_reports.py,sha256=R3xHTJb_y2b0tI8N0qPF1oS4f9ZVb539_82dj5nmmxA,7593
43
- mcp_souschef-3.2.0.dist-info/METADATA,sha256=8yGaW_bXIxvKHzwS7x_gBMXqH850qif_HuTyq2nnDVY,41878
44
- mcp_souschef-3.2.0.dist-info/WHEEL,sha256=3ny-bZhpXrU6vSQ1UPG34FoxZBp3lVcvK0LkgUz6VLk,88
45
- mcp_souschef-3.2.0.dist-info/entry_points.txt,sha256=NVSk61tLG4W0xEkWGOMXAVCIUyodyZCY_j3Z_0m6rkQ,80
46
- mcp_souschef-3.2.0.dist-info/licenses/LICENSE,sha256=t31dYSuvYYNw6trj-coWSsLK-Tg_Iyl8ObcolQcrUKM,1078
47
- mcp_souschef-3.2.0.dist-info/RECORD,,
48
+ mcp_souschef-3.5.2.dist-info/METADATA,sha256=ih95vf1qxSdw0VKL_wkka3Sx3aj8SoxB1SgGbhVPBAM,47268
49
+ mcp_souschef-3.5.2.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
50
+ mcp_souschef-3.5.2.dist-info/entry_points.txt,sha256=NVSk61tLG4W0xEkWGOMXAVCIUyodyZCY_j3Z_0m6rkQ,80
51
+ mcp_souschef-3.5.2.dist-info/licenses/LICENSE,sha256=t31dYSuvYYNw6trj-coWSsLK-Tg_Iyl8ObcolQcrUKM,1078
52
+ mcp_souschef-3.5.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.3.0
2
+ Generator: poetry-core 2.3.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
souschef/assessment.py CHANGED
@@ -25,6 +25,7 @@ from souschef.core.metrics import (
25
25
  estimate_effort_for_complexity,
26
26
  )
27
27
  from souschef.core.path_utils import _validated_candidate, safe_glob
28
+ from souschef.core.url_validation import validate_user_provided_url
28
29
  from souschef.core.validation import (
29
30
  ValidationEngine,
30
31
  ValidationLevel,
@@ -34,9 +35,9 @@ from souschef.core.validation import (
34
35
 
35
36
  # Optional AI provider imports
36
37
  try:
37
- import requests # type: ignore[import-untyped]
38
+ import requests
38
39
  except ImportError:
39
- requests = None
40
+ requests = None # type: ignore[assignment]
40
41
 
41
42
  try:
42
43
  from ibm_watsonx_ai import APIClient # type: ignore[import-not-found]
@@ -1200,17 +1201,28 @@ def _assess_single_cookbook(cookbook_path: Path) -> dict:
1200
1201
 
1201
1202
 
1202
1203
  def _format_overall_metrics(metrics: dict) -> str:
1203
- """Format overall migration metrics."""
1204
+ """Format overall migration metrics with manual and SousChef-assisted estimates."""
1205
+ effort_metrics = EffortMetrics(metrics["estimated_effort_days"])
1206
+
1204
1207
  return f"""• Total Cookbooks: {metrics["total_cookbooks"]}
1205
1208
  • Total Recipes: {metrics["total_recipes"]}
1206
1209
  • Total Resources: {metrics["total_resources"]}
1207
1210
  • Average Complexity: {metrics.get("avg_complexity", 0):.1f}/100
1208
- • Estimated Total Effort: {metrics["estimated_effort_days"]:.1f} person-days
1209
- Estimated Duration: {EffortMetrics(metrics["estimated_effort_days"]).estimated_weeks_range}"""
1211
+
1212
+ ## Manual Migration Effort (Without SousChef):
1213
+ • Estimated Effort: {metrics["estimated_effort_days"]:.1f} person-days ({effort_metrics.estimated_hours:.0f} hours)
1214
+ • Estimated Duration: {effort_metrics.estimated_weeks_range}
1215
+ • Team Required: {max(2, int(metrics["estimated_effort_days"] / 15))} developers
1216
+
1217
+ ## AI-Assisted Migration (With SousChef):
1218
+ • Estimated Effort: {effort_metrics.estimated_days_with_souschef:.1f} person-days ({effort_metrics.estimated_hours_with_souschef:.0f} hours)
1219
+ • Estimated Duration: {effort_metrics.estimated_weeks_range_with_souschef}
1220
+ • Team Required: {max(1, int(effort_metrics.estimated_days_with_souschef / 15))} developers
1221
+ • **Time Saved: {effort_metrics.time_saved:.1f} days ({effort_metrics.efficiency_gain_percent}% faster)**"""
1210
1222
 
1211
1223
 
1212
1224
  def _format_cookbook_assessments(assessments: list) -> str:
1213
- """Format individual cookbook assessments."""
1225
+ """Format individual cookbook assessments with manual and AI-assisted estimates."""
1214
1226
  if not assessments:
1215
1227
  return "No cookbooks assessed."
1216
1228
 
@@ -1226,13 +1238,14 @@ def _format_cookbook_assessments(assessments: list) -> str:
1226
1238
  formatted = []
1227
1239
  for assessment in assessments:
1228
1240
  priority_icon = _get_priority_icon(assessment["migration_priority"])
1241
+ effort_metrics = EffortMetrics(assessment["estimated_effort_days"])
1242
+
1229
1243
  formatted.append(f"""### {assessment["cookbook_name"]} {priority_icon}
1230
1244
  • Complexity Score: {assessment["complexity_score"]:.1f}/100
1231
- Estimated Effort: {assessment["estimated_effort_days"]} days
1232
- Recipes: {assessment["metrics"]["recipe_count"]}
1233
- Resources: {assessment["metrics"]["resource_count"]}
1234
- Custom Resources: {assessment["metrics"]["custom_resources"]}
1235
- • Challenges: {len(assessment["challenges"])}""")
1245
+ Recipes: {assessment["metrics"]["recipe_count"]} | Resources: {assessment["metrics"]["resource_count"]} | Custom Resources: {assessment["metrics"]["custom_resources"]}
1246
+ Manual Effort: {assessment["estimated_effort_days"]:.1f} days ({effort_metrics.estimated_weeks_range})
1247
+ With SousChef: {effort_metrics.estimated_days_with_souschef:.1f} days ({effort_metrics.estimated_weeks_range_with_souschef}) - Save {effort_metrics.time_saved:.1f} days
1248
+ Migration Challenges: {len(assessment["challenges"])}""")
1236
1249
 
1237
1250
  return "\n\n".join(formatted)
1238
1251
 
@@ -1445,26 +1458,56 @@ def _assess_migration_risks(assessments: list, target_platform: str) -> str:
1445
1458
 
1446
1459
 
1447
1460
  def _estimate_resource_requirements(metrics: dict, target_platform: str) -> str:
1448
- """Estimate resource requirements for migration."""
1461
+ """Estimate resource requirements for migration with and without SousChef."""
1449
1462
  total_effort = metrics["estimated_effort_days"]
1463
+ effort_metrics = EffortMetrics(total_effort)
1450
1464
 
1451
- # Team size recommendations
1465
+ # Manual migration requirements
1452
1466
  if total_effort < 20:
1453
- team_size = "1 developer + 1 reviewer"
1454
- timeline = "4-6 weeks"
1467
+ manual_team = "1 developer + 1 reviewer"
1468
+ manual_timeline = "4-6 weeks"
1455
1469
  elif total_effort < 50:
1456
- team_size = "2 developers + 1 senior reviewer"
1457
- timeline = "6-10 weeks"
1470
+ manual_team = "2 developers + 1 senior reviewer"
1471
+ manual_timeline = "6-10 weeks"
1472
+ else:
1473
+ manual_team = "3-4 developers + 1 tech lead + 1 architect"
1474
+ manual_timeline = "10-16 weeks"
1475
+
1476
+ # SousChef-assisted requirements
1477
+ souschef_effort = effort_metrics.estimated_days_with_souschef
1478
+ if souschef_effort < 20:
1479
+ souschef_team = "1 developer (with SousChef AI assistance)"
1480
+ souschef_timeline = "2-3 weeks"
1481
+ elif souschef_effort < 50:
1482
+ souschef_team = "1-2 developers + 1 reviewer (with SousChef)"
1483
+ souschef_timeline = "3-5 weeks"
1458
1484
  else:
1459
- team_size = "3-4 developers + 1 tech lead + 1 architect"
1460
- timeline = "10-16 weeks"
1485
+ souschef_team = "2-3 developers + 1 tech lead (with SousChef)"
1486
+ souschef_timeline = "5-8 weeks"
1461
1487
 
1462
- return f""" **Team Size:** {team_size}
1463
- • **Estimated Timeline:** {timeline}
1464
- • **Total Effort:** {total_effort:.1f} person-days
1488
+ return f"""## Manual Migration (Without AI Assistance):
1489
+ • **Team Size:** {manual_team}
1490
+ • **Estimated Timeline:** {manual_timeline}
1491
+ • **Total Effort:** {total_effort:.1f} person-days ({effort_metrics.estimated_hours:.0f} hours)
1492
+ • **Infrastructure:** {target_platform.replace("_", "/").upper()} environment
1493
+ • **Testing:** Dedicated test environment required
1494
+ • **Training:** 3-5 days Ansible/AWX training for team
1495
+
1496
+ ## AI-Assisted Migration (With SousChef):
1497
+ • **Team Size:** {souschef_team}
1498
+ • **Estimated Timeline:** {souschef_timeline}
1499
+ • **Total Effort:** {souschef_effort:.1f} person-days ({effort_metrics.estimated_hours_with_souschef:.0f} hours)
1500
+ • **Time Savings:** {effort_metrics.time_saved:.1f} days ({effort_metrics.efficiency_gain_percent}% reduction)
1465
1501
  • **Infrastructure:** {target_platform.replace("_", "/").upper()} environment
1466
- • **Testing:** Dedicated test environment recommended
1467
- • **Training:** 2-3 days Ansible/AWX training for team"""
1502
+ • **Testing:** Automated validation + human review
1503
+ • **Training:** 1-2 days SousChef usage + Ansible basics
1504
+
1505
+ **SousChef Benefits:**
1506
+ • Automated boilerplate conversion (60-70% of work)
1507
+ • Built-in best practices validation
1508
+ • Faster iteration cycles
1509
+ • Consistent output quality
1510
+ • Reduced human error"""
1468
1511
 
1469
1512
 
1470
1513
  def _analyse_cookbook_dependencies_detailed(cookbook_path: Path | str) -> dict:
@@ -2554,8 +2597,21 @@ def _call_ai_api(
2554
2597
  elif ai_provider == "openai":
2555
2598
  return _call_openai_api(prompt, api_key, model, temperature, max_tokens)
2556
2599
  elif ai_provider == "watson":
2600
+ validated_url = None
2601
+ if base_url:
2602
+ try:
2603
+ validated_url = validate_user_provided_url(base_url)
2604
+ except ValueError:
2605
+ return None
2606
+
2557
2607
  return _call_watson_api(
2558
- prompt, api_key, model, temperature, max_tokens, project_id, base_url
2608
+ prompt,
2609
+ api_key,
2610
+ model,
2611
+ temperature,
2612
+ max_tokens,
2613
+ project_id,
2614
+ validated_url,
2559
2615
  )
2560
2616
  else:
2561
2617
  return None