chore: add frontend dependencies and update test fixtures

- Add react-router-dom, @tanstack/react-query, zustand, @headlessui/react
- Update pnpm workspace configuration
- Update test fixtures to reference OpenCode instead of RunFusion
- Add frontend environment variable examples
- Update .gitignore for .opencode and .sisyphus directories
This commit is contained in:
2026-05-14 17:30:41 +02:00
parent 62640daf36
commit 85ae390263
8 changed files with 423 additions and 29 deletions
@@ -6,7 +6,11 @@ from httpx import AsyncClient
async def test_tool_definition_crud(auth_client: AsyncClient) -> None:
resp = await auth_client.post(
"/api/v1/tool-definitions",
json={"key": "runfusion", "name": "RunFusion", "image": "runfusion:latest"},
json={
"key": "opencode",
"name": "OpenCode",
"image": "ghcr.io/opencode-ai/opencode:latest",
},
)
assert resp.status_code == 201
td_id = resp.json()["id"]
@@ -18,9 +22,9 @@ async def test_tool_definition_crud(auth_client: AsyncClient) -> None:
resp = await auth_client.get(f"/api/v1/tool-definitions/{td_id}")
assert resp.status_code == 200
resp = await auth_client.put(f"/api/v1/tool-definitions/{td_id}", json={"name": "RunFusionV2"})
resp = await auth_client.put(f"/api/v1/tool-definitions/{td_id}", json={"name": "OpenCodeV2"})
assert resp.status_code == 200
assert resp.json()["name"] == "RunFusionV2"
assert resp.json()["name"] == "OpenCodeV2"
resp = await auth_client.delete(f"/api/v1/tool-definitions/{td_id}")
assert resp.status_code == 204
+14 -16
View File
@@ -6,7 +6,6 @@ import pytest
from pydantic import ValidationError
from app.tools.models import (
ExecutableConfig,
HealthCheckConfig,
MountConfig,
PortConfig,
@@ -36,33 +35,32 @@ def _minimal_manifest(**overrides: object) -> ToolManifest:
# Valid construction
# ---------------------------------------------------------------------------
def test_valid_runfusion_shape() -> None:
def test_valid_opencode_shape() -> None:
manifest = ToolManifest(
id="runfusion",
name="RunFusion",
description="Executable Node.js environment.",
image="node:22-slim",
id="opencode",
name="OpenCode",
description="AI-powered terminal-based development environment.",
image="ghcr.io/opencode-ai/opencode:latest",
runtime_working_dir="/workspace",
ports=[PortConfig(container_port=8080, name="http", primary=True)],
ports=[PortConfig(container_port=3000, name="http", primary=True)],
workspace_mounts=[
MountConfig(source_pattern="{project_repo}", target="/workspace")
],
config_mounts=[
MountConfig(
source_pattern="{user_config}/runfusion", target="/home/node/.config"
source_pattern="{user_config}/opencode", target="/root/.config/opencode"
)
],
env={"NODE_ENV": "development"},
env={"TERM": "xterm-256color", "FORCE_COLOR": "1"},
health_check=HealthCheckConfig(
type="http", path="/", port=8080, start_period_seconds=10
type="http", path="/", port=3000, start_period_seconds=15
),
resource_limits=ResourceLimits(cpus=2.0, memory_mb=2048),
executable=ExecutableConfig(node_version="22", package_manager="npm"),
resource_limits=ResourceLimits(cpus=2.0, memory_mb=4096),
traefik=TraefikConfig(
enabled=True, subdomain_prefix="runfusion", port=8080
enabled=True, subdomain_prefix="opencode", port=3000
),
)
assert manifest.id == "runfusion"
assert manifest.id == "opencode"
assert manifest.ports[0].primary is True
assert manifest.traefik is not None
assert manifest.traefik.enabled is True
@@ -102,13 +100,13 @@ def test_valid_code_server_shape() -> None:
def test_invalid_id_uppercase() -> None:
with pytest.raises(ValidationError) as exc_info:
_minimal_manifest(id="RunFusion")
_minimal_manifest(id="OpenCode")
assert "id" in str(exc_info.value)
def test_invalid_id_spaces() -> None:
with pytest.raises(ValidationError) as exc_info:
_minimal_manifest(id="run fusion")
_minimal_manifest(id="open code")
assert "id" in str(exc_info.value)
+6 -6
View File
@@ -27,7 +27,7 @@ def test_list_tools_includes_builtins() -> None:
assert response.status_code == 200
data = response.json()
ids = {item["id"] for item in data}
assert "runfusion" in ids
assert "opencode" in ids
assert "code-server" in ids
@@ -36,12 +36,12 @@ def test_list_tools_includes_builtins() -> None:
# ---------------------------------------------------------------------------
def test_get_tool_runfusion() -> None:
response = client.get("/api/v1/tools/runfusion")
def test_get_tool_opencode() -> None:
response = client.get("/api/v1/tools/opencode")
assert response.status_code == 200
data = response.json()
assert data["id"] == "runfusion"
assert data["name"] == "RunFusion"
assert data["id"] == "opencode"
assert data["name"] == "OpenCode"
def test_get_tool_not_found() -> None:
@@ -71,7 +71,7 @@ def test_create_tool_success() -> None:
def test_create_tool_duplicate() -> None:
payload = {
"id": "runfusion",
"id": "opencode",
"name": "Duplicate",
"image": "dup:latest",
"ports": [{"container_port": 3000, "primary": True}],
+5
View File
@@ -1,3 +1,8 @@
# Frontend runtime configuration
VITE_API_URL=http://localhost:8000
VITE_APP_NAME=Headquarter
# OIDC Authentication (Authentik)
VITE_OIDC_ISSUER=https://authentik.example.com/application/o/headquarter
VITE_OIDC_CLIENT_ID=headquarter-web
VITE_OIDC_REDIRECT_URI=http://localhost:5173/callback
+16 -4
View File
@@ -4,7 +4,9 @@
"private": true,
"type": "module",
"pnpm": {
"onlyBuiltDependencies": ["esbuild"]
"onlyBuiltDependencies": [
"esbuild"
]
},
"scripts": {
"dev": "vite",
@@ -14,22 +16,32 @@
"typecheck": "tsc -b --noEmit"
},
"dependencies": {
"@headlessui/react": "^2.2.10",
"@heroicons/react": "^2.2.0",
"@tanstack/react-query": "^5.100.10",
"clsx": "^2.1.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
"react-dom": "^19.0.0",
"react-router-dom": "^7.15.0",
"tailwind-merge": "^3.6.0",
"zustand": "^5.0.13"
},
"devDependencies": {
"@eslint/js": "^9.24.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.4.0",
"@eslint/js": "^9.24.0",
"autoprefixer": "^10.5.0",
"eslint": "^9.24.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^16.0.0",
"jsdom": "^26.0.0",
"@types/node": "^22.0.0",
"postcss": "^8.5.14",
"tailwindcss": "^4.3.0",
"typescript": "~5.7.0",
"typescript-eslint": "^8.29.0",
"vite": "^6.3.0",