Conversation
Features/hub integration
…-use-mcp-tools refactor: remove module system, migrate to MCP hub tools architecture
feat(tui): add terminal UI with hub and agent management
… for project storage
… persistent sessions
There was a problem hiding this comment.
Pull request overview
This PR pivots the codebase from the legacy “runner + local modules/workflows” model to a hub-driven MCP integration, and adds a richer CLI TUI for managing hubs/agents/builds.
Changes:
- Remove
fuzzforge-runnerand the in-repo module/SDK projects; MCP now focuses on hub tool discovery/execution. - Add hub registry/models in
fuzzforge-commonand local project storage/settings infuzzforge-mcp. - Add new TUI screens and update CLI commands/config generation; introduce CI workflows.
Reviewed changes
Copilot reviewed 151 out of 168 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Renames project branding and updates workspace/dependencies to remove runner/modules components. |
| hub-config.json | Adds an (empty) hub configuration file at repo root. |
| fuzzforge-tests/src/fuzzforge_tests/fixtures.py | Simplifies fixtures and renames execution identifier fixture. |
| fuzzforge-runner/tests/conftest.py | Removed (runner test scaffolding deleted). |
| fuzzforge-runner/tests/init.py | Removed (runner test package deleted). |
| fuzzforge-runner/src/fuzzforge_runner/storage.py | Removed (storage moved to MCP). |
| fuzzforge-runner/src/fuzzforge_runner/settings.py | Removed (settings moved to MCP). |
| fuzzforge-runner/src/fuzzforge_runner/orchestrator.py | Removed (workflow orchestration removed). |
| fuzzforge-runner/src/fuzzforge_runner/exceptions.py | Removed (runner exceptions deleted). |
| fuzzforge-runner/src/fuzzforge_runner/constants.py | Removed (runner constants deleted). |
| fuzzforge-runner/src/fuzzforge_runner/main.py | Removed (runner CLI entrypoint deleted). |
| fuzzforge-runner/src/fuzzforge_runner/init.py | Removed (runner package exports deleted). |
| fuzzforge-runner/ruff.toml | Removed (runner-specific lint config deleted). |
| fuzzforge-runner/pytest.ini | Removed (runner-specific pytest config deleted). |
| fuzzforge-runner/pyproject.toml | Removed (runner package deleted). |
| fuzzforge-runner/mypy.ini | Removed (runner-specific typing config deleted). |
| fuzzforge-runner/README.md | Removed (runner docs deleted). |
| fuzzforge-runner/Makefile | Removed (runner make targets deleted). |
| fuzzforge-modules/rust-analyzer/src/module/settings.py | Removed (module removed from repo). |
| fuzzforge-modules/rust-analyzer/src/module/models.py | Removed (module removed from repo). |
| fuzzforge-modules/rust-analyzer/src/module/mod.py | Removed (module removed from repo). |
| fuzzforge-modules/rust-analyzer/src/module/main.py | Removed (module removed from repo). |
| fuzzforge-modules/rust-analyzer/ruff.toml | Removed (module config deleted). |
| fuzzforge-modules/rust-analyzer/pyproject.toml | Removed (module package deleted). |
| fuzzforge-modules/rust-analyzer/mypy.ini | Removed (module config deleted). |
| fuzzforge-modules/rust-analyzer/README.md | Removed (module docs deleted). |
| fuzzforge-modules/rust-analyzer/Makefile | Removed (module makefile deleted). |
| fuzzforge-modules/rust-analyzer/Dockerfile | Removed (module container build deleted). |
| fuzzforge-modules/harness-tester/src/module/settings.py | Removed (module removed from repo). |
| fuzzforge-modules/harness-tester/src/module/models.py | Removed (module removed from repo). |
| fuzzforge-modules/harness-tester/src/module/feedback.py | Removed (module removed from repo). |
| fuzzforge-modules/harness-tester/src/module/main.py | Removed (module removed from repo). |
| fuzzforge-modules/harness-tester/ruff.toml | Removed (module config deleted). |
| fuzzforge-modules/harness-tester/pyproject.toml | Removed (module package deleted). |
| fuzzforge-modules/harness-tester/mypy.ini | Removed (module config deleted). |
| fuzzforge-modules/harness-tester/README.md | Removed (module docs deleted). |
| fuzzforge-modules/harness-tester/Makefile | Removed (module makefile deleted). |
| fuzzforge-modules/harness-tester/FEEDBACK_TYPES.md | Removed (module docs deleted). |
| fuzzforge-modules/harness-tester/Dockerfile | Removed (module container build deleted). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/src/module/settings.py | Removed (SDK template removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/src/module/models.py | Removed (SDK template removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/src/module/mod.py | Removed (SDK template removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/src/module/main.py | Removed (SDK template removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/ruff.toml | Removed (SDK template config removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/pyproject.toml | Removed (SDK template removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/mypy.ini | Removed (SDK template config removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/README.md | Removed (SDK template docs removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/Makefile | Removed (SDK template makefile removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/templates/fuzzforge-module-template/Dockerfile | Removed (SDK template container build removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/assets/pyproject.toml | Removed (SDK assets removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/assets/Dockerfile | Removed (SDK assets removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/api/modules/base.py | Removed (SDK runtime removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/api/models.py | Removed (SDK runtime removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/api/logs.py | Removed (SDK runtime removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/api/exceptions.py | Removed (SDK runtime removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/api/constants.py | Removed (SDK runtime removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/_cli/main.py | Removed (SDK CLI removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/_cli/create_new_module.py | Removed (SDK CLI removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/src/fuzzforge_modules_sdk/_cli/build_base_image.py | Removed (SDK CLI removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/ruff.toml | Removed (SDK config removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/pyproject.toml | Removed (SDK package removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/mypy.ini | Removed (SDK config removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/README.md | Removed (SDK docs removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/Makefile | Removed (SDK makefile removed). |
| fuzzforge-modules/fuzzforge-modules-sdk/Dockerfile | Removed (SDK container build removed). |
| fuzzforge-modules/fuzzforge-module-template/src/module/settings.py | Removed (template removed). |
| fuzzforge-modules/fuzzforge-module-template/src/module/models.py | Removed (template removed). |
| fuzzforge-modules/fuzzforge-module-template/src/module/mod.py | Removed (template removed). |
| fuzzforge-modules/fuzzforge-module-template/src/module/main.py | Removed (template removed). |
| fuzzforge-modules/fuzzforge-module-template/ruff.toml | Removed (template config removed). |
| fuzzforge-modules/fuzzforge-module-template/pyproject.toml | Removed (template package removed). |
| fuzzforge-modules/fuzzforge-module-template/mypy.ini | Removed (template config removed). |
| fuzzforge-modules/fuzzforge-module-template/README.md | Removed (template docs removed). |
| fuzzforge-modules/fuzzforge-module-template/Makefile | Removed (template makefile removed). |
| fuzzforge-modules/fuzzforge-module-template/Dockerfile | Removed (template container build removed). |
| fuzzforge-modules/crash-analyzer/src/module/settings.py | Removed (module removed from repo). |
| fuzzforge-modules/crash-analyzer/src/module/models.py | Removed (module removed from repo). |
| fuzzforge-modules/crash-analyzer/src/module/mod.py | Removed (module removed from repo). |
| fuzzforge-modules/crash-analyzer/src/module/main.py | Removed (module removed from repo). |
| fuzzforge-modules/crash-analyzer/ruff.toml | Removed (module config deleted). |
| fuzzforge-modules/crash-analyzer/pyproject.toml | Removed (module package deleted). |
| fuzzforge-modules/crash-analyzer/mypy.ini | Removed (module config deleted). |
| fuzzforge-modules/crash-analyzer/README.md | Removed (module docs deleted). |
| fuzzforge-modules/crash-analyzer/Makefile | Removed (module makefile deleted). |
| fuzzforge-modules/crash-analyzer/Dockerfile | Removed (module container build deleted). |
| fuzzforge-modules/cargo-fuzzer/src/module/settings.py | Removed (module removed from repo). |
| fuzzforge-modules/cargo-fuzzer/src/module/models.py | Removed (module removed from repo). |
| fuzzforge-modules/cargo-fuzzer/src/module/main.py | Removed (module removed from repo). |
| fuzzforge-modules/cargo-fuzzer/ruff.toml | Removed (module config deleted). |
| fuzzforge-modules/cargo-fuzzer/pyproject.toml | Removed (module package deleted). |
| fuzzforge-modules/cargo-fuzzer/mypy.ini | Removed (module config deleted). |
| fuzzforge-modules/cargo-fuzzer/README.md | Removed (module docs deleted). |
| fuzzforge-modules/cargo-fuzzer/Makefile | Removed (module makefile deleted). |
| fuzzforge-modules/cargo-fuzzer/Dockerfile | Removed (module container build deleted). |
| fuzzforge-mcp/tests/test_resources.py | Updates MCP tool tests to reflect hub/project toolset. |
| fuzzforge-mcp/src/fuzzforge_mcp/tools/workflows.py | Removed (workflow tool removed). |
| fuzzforge-mcp/src/fuzzforge_mcp/tools/projects.py | Refactors tools to use MCP-local storage instead of runner. |
| fuzzforge-mcp/src/fuzzforge_mcp/tools/init.py | Mounts hub tools instead of module/workflow tools. |
| fuzzforge-mcp/src/fuzzforge_mcp/storage.py | Adds new local .fuzzforge/ storage implementation. |
| fuzzforge-mcp/src/fuzzforge_mcp/settings.py | Adds MCP server settings incl. hub config settings. |
| fuzzforge-mcp/src/fuzzforge_mcp/resources/workflows.py | Removed (workflow resource removed). |
| fuzzforge-mcp/src/fuzzforge_mcp/resources/project.py | Updates resources to use MCP-local settings/storage and expose hub settings. |
| fuzzforge-mcp/src/fuzzforge_mcp/resources/modules.py | Removed (module resources removed). |
| fuzzforge-mcp/src/fuzzforge_mcp/resources/executions.py | Refactors execution resources to use MCP-local storage. |
| fuzzforge-mcp/src/fuzzforge_mcp/resources/init.py | Stops mounting module/workflow resources. |
| fuzzforge-mcp/src/fuzzforge_mcp/dependencies.py | Replaces runner dependency with Settings + LocalStorage singleton. |
| fuzzforge-mcp/src/fuzzforge_mcp/application.py | Updates app instructions and settings source for hub-first approach. |
| fuzzforge-mcp/ruff.toml | Adds per-path ignores for new patterns. |
| fuzzforge-mcp/pyproject.toml | Drops runner dependency; updates package description. |
| fuzzforge-mcp/README.md | Renames paths but still documents old module-based env/config (needs update). |
| fuzzforge-common/src/fuzzforge_common/sandboxes/engines/podman/engine.py | Adds tail_file_from_container for incremental reads. |
| fuzzforge-common/src/fuzzforge_common/sandboxes/engines/podman/cli.py | Adds tail_file_from_container implementation. |
| fuzzforge-common/src/fuzzforge_common/sandboxes/engines/docker/engine.py | Adds stub tail_file_from_container to satisfy abstract interface. |
| fuzzforge-common/src/fuzzforge_common/sandboxes/engines/docker/cli.py | Adds tail_file_from_container implementation. |
| fuzzforge-common/src/fuzzforge_common/sandboxes/engines/base/engine.py | Extends engine interface with tail_file_from_container. |
| fuzzforge-common/src/fuzzforge_common/sandboxes/engines/base/configuration.py | Minor import cleanup. |
| fuzzforge-common/src/fuzzforge_common/hub/registry.py | Adds registry for hub server configs and discovered tools. |
| fuzzforge-common/src/fuzzforge_common/hub/models.py | Adds Pydantic models for hub servers/tools/config. |
| fuzzforge-common/src/fuzzforge_common/hub/init.py | Exports hub API surface. |
| fuzzforge-common/ruff.toml | Adds per-path ignores for legacy/common patterns. |
| fuzzforge-cli/src/fuzzforge_cli/tui/screens/hub_manager.py | Adds TUI screens for managing hubs (link/clone/remove). |
| fuzzforge-cli/src/fuzzforge_cli/tui/screens/build_log.py | Adds live build log viewer modal. |
| fuzzforge-cli/src/fuzzforge_cli/tui/screens/build_image.py | Adds build confirmation modal. |
| fuzzforge-cli/src/fuzzforge_cli/tui/screens/agent_setup.py | Adds agent setup/unlink modals. |
| fuzzforge-cli/src/fuzzforge_cli/tui/screens/init.py | Adds TUI screens package init. |
| fuzzforge-cli/src/fuzzforge_cli/tui/init.py | Adds TUI package init. |
| fuzzforge-cli/src/fuzzforge_cli/context.py | Refactors CLI context to use MCP LocalStorage instead of Runner. |
| fuzzforge-cli/src/fuzzforge_cli/commands/projects.py | Updates project commands to use storage backend. |
| fuzzforge-cli/src/fuzzforge_cli/commands/modules.py | Removed (module CLI removed). |
| fuzzforge-cli/src/fuzzforge_cli/commands/mcp.py | Updates MCP config generation/installation to hub-config based settings. |
| fuzzforge-cli/src/fuzzforge_cli/application.py | Removes module commands; adds ui command and uses storage-only context. |
| fuzzforge-cli/ruff.toml | Adds ignore rules for new TUI code and updated command file. |
| fuzzforge-cli/pyproject.toml | Switches dependency from runner to MCP; adds Textual. |
| ROADMAP.md | Renames roadmap branding. |
| README.md | Renames branding but still describes removed module architecture (needs update). |
| Makefile | Renames build target to hub images and points to a missing script (needs fix). |
| CONTRIBUTING.md | Updates branding and repository name references. |
| .github/workflows/mcp-server.yml | Adds MCP smoke test workflow (currently references non-existent module). |
| .github/workflows/ci.yml | Adds CI for lint/typecheck/tests across packages. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Create server instances from config | ||
| for server_config in self._config.servers: | ||
| if server_config.enabled: | ||
| self._servers[server_config.name] = HubServer( | ||
| config=server_config, | ||
| ) |
There was a problem hiding this comment.
_load_config() only creates HubServer instances for enabled configs, but servers is documented as “all registered servers” and remove_server() only removes names present in _servers. This means disabled servers can't be listed/removed via the registry API. Consider instantiating servers for all configs (and filtering in enabled_servers), or adjust servers/remove_server to operate on _config.servers rather than _servers.
| # Create server instances from config | |
| for server_config in self._config.servers: | |
| if server_config.enabled: | |
| self._servers[server_config.name] = HubServer( | |
| config=server_config, | |
| ) | |
| # Create server instances from config (all registered servers) | |
| for server_config in self._config.servers: | |
| self._servers[server_config.name] = HubServer( | |
| config=server_config, | |
| ) |
| self.query_one("#btn-clone", Button).disabled = True | ||
| self.query_one("#clone-status", Static).update("⏳ Cloning repository...") | ||
| self._do_clone(url) | ||
|
|
||
| @work(thread=True) | ||
| def _do_clone(self, url: str) -> None: | ||
| """Clone the repo in a background thread.""" | ||
| name_input = self.query_one("#name-input", Input).value.strip() |
There was a problem hiding this comment.
_do_clone() runs in a background thread (@work(thread=True)) but calls self.query_one(...).value to read widget state from that thread. Textual widget access is not thread-safe and can raise or lead to undefined behavior. Capture name_input (and any other UI state) in _start_clone() before spawning the worker, and pass it into _do_clone() as a plain string.
| self.query_one("#btn-clone", Button).disabled = True | |
| self.query_one("#clone-status", Static).update("⏳ Cloning repository...") | |
| self._do_clone(url) | |
| @work(thread=True) | |
| def _do_clone(self, url: str) -> None: | |
| """Clone the repo in a background thread.""" | |
| name_input = self.query_one("#name-input", Input).value.strip() | |
| # Capture name input on the UI thread before starting background work | |
| name_input = self.query_one("#name-input", Input).value.strip() | |
| self.query_one("#btn-clone", Button).disabled = True | |
| self.query_one("#clone-status", Static).update("⏳ Cloning repository...") | |
| self._do_clone(url, name_input) | |
| @work(thread=True) | |
| def _do_clone(self, url: str, name_input: str) -> None: | |
| """Clone the repo in a background thread.""" |
| @@ -43,7 +43,7 @@ At the heart of FuzzForge are **modules** - containerized security tools that AI | |||
| - **🔗 Composable**: Chain modules together into automated workflows | |||
| - **📦 Extensible**: Build custom modules with the Python SDK | |||
|
|
|||
| The OSS runtime handles module discovery, execution, and result collection. Security modules (developed separately) provide the actual security tooling - from static analyzers to fuzzers to crash triagers. | |||
| FuzzForge AI handles module discovery, execution, and result collection. Security modules (developed separately) provide the actual security tooling - from static analyzers to fuzzers to crash triagers. | |||
There was a problem hiding this comment.
This section still describes FuzzForge in terms of “modules” and “module discovery/execution”, but this PR removes the module/workflow tools and pivots the MCP server to hub tool discovery/execution. The README should be updated to reflect the new hub-based architecture (and avoid directing users toward removed capabilities).
| @pytest.fixture | ||
| def random_module_identifier() -> Callable[[], FuzzForgeModuleIdentifier]: | ||
| """Generate random module identifiers.""" | ||
|
|
||
| def inner() -> FuzzForgeModuleIdentifier: | ||
| return uuid7() | ||
|
|
||
| return inner | ||
|
|
||
|
|
||
| @pytest.fixture | ||
| def random_module_execution_identifier() -> Callable[[], FuzzForgeExecutionIdentifier]: | ||
| """Generate random workflow execution identifiers. | ||
| def random_execution_identifier() -> Callable[[], FuzzForgeExecutionIdentifier]: | ||
| """Generate random execution identifiers. | ||
|
|
||
| Returns a callable that generates fresh UUID7 identifiers for each call. |
There was a problem hiding this comment.
The shared conftest still imports/exports random_module_execution_identifier, but this fixture was removed/renamed to random_execution_identifier here, which will cause ImportError in test runs. To keep backward compatibility, either keep an alias fixture named random_module_execution_identifier (and optionally deprecate it), or update all imports/exports to the new fixture name.
| try: | ||
| destination.mkdir(parents=True, exist_ok=True) | ||
| with Archive(results_path, "r:gz") as tar: | ||
| tar.extractall(path=destination) # noqa: S202 | ||
| logger.info("Extracted results: %s -> %s", results_path, destination) | ||
| return destination |
There was a problem hiding this comment.
tar.extractall() allows path traversal (e.g., members with ../) and can write outside destination if the archive is untrusted. Even if archives are usually produced internally, results may come from external hub tools, so this should use a safe extraction routine that validates member paths (and optionally rejects symlinks/hardlinks) before extracting.
| # Search in all run directories | ||
| runs_dir = storage_path / "runs" | ||
| if runs_dir.exists(): | ||
| for run_dir in runs_dir.iterdir(): | ||
| if run_dir.is_dir() and execution_id in run_dir.name: | ||
| candidate = run_dir / RESULTS_ARCHIVE_FILENAME | ||
| if candidate.exists(): | ||
| return candidate |
There was a problem hiding this comment.
The fallback search matches execution_id in run_dir.name, which can return the wrong run when one execution id is a substring of another (or of other directory names). Prefer an exact directory match (e.g., run_dir.name == execution_id) or store a mapping/index so lookups are deterministic.
| "command": "/path/to/fuzzforge_ai/.venv/bin/python", | ||
| "args": ["-m", "fuzzforge_mcp"], | ||
| "cwd": "/path/to/fuzzforge-oss", | ||
| "cwd": "/path/to/fuzzforge_ai", | ||
| "env": { | ||
| "FUZZFORGE_MODULES_PATH": "/path/to/fuzzforge-oss/fuzzforge-modules", | ||
| "FUZZFORGE_MODULES_PATH": "/path/to/fuzzforge_ai/fuzzforge-modules", | ||
| "FUZZFORGE_ENGINE__TYPE": "docker" | ||
| } |
There was a problem hiding this comment.
The manual MCP config examples and env var table still require FUZZFORGE_MODULES_PATH, but the server no longer uses modules and the CLI now emits FUZZFORGE_HUB__CONFIG_PATH/hub settings instead. Update these snippets to remove FUZZFORGE_MODULES_PATH and document the hub config env vars so users can actually start/discover hub tools.
| def _find_fuzzforge_root() -> Path: | ||
| """Find the FuzzForge installation root. | ||
|
|
||
| :returns: Path to fuzzforge-oss directory. | ||
|
|
||
| """ | ||
| # Try to find from current file location | ||
| current = Path(__file__).resolve() | ||
| # Check environment variable override first | ||
| env_root = os.environ.get("FUZZFORGE_ROOT") | ||
| if env_root: | ||
| return Path(env_root).resolve() | ||
|
|
||
| # Walk up from cwd to find a fuzzforge root (hub-config.json is the marker) | ||
| for parent in [Path.cwd(), *Path.cwd().parents]: | ||
| if (parent / "hub-config.json").is_file(): | ||
| return parent | ||
|
|
||
| # Walk up to find fuzzforge-oss root | ||
| # Fall back to __file__-based search (dev install inside fuzzforge-oss) | ||
| current = Path(__file__).resolve() | ||
| for parent in current.parents: | ||
| if (parent / "fuzzforge-mcp").is_dir() and (parent / "fuzzforge-runner").is_dir(): | ||
| if (parent / "fuzzforge-mcp").is_dir(): | ||
| return parent | ||
|
|
||
| # Fall back to cwd | ||
| return Path.cwd() | ||
|
|
||
|
|
||
| def _generate_mcp_config( | ||
| fuzzforge_root: Path, | ||
| modules_path: Path, | ||
| engine_type: str, | ||
| engine_socket: str, | ||
| ) -> dict: | ||
| ) -> dict[str, Any]: | ||
| """Generate MCP server configuration. | ||
|
|
||
| :param fuzzforge_root: Path to fuzzforge-oss installation. | ||
| :param modules_path: Path to the modules directory. | ||
| :param engine_type: Container engine type (podman or docker). |
There was a problem hiding this comment.
Docstrings still refer to “fuzzforge-oss” (e.g., return value and installation root) even though the project has been renamed and root discovery now keys off hub-config.json. Update these docstrings to match the current FuzzForge AI naming and the new root-discovery behavior so the help text stays accurate.
| @echo "✓ All modules built successfully!" | ||
| # Build all mcp-security-hub images for the firmware analysis pipeline | ||
| build-hub-images: | ||
| @bash scripts/build-hub-images.sh |
There was a problem hiding this comment.
build-hub-images invokes scripts/build-hub-images.sh, but there is no scripts/ directory/script in the repository, so this target will fail. Either add the script to the PR or update the target to call an existing script/path (or inline the build logic).
| @bash scripts/build-hub-images.sh | |
| @echo "Error: build-hub-images is not implemented because scripts/build-hub-images.sh is missing." 1>&2; exit 1 |
| - name: Start MCP server in background | ||
| run: | | ||
| cd fuzzforge-mcp | ||
| nohup uv run python -m fuzzforge_mcp.server > server.log 2>&1 & | ||
| echo $! > server.pid | ||
| sleep 3 | ||
|
|
||
| - name: Run MCP tool tests | ||
| run: | | ||
| cd fuzzforge-mcp | ||
| uv run --extra tests pytest tests/test_resources.py -v | ||
|
|
||
| - name: Stop MCP server | ||
| if: always() | ||
| run: | | ||
| if [ -f fuzzforge-mcp/server.pid ]; then | ||
| kill $(cat fuzzforge-mcp/server.pid) || true | ||
| fi | ||
|
|
||
| - name: Show server logs | ||
| if: failure() | ||
| run: cat fuzzforge-mcp/server.log || true |
There was a problem hiding this comment.
This workflow starts python -m fuzzforge_mcp.server, but the package entrypoint is python -m fuzzforge_mcp (there is no fuzzforge_mcp.server module). Also, the MCP tests use the in-process mcp transport (see fuzzforge-mcp/tests/conftest.py), so starting a background stdio server here is unnecessary and may hang. Consider removing the start/stop steps entirely, or updating the command to python -m fuzzforge_mcp and actually exercising it via a real stdio client.
| - name: Start MCP server in background | |
| run: | | |
| cd fuzzforge-mcp | |
| nohup uv run python -m fuzzforge_mcp.server > server.log 2>&1 & | |
| echo $! > server.pid | |
| sleep 3 | |
| - name: Run MCP tool tests | |
| run: | | |
| cd fuzzforge-mcp | |
| uv run --extra tests pytest tests/test_resources.py -v | |
| - name: Stop MCP server | |
| if: always() | |
| run: | | |
| if [ -f fuzzforge-mcp/server.pid ]; then | |
| kill $(cat fuzzforge-mcp/server.pid) || true | |
| fi | |
| - name: Show server logs | |
| if: failure() | |
| run: cat fuzzforge-mcp/server.log || true | |
| - name: Run MCP tool tests | |
| run: | | |
| cd fuzzforge-mcp | |
| uv run --extra tests pytest tests/test_resources.py -v |
No description provided.