Skip to content
This repository was archived by the owner on Apr 22, 2026. It is now read-only.

Commit 544569d

Browse files
committed
fix: use ~/.fuzzforge for user-global data, keep workspace .fuzzforge for project storage
1 parent 6f967ff commit 544569d

2 files changed

Lines changed: 31 additions & 11 deletions

File tree

fuzzforge-cli/src/fuzzforge_cli/commands/mcp.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,10 @@ def _generate_mcp_config(
174174
command = "uv"
175175
args = ["--directory", str(fuzzforge_root), "run", "fuzzforge-mcp"]
176176

177-
# Self-contained storage paths for FuzzForge containers
178-
# This isolates FuzzForge from system Podman and avoids snap issues
179-
fuzzforge_home = Path.cwd() / ".fuzzforge"
177+
# User-global storage paths for FuzzForge containers.
178+
# Kept under ~/.fuzzforge so images are built once and shared across
179+
# all workspaces — regardless of where `fuzzforge mcp install` is run.
180+
fuzzforge_home = Path.home() / ".fuzzforge"
180181
graphroot = fuzzforge_home / "containers" / "storage"
181182
runroot = fuzzforge_home / "containers" / "run"
182183

fuzzforge-cli/src/fuzzforge_cli/tui/helpers.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,25 @@
3030
FUZZFORGE_DEFAULT_HUB_NAME = "mcp-security-hub"
3131

3232

33+
def get_fuzzforge_user_dir() -> Path:
34+
"""Return the user-global ``~/.fuzzforge/`` directory.
35+
36+
Stores data that is shared across all workspaces: cloned hub
37+
repositories, the hub registry, container storage (graphroot/runroot),
38+
and the hub workspace volume.
39+
40+
:return: ``Path.home() / ".fuzzforge"``
41+
42+
"""
43+
return Path.home() / ".fuzzforge"
44+
45+
3346
def get_fuzzforge_dir() -> Path:
3447
"""Return the project-local ``.fuzzforge/`` directory.
3548
36-
Uses the current working directory so that each project gets its
37-
own isolated FuzzForge configuration, hubs, and storage — similar
38-
to how ``.git/`` or ``.venv/`` work.
49+
Stores data that is specific to the current workspace: fuzzing
50+
results and project artifacts. Similar to how ``.git/`` scopes
51+
version-control data to a single project.
3952
4053
:return: ``Path.cwd() / ".fuzzforge"``
4154
@@ -238,21 +251,27 @@ def uninstall_agent_config(agent: AIAgent) -> str:
238251

239252

240253
def get_hubs_registry_path() -> Path:
241-
"""Return path to the hubs registry file (``.fuzzforge/hubs.json``).
254+
"""Return path to the hubs registry file (``~/.fuzzforge/hubs.json``).
255+
256+
Stored in the user-global directory so the registry is shared across
257+
all workspaces.
242258
243259
:return: Path to the registry JSON file.
244260
245261
"""
246-
return get_fuzzforge_dir() / "hubs.json"
262+
return get_fuzzforge_user_dir() / "hubs.json"
247263

248264

249265
def get_default_hubs_dir() -> Path:
250-
"""Return default directory for cloned hubs (``.fuzzforge/hubs/``).
266+
"""Return default directory for cloned hubs (``~/.fuzzforge/hubs/``).
267+
268+
Stored in the user-global directory so hubs are cloned once and
269+
reused in every workspace.
251270
252271
:return: Path to the default hubs directory.
253272
254273
"""
255-
return get_fuzzforge_dir() / "hubs"
274+
return get_fuzzforge_user_dir() / "hubs"
256275

257276

258277
def load_hubs_registry() -> dict[str, Any]:
@@ -322,7 +341,7 @@ def scan_hub_for_servers(hub_path: Path) -> list[dict[str, Any]]:
322341
"image": f"{tool_name}:latest",
323342
"category": category,
324343
"capabilities": capabilities,
325-
"volumes": [f"{get_fuzzforge_dir()}/hub/workspace:/data"],
344+
"volumes": [f"{get_fuzzforge_user_dir()}/hub/workspace:/data"],
326345
"enabled": True,
327346
}
328347
)

0 commit comments

Comments
 (0)