Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
15 changes: 15 additions & 0 deletions .cursor/environment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "Project Muteki",
"install": "bash .cursor/install.sh",
"terminals": [
{
"name": "web-deck",
"command": "./run.sh web",
"description": "Muteki command deck: FastAPI backend on :8000 + production Next UI on :3001 (loopback). Open http://127.0.0.1:3001. Set MUTEKI_DEEPSEEK_API_KEY (and an engine CLI login) to run real solves."
}
],
"ports": [
{ "name": "backend", "port": 8000 },
{ "name": "web-ui", "port": 3001 }
]
}
42 changes: 42 additions & 0 deletions .cursor/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Cloud Agent install phase for Project Muteki.
#
# Idempotent dependency refresh run after the repository is checked out. It must
# terminate: no dev servers, tests, or long-running processes belong here (the
# web deck is launched from the `terminals` entry in .cursor/environment.json).
set -euo pipefail

cd "$(dirname "$0")/.."

# ── System dependency: libzbar (pyzbar QR decoding) ──────────────────────────
# Only a QR challenge needs it; the default test path never imports pyzbar, so a
# failure here is a warning, not a hard stop (mirrors init.sh's behaviour).
if ! ldconfig -p 2>/dev/null | grep -qi 'libzbar'; then
if command -v sudo >/dev/null 2>&1; then
sudo apt-get update -qq \
&& sudo apt-get install -y -qq libzbar0 \
|| echo "(warn) could not install libzbar0 — QR-decode helpers will be unavailable." >&2
else
echo "(warn) no sudo — skipping libzbar0; QR-decode helpers will be unavailable." >&2
fi
fi

# ── Python toolchain (uv) ────────────────────────────────────────────────────
# uv provisions the pinned Python (>=3.13 per pyproject.toml) itself.
export PATH="$HOME/.local/bin:$PATH"
if ! command -v uv >/dev/null 2>&1; then
echo "==> installing uv from https://astral.sh/uv …"
curl -LsSf https://astral.sh/uv/install.sh | sh
export PATH="$HOME/.local/bin:$PATH"
fi

# ── Python dependencies (core + dev test tools) ──────────────────────────────
uv sync --extra dev

# ── Next.js command-deck dependencies ────────────────────────────────────────
# Only the local web UI needs Node; skip cleanly if npm is unavailable.
if [ -f apps/web/ui/package.json ] && command -v npm >/dev/null 2>&1; then
( cd apps/web/ui && npm install )
fi

echo "OK — Muteki install complete."
19 changes: 19 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ MUTEKI_DEEPSEEK_API_KEY=sk-your-deepseek-key-here
# MUTEKI_WEB_TOKEN_TTL=43200 # session-token lifetime in seconds (default 12h)
# MUTEKI_WEB_AUTH_SECRET= # optional explicit HMAC signing key

# ── Optional: self-hosted releases ────────────────────────────────────────────
# Public upgrades default to FishCodeTech/muteki and ghcr.io/fishcodetech.
# Override only if you publish your own tags and images:
# MUTEKI_RELEASE_REPOSITORY=FishCodeTech/muteki
# MUTEKI_GITHUB_TOKEN=ghp_your_release_token
# MUTEKI_IMAGE_REGISTRY=ghcr.io/fishcodetech
# MUTEKI_UPDATE_MANIFEST_URL= # optional full manifest URL, may include {version}
# Protocol 2 release receipts are normally loaded automatically from the
# worktree-bound docs/_local/protocol2_release_receipts.json. Explicit shell or
# .env values still win; a stale/mismatched receipt leaves production disabled.
# MUTEKI_PROTOCOL2_BASELINE_RECEIPT=
# MUTEKI_PROTOCOL2_FAULT_SUITE_RECEIPT=

# ── Optional: model endpoint / HTTP transport ────────────────────────────────
# Defaults to https://api.deepseek.com/v1 if unset.
# MUTEKI_DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
Expand Down Expand Up @@ -108,6 +121,12 @@ MUTEKI_DEEPSEEK_API_KEY=sk-your-deepseek-key-here
# MUTEKI_CONTAINER_DATA_ROOT, MUTEKI_SESSIONS_ROOT, MUTEKI_WEB_BIND.
# Do NOT set those by hand unless you are building a custom deployment topology.

# Optional coordinator-private root for durable control.db + SecretStore files.
# It must be outside every sessions/{run}/workspace tree (worker workspaces are
# recursively chowned and bind-mounted read-write). Compose sets a safe sibling
# under MUTEKI_HOST_DATA_ROOT; local runs default to sessions/.coordinator-control.
# MUTEKI_COORDINATOR_CONTROL_ROOT=/opt/muteki/data/coordinator-control

# ── Optional: reverse-connect control plane (advanced) ───────────────────────
# Worker containers dial back to the backend receiver. Defaults work for local
# Docker Desktop; compose sets the right values automatically.
Expand Down
80 changes: 80 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: ci

on:
push:
branches:
- main
- feat/web-beautiful-ui
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
python:
name: Python tests
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v7

- name: Set up uv and Python
uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
version: "0.12.5"
python-version: "3.13"
enable-cache: true
cache-dependency-glob: uv.lock

- name: Install locked dependencies
run: uv sync --frozen --extra dev

- name: Run Python tests
run: uv run --frozen python -m pytest -q

runtime-agent:
name: Runtime agent tests
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7

- name: Set up Go
uses: actions/setup-go@v7
with:
go-version-file: cmd/runtime-agent/go.mod
cache: false

- name: Run Go tests
run: go test -C cmd/runtime-agent ./...

web-ui:
name: Web UI checks
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: apps/web/ui
steps:
- uses: actions/checkout@v7

- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: "20"
cache: npm
cache-dependency-path: apps/web/ui/package-lock.json

- name: Install locked dependencies
run: npm ci

- name: Check TypeScript
run: ./node_modules/.bin/tsc --noEmit

- name: Build production UI
run: npm run build
Loading