Private
Public Access
docs(plans): implementation plans for 4 tracks - command palette, test consolidation, clean install, docker web
This commit is contained in:
@@ -0,0 +1,594 @@
|
||||
# Docker & Web Frontend Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Containerize Manual Slop for Unraid deployment. Add a web frontend via the imgui-bundle web backend (per the [explorer docs](https://imgui-bundle.pages.dev/explorer/)). Preserve the existing Hook API on :8999 for agent access.
|
||||
|
||||
**Architecture:** Python 3.11-slim base image with `uv` for dependency management. The container runs `sloppy.py` in web mode (via a new `--web-host` / `--web-port` arg), which uses the imgui-bundle Hello ImGui web backend to render ImGui to a WebGL canvas in the browser. Two exposed ports: 8080 (web client) and 8999 (hook API). Volumes for project data and app state.
|
||||
|
||||
**Tech Stack:** Docker, docker-compose, Python 3.11, imgui-bundle (web backend), FastAPI/Uvicorn (existing, for hooks)
|
||||
|
||||
**Spec:** `docs/superpowers/specs/2026-06-02-docker-web-frontend-design.md`
|
||||
|
||||
---
|
||||
|
||||
## Execution Constraints
|
||||
|
||||
- **No subagents.**
|
||||
- **Pre-edit checkpoint:** `git add .` before any file edit.
|
||||
- **Per-file atomic commits.**
|
||||
- **Commit message format:** `<type>(<scope>): <imperative description>`.
|
||||
- **Git note format:** 3-8 line rationale per commit.
|
||||
- **Style baseline:** 1-space indent, no comments, type hints.
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
| File | Action | Responsibility |
|
||||
|---|---|---|
|
||||
| `Dockerfile` | Create | Container build for Manual Slop |
|
||||
| `docker-compose.yml` | Create | Multi-container orchestration for Unraid |
|
||||
| `scripts/docker_build.sh` | Create | Build helper |
|
||||
| `scripts/docker_run.sh` | Create | Run helper with env var wiring |
|
||||
| `sloppy.py` | Modify | Add `--web-host` and `--web-port` args |
|
||||
| `docs/guide_docker_deployment.md` | Create | Unraid setup guide |
|
||||
| `tests/test_docker_build.py` | Create | Opt-in Docker build test |
|
||||
| `pyproject.toml` | Modify | Add `docker` marker |
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Add web args to `sloppy.py`
|
||||
|
||||
**Files:**
|
||||
- Modify: `sloppy.py`
|
||||
|
||||
- [ ] **Step 1.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 1.2: Read current `sloppy.py`**
|
||||
|
||||
Use `manual-slop_read_file` to see current contents.
|
||||
|
||||
- [ ] **Step 1.3: Add the new args**
|
||||
|
||||
Find the existing argument parser setup and add the web args. If there isn't an argparse, look for how args are handled. Add:
|
||||
|
||||
```python
|
||||
# In sloppy.py, after existing argument definitions
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Manual Slop entry point")
|
||||
# ... existing args ...
|
||||
parser.add_argument("--web-host", default=None, help="Enable web mode and bind to this host (e.g., 0.0.0.0)")
|
||||
parser.add_argument("--web-port", type=int, default=8080, help="Web mode port (default: 8080)")
|
||||
parser.add_argument("--enable-test-hooks", action="store_true", help="Enable the HookServer on :8999 for external automation")
|
||||
args = parser.parse_args()
|
||||
```
|
||||
|
||||
If the existing entry point uses a different mechanism, integrate the args there.
|
||||
|
||||
- [ ] **Step 1.4: Add the web mode branch**
|
||||
|
||||
After argument parsing, before the existing main launch, add:
|
||||
|
||||
```python
|
||||
if args.web_host is not None:
|
||||
from imgui_bundle import hello_imgui
|
||||
from src.api_hooks import HookServer
|
||||
|
||||
if args.enable_test_hooks:
|
||||
hook_server = HookServer()
|
||||
hook_server.start()
|
||||
|
||||
runner_params = hello_imgui.RunnerParams()
|
||||
runner_params.app_window_params.window_title = "Manual Slop (Web)"
|
||||
runner_params.app_window_params.borderless = True
|
||||
runner_params.imgui_window_params.default_imgui_window_type = hello_imgui.DefaultImGuiWindowType.provide_full_screen_docker_space
|
||||
runner_params.app_window_params.restore_previous_window_size = True
|
||||
|
||||
from src.gui_2 import App
|
||||
app = App()
|
||||
hello_imgui.run(runner_params, lambda: app.render_frame())
|
||||
```
|
||||
|
||||
- [ ] **Step 1.5: Commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add sloppy.py
|
||||
git -C C:\projects\manual_slop commit -m "feat(sloppy): add --web-host and --web-port args for web mode"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Adds --web-host (enables web mode) and --web-port (default 8080) args. When --web-host is set, launches via Hello ImGui web backend with full-screen docking. Preserves --enable-test-hooks for agent access via :8999." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Create the Dockerfile
|
||||
|
||||
**Files:**
|
||||
- Create: `Dockerfile`
|
||||
|
||||
- [ ] **Step 2.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 2.2: Create the Dockerfile**
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git curl ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pip install uv
|
||||
|
||||
WORKDIR /app
|
||||
COPY pyproject.toml uv.lock ./
|
||||
RUN uv sync --frozen
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN mkdir -p /projects /config
|
||||
VOLUME ["/projects", "/config"]
|
||||
|
||||
EXPOSE 8080 8999
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
||||
CMD curl -f http://127.0.0.1:8999/status || exit 1
|
||||
|
||||
ENTRYPOINT ["uv", "run", "sloppy.py", "--enable-test-hooks", "--web-host=0.0.0.0", "--web-port=8080"]
|
||||
```
|
||||
|
||||
- [ ] **Step 2.3: Add a `.dockerignore`**
|
||||
|
||||
```dockerignore
|
||||
# .dockerignore
|
||||
.git
|
||||
__pycache__
|
||||
*.pyc
|
||||
.pytest_cache
|
||||
.ruff_cache
|
||||
.venv
|
||||
.env
|
||||
tests/artifacts/
|
||||
tests/logs/
|
||||
logs/
|
||||
md_gen/
|
||||
*.log
|
||||
```
|
||||
|
||||
- [ ] **Step 2.4: Commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add Dockerfile .dockerignore
|
||||
git -C C:\projects\manual_slop commit -m "feat(docker): add Dockerfile and .dockerignore for containerized deployment"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Python 3.11-slim base, uv for dep management, copies pyproject + uv.lock first for layer caching. Exposes 8080 (web) and 8999 (hooks). Volumes for /projects and /config. Healthcheck on hook status. .dockerignore excludes test artifacts and git." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Create the docker-compose.yml
|
||||
|
||||
**Files:**
|
||||
- Create: `docker-compose.yml`
|
||||
|
||||
- [ ] **Step 3.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 3.2: Create the compose file**
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
manual_slop:
|
||||
build: .
|
||||
image: manual_slop:latest
|
||||
container_name: manual_slop
|
||||
ports:
|
||||
- "8999:8999"
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /mnt/user/projects:/projects:rw
|
||||
- /mnt/user/appdata/manual_slop:/config:rw
|
||||
environment:
|
||||
- GEMINI_API_KEY=${GEMINI_API_KEY:-}
|
||||
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
|
||||
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY:-}
|
||||
- MINIMAX_API_KEY=${MINIMAX_API_KEY:-}
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://127.0.0.1:8999/status"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
```
|
||||
|
||||
- [ ] **Step 3.3: Commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add docker-compose.yml
|
||||
git -C C:\projects\manual_slop commit -m "feat(docker): add docker-compose.yml for Unraid deployment"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Two ports (8999 hooks, 8080 web), two volumes (projects, appdata config), env vars for 4 providers, healthcheck on hook status. Unraid-friendly paths." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: Create the build/run scripts
|
||||
|
||||
**Files:**
|
||||
- Create: `scripts/docker_build.sh`
|
||||
- Create: `scripts/docker_run.sh`
|
||||
|
||||
- [ ] **Step 4.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 4.2: Create `scripts/docker_build.sh`**
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# scripts/docker_build.sh
|
||||
# Build the Manual Slop Docker image.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
docker build -t manual_slop:latest .
|
||||
```
|
||||
|
||||
- [ ] **Step 4.3: Create `scripts/docker_run.sh`**
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# scripts/docker_run.sh
|
||||
# Run the Manual Slop container.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
- [ ] **Step 4.4: Make scripts executable and commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add scripts/docker_build.sh scripts/docker_run.sh
|
||||
git -C C:\projects\manual_slop commit -m "feat(docker): add build and run shell scripts"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Two thin shell scripts: build (docker build -t manual_slop:latest .) and run (docker compose up -d). Will be made executable in chmod step during deployment." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 5: Add the `docker` marker to `pyproject.toml`
|
||||
|
||||
**Files:**
|
||||
- Modify: `pyproject.toml`
|
||||
|
||||
- [ ] **Step 5.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 5.2: Add the marker**
|
||||
|
||||
Find the markers list (from Task 1 of the clean-install plan) and add:
|
||||
|
||||
```toml
|
||||
markers = [
|
||||
"integration: integration tests requiring live GUI",
|
||||
"strict: tests that require strict mode",
|
||||
"clean_install: clean install verification (opt-in via RUN_CLEAN_INSTALL_TEST=1)",
|
||||
"docker: docker build and run test (opt-in via RUN_DOCKER_TEST=1)",
|
||||
]
|
||||
```
|
||||
|
||||
- [ ] **Step 5.3: Commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add pyproject.toml
|
||||
git -C C:\projects\manual_slop commit -m "test(pytest): add docker marker"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Registers the docker marker. Tests using Docker can be filtered with -m docker or -m 'not docker'." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Write the Docker build test
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/test_docker_build.py`
|
||||
|
||||
- [ ] **Step 6.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 6.2: Create the test file**
|
||||
|
||||
```python
|
||||
# tests/test_docker_build.py
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
|
||||
|
||||
IMAGE_NAME = "manual_slop:test"
|
||||
CONTAINER_NAME = "manual_slop_test_container"
|
||||
WEB_PORT = 18080
|
||||
HOOK_PORT = 18999
|
||||
|
||||
|
||||
@pytest.mark.docker
|
||||
def test_docker_image_builds(tmp_path):
|
||||
"""Build the Docker image. Slow; opt-in."""
|
||||
if os.environ.get("RUN_DOCKER_TEST") != "1":
|
||||
pytest.skip("Set RUN_DOCKER_TEST=1 to enable")
|
||||
if not _docker_available():
|
||||
pytest.skip("Docker not available in this environment")
|
||||
|
||||
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
result = subprocess.run(
|
||||
["docker", "build", "-t", IMAGE_NAME, "."],
|
||||
cwd=repo_root,
|
||||
capture_output=True, text=True, timeout=600,
|
||||
)
|
||||
assert result.returncode == 0, f"Docker build failed: {result.stderr}"
|
||||
|
||||
|
||||
@pytest.mark.docker
|
||||
def test_docker_container_starts_and_responds():
|
||||
"""Run the container, verify web and hook endpoints respond."""
|
||||
if os.environ.get("RUN_DOCKER_TEST") != "1":
|
||||
pytest.skip("Set RUN_DOCKER_TEST=1 to enable")
|
||||
if not _docker_available():
|
||||
pytest.skip("Docker not available in this environment")
|
||||
|
||||
_cleanup_container()
|
||||
|
||||
repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
result = subprocess.run(
|
||||
[
|
||||
"docker", "run", "-d",
|
||||
"--name", CONTAINER_NAME,
|
||||
"-p", f"{WEB_PORT}:8080",
|
||||
"-p", f"{HOOK_PORT}:8999",
|
||||
IMAGE_NAME,
|
||||
],
|
||||
cwd=repo_root,
|
||||
capture_output=True, text=True, timeout=30,
|
||||
)
|
||||
assert result.returncode == 0, f"Docker run failed: {result.stderr}"
|
||||
|
||||
try:
|
||||
start = time.time()
|
||||
ready = False
|
||||
while time.time() - start < 90:
|
||||
try:
|
||||
r = requests.get(f"http://127.0.0.1:{HOOK_PORT}/status", timeout=1)
|
||||
if r.status_code == 200:
|
||||
ready = True
|
||||
break
|
||||
except (requests.ConnectionError, requests.Timeout):
|
||||
pass
|
||||
time.sleep(1)
|
||||
assert ready, "Container hook API did not respond within 90s"
|
||||
|
||||
r = requests.get(f"http://127.0.0.1:{WEB_PORT}/", timeout=5)
|
||||
assert r.status_code == 200
|
||||
body = r.content.lower()
|
||||
assert b"<html" in body or b"<!doctype" in body, "Web endpoint did not return HTML"
|
||||
|
||||
finally:
|
||||
_cleanup_container()
|
||||
|
||||
|
||||
def _docker_available() -> bool:
|
||||
return shutil.which("docker") is not None
|
||||
|
||||
|
||||
def _cleanup_container() -> None:
|
||||
subprocess.run(
|
||||
["docker", "rm", "-f", CONTAINER_NAME],
|
||||
capture_output=True,
|
||||
)
|
||||
```
|
||||
|
||||
- [ ] **Step 6.3: Run in skip mode**
|
||||
|
||||
```powershell
|
||||
uv run pytest tests/test_docker_build.py -v
|
||||
```
|
||||
|
||||
Expected: 2 skipped.
|
||||
|
||||
- [ ] **Step 6.4: Commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add tests/test_docker_build.py
|
||||
git -C C:\projects\manual_slop commit -m "test(docker): add opt-in build and container-run tests"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Two opt-in tests: build image (RUN_DOCKER_TEST=1), run container and verify hook + web endpoints. Skipped by default. Docker daemon required." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Write the Unraid deployment guide
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/guide_docker_deployment.md`
|
||||
|
||||
- [ ] **Step 7.1: Pre-edit checkpoint**
|
||||
|
||||
```powershell
|
||||
git -C C:\projects\manual_slop add .
|
||||
```
|
||||
|
||||
- [ ] **Step 7.2: Create the guide**
|
||||
|
||||
```markdown
|
||||
# Docker Deployment Guide (Unraid)
|
||||
|
||||
[Top](../README.md) | [Architecture](guide_architecture.md) | [Tools & IPC](guide_tools.md)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This guide covers deploying Manual Slop on Unraid (or any Docker host) using the containerized image. The deployment provides:
|
||||
- A web-accessible ImGui GUI (browser-based, no local display required)
|
||||
- The Hook API on `:8999` for agent access
|
||||
- Persistent volumes for projects and app state
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Unraid 6.10+ (or any Docker host with compose support)
|
||||
- A project share mounted at `/mnt/user/projects` (or edit `docker-compose.yml` to match your path)
|
||||
- API keys for the providers you want to use
|
||||
|
||||
## Building the Image
|
||||
|
||||
From the repo root:
|
||||
```bash
|
||||
docker build -t manual_slop:latest .
|
||||
```
|
||||
|
||||
Or use the helper:
|
||||
```bash
|
||||
./scripts/docker_build.sh
|
||||
```
|
||||
|
||||
## Running the Container
|
||||
|
||||
Edit `docker-compose.yml` to set your volume paths and provider keys (via `.env` file or environment).
|
||||
|
||||
```bash
|
||||
# Create a .env file with your API keys
|
||||
cat > .env <<EOF
|
||||
GEMINI_API_KEY=your-key-here
|
||||
ANTHROPIC_API_KEY=your-key-here
|
||||
DEEPSEEK_API_KEY=your-key-here
|
||||
MINIMAX_API_KEY=your-key-here
|
||||
EOF
|
||||
|
||||
# Start the container
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Accessing the GUI
|
||||
|
||||
Open a browser and navigate to:
|
||||
- `http://<your-unraid-ip>:8080` for the web client
|
||||
- `http://<your-unraid-ip>:8999/status` for the hook API health check
|
||||
|
||||
The web client renders the ImGui panels via WebGL. The Hello ImGui web backend streams frame deltas over WebSocket.
|
||||
|
||||
## Agent Access
|
||||
|
||||
Agents interact with the running container via the Hook API on `:8999`. Examples:
|
||||
|
||||
```bash
|
||||
# Check status
|
||||
curl http://<your-unraid-ip>:8999/status
|
||||
|
||||
# Get MMA state
|
||||
curl http://<your-unraid-ip>:8999/api/mma_status
|
||||
```
|
||||
|
||||
See [guide_tools.md](guide_tools.md) for the full Hook API reference.
|
||||
|
||||
## Volumes
|
||||
|
||||
- `/projects` — Mounted from `/mnt/user/projects` by default. Your project workspaces live here. The `manual_slop.toml` per project is in this directory.
|
||||
- `/config` — Mounted from `/mnt/user/appdata/manual_slop` by default. App state: presets, personas, log directory, workspace profiles.
|
||||
|
||||
## Updating
|
||||
|
||||
```bash
|
||||
git pull
|
||||
docker build -t manual_slop:latest .
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Backup
|
||||
|
||||
Back up `/config` to preserve presets, personas, and workspace profiles. Back up `/projects/<project>/conductor/` to preserve track history.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Port conflicts:** Edit `docker-compose.yml` to change the host port (e.g., `"18080:8080"` to use 18080 on the host).
|
||||
- **Permission errors:** Ensure the Unraid share has write permissions for the container's UID.
|
||||
- **Hook API not responding:** Check `docker logs manual_slop` for the startup output. The hook server should log "HookServer started on :8999".
|
||||
```
|
||||
|
||||
- [ ] **Step 7.3: Commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop add docs/guide_docker_deployment.md
|
||||
git -C C:\projects\manual_slop commit -m "docs(docker): add Unraid deployment guide"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Unraid-specific setup guide: prerequisites, build, run via compose, web access URLs, agent access via hook API, volumes, updating, backup, troubleshooting." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 8: Phase Completion Verification
|
||||
|
||||
- [ ] **Step 8.1: Verify all files exist and are syntactically valid**
|
||||
|
||||
```powershell
|
||||
# Python syntax
|
||||
python -c "import ast; ast.parse(open('sloppy.py').read())"
|
||||
|
||||
# YAML syntax (if PyYAML available)
|
||||
python -c "import yaml; yaml.safe_load(open('docker-compose.yml').read())"
|
||||
|
||||
# Dockerfile syntax (if hadolint available)
|
||||
# hadolint Dockerfile || echo "hadolint not installed, skipping"
|
||||
|
||||
# Markdown lint (skip if not configured)
|
||||
```
|
||||
|
||||
- [ ] **Step 8.2: Run the test suite in skip mode**
|
||||
|
||||
```powershell
|
||||
uv run pytest tests/test_docker_build.py -v
|
||||
```
|
||||
|
||||
Expected: 2 skipped.
|
||||
|
||||
- [ ] **Step 8.3: If Docker is available, run the tests**
|
||||
|
||||
```powershell
|
||||
RUN_DOCKER_TEST=1 uv run pytest tests/test_docker_build.py -v
|
||||
```
|
||||
|
||||
- [ ] **Step 8.4: Create the checkpoint commit**
|
||||
|
||||
```bash
|
||||
git -C C:\projects\manual_slop commit --allow-empty -m "conductor(checkpoint): Docker & web frontend complete"
|
||||
git -C C:\projects\manual_slop log -1 --format='%H' | ForEach-Object { git -C C:\projects\manual_slop notes add -m "Track complete. Dockerfile, docker-compose.yml, build/run scripts, --web-host arg, Unraid deployment guide, opt-in Docker build test. imgui-bundle web backend integration pending Hello ImGui runner config tuning." $_ }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Self-Review
|
||||
|
||||
- **Spec coverage:** All design sections have tasks. ✓
|
||||
- **Placeholder scan:** All code blocks are complete. ✓
|
||||
- **Type consistency:** Args named consistently (`--web-host`, `--web-port`, `--enable-test-hooks`). ✓
|
||||
- **Risk acknowledged:** The web backend integration is experimental and may need iteration after testing. The checkpoint note flags this. ✓
|
||||
Reference in New Issue
Block a user