mirror of
https://github.com/FuzzingLabs/fuzzforge_ai.git
synced 2026-03-18 11:03:22 +00:00
ci: add GitHub Actions workflows with lint, typecheck and tests
This commit is contained in:
@@ -9,12 +9,14 @@ hub management capabilities.
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from rich.text import Text
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.binding import Binding
|
||||
from textual.containers import Horizontal, Vertical, VerticalScroll
|
||||
from textual.widgets import Button, DataTable, Footer, Header, Label
|
||||
from textual.widgets import Button, DataTable, Footer, Header
|
||||
|
||||
from fuzzforge_cli.tui.helpers import (
|
||||
check_agent_status,
|
||||
@@ -24,11 +26,14 @@ from fuzzforge_cli.tui.helpers import (
|
||||
load_hub_config,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from fuzzforge_cli.commands.mcp import AIAgent
|
||||
|
||||
# Agent config entries stored alongside their linked status for row mapping
|
||||
_AgentRow = tuple[str, "AIAgent", "Path", str, bool] # noqa: F821
|
||||
_AgentRow = tuple[str, "AIAgent", Path, str, bool]
|
||||
|
||||
|
||||
class FuzzForgeApp(App):
|
||||
class FuzzForgeApp(App[None]):
|
||||
"""FuzzForge AI terminal user interface."""
|
||||
|
||||
TITLE = "FuzzForge AI"
|
||||
@@ -236,7 +241,7 @@ class FuzzForgeApp(App):
|
||||
return
|
||||
|
||||
# Group servers by source hub
|
||||
groups: dict[str, list[dict]] = defaultdict(list)
|
||||
groups: dict[str, list[dict[str, Any]]] = defaultdict(list)
|
||||
for server in servers:
|
||||
source = server.get("source_hub", "manual")
|
||||
groups[source].append(server)
|
||||
@@ -245,7 +250,7 @@ class FuzzForgeApp(App):
|
||||
ready_count = 0
|
||||
total = len(hub_servers)
|
||||
|
||||
statuses: list[tuple[dict, bool, str]] = []
|
||||
statuses: list[tuple[dict[str, Any], bool, str]] = []
|
||||
for server in hub_servers:
|
||||
enabled = server.get("enabled", True)
|
||||
if not enabled:
|
||||
|
||||
@@ -108,7 +108,7 @@ def check_hub_image(image: str) -> tuple[bool, str]:
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["docker", "image", "inspect", image],
|
||||
capture_output=True,
|
||||
check=False, capture_output=True,
|
||||
text=True,
|
||||
timeout=5,
|
||||
)
|
||||
@@ -132,7 +132,8 @@ def load_hub_config(fuzzforge_root: Path) -> dict[str, Any]:
|
||||
if not config_path.exists():
|
||||
return {}
|
||||
try:
|
||||
return json.loads(config_path.read_text())
|
||||
data: dict[str, Any] = json.loads(config_path.read_text())
|
||||
return data
|
||||
except json.JSONDecodeError:
|
||||
return {}
|
||||
|
||||
@@ -264,7 +265,8 @@ def load_hubs_registry() -> dict[str, Any]:
|
||||
if not path.exists():
|
||||
return {"hubs": []}
|
||||
try:
|
||||
return json.loads(path.read_text())
|
||||
data: dict[str, Any] = json.loads(path.read_text())
|
||||
return data
|
||||
except (json.JSONDecodeError, OSError):
|
||||
return {"hubs": []}
|
||||
|
||||
@@ -422,8 +424,7 @@ def clone_hub(
|
||||
"""
|
||||
if name is None:
|
||||
name = git_url.rstrip("/").split("/")[-1]
|
||||
if name.endswith(".git"):
|
||||
name = name[:-4]
|
||||
name = name.removesuffix(".git")
|
||||
|
||||
if dest is None:
|
||||
dest = get_default_hubs_dir() / name
|
||||
@@ -433,7 +434,7 @@ def clone_hub(
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "-C", str(dest), "pull"],
|
||||
capture_output=True,
|
||||
check=False, capture_output=True,
|
||||
text=True,
|
||||
timeout=120,
|
||||
)
|
||||
@@ -451,7 +452,7 @@ def clone_hub(
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "clone", git_url, str(dest)],
|
||||
capture_output=True,
|
||||
check=False, capture_output=True,
|
||||
text=True,
|
||||
timeout=300,
|
||||
)
|
||||
|
||||
@@ -81,6 +81,7 @@ class HubManagerScreen(ModalScreen[str | None]):
|
||||
is_default = hub.get("is_default", False)
|
||||
|
||||
hub_path = Path(path)
|
||||
count: str | Text
|
||||
if hub_path.is_dir():
|
||||
servers = scan_hub_for_servers(hub_path)
|
||||
count = str(len(servers))
|
||||
@@ -88,10 +89,11 @@ class HubManagerScreen(ModalScreen[str | None]):
|
||||
count = Text("dir missing", style="yellow")
|
||||
|
||||
source = git_url or "local"
|
||||
name_cell: str | Text
|
||||
if is_default:
|
||||
name_cell = Text(f"★ {name}", style="bold")
|
||||
else:
|
||||
name_cell = Text(name)
|
||||
name_cell = name
|
||||
|
||||
table.add_row(name_cell, path, count, source)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user