Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- PLAN.md +4 -84
- TASKS.md +64 -0
- app/routes/base.py +10 -1
- static/dashboard.html +2 -2
- static/index.html +3 -3
- static/landing.html +104 -0
PLAN.md
CHANGED
|
@@ -1,87 +1,7 @@
|
|
| 1 |
-
#
|
| 2 |
|
| 3 |
-
This
|
| 4 |
|
| 5 |
-
|
| 6 |
-
-
|
| 7 |
-
- `/ws/terminal`
|
| 8 |
-
- `/api/codex*`
|
| 9 |
-
- `/api/mcp*`
|
| 10 |
-
- any indexing endpoints (docs/web/GitHub)
|
| 11 |
-
- Define a clear auth transport for WebSockets (cookie or token) and verify on the server.
|
| 12 |
-
- Add capability flags with safe defaults:
|
| 13 |
-
- `ENABLE_TERMINAL`, `ENABLE_CODEX`, `ENABLE_MCP`, `ENABLE_INDEXING`
|
| 14 |
-
- Add `SECURITY.md` with threat model + safe deployment guidance.
|
| 15 |
-
|
| 16 |
-
## P1 — Backend refactor + lifecycle
|
| 17 |
-
- Split `main.py` into routers/services:
|
| 18 |
-
- `app/auth.py`, `app/chat.py`, `app/terminal.py`, `app/codex.py`, `app/mcp.py`, `app/settings.py`, `app/admin.py`, `app/indexing.py`
|
| 19 |
-
- Add FastAPI lifespan management:
|
| 20 |
-
- subprocess lifecycle (Codex MCP server)
|
| 21 |
-
- cleanup policies (device-login attempts, job registries)
|
| 22 |
-
- Unify Codex integration (prefer CLI-first for device-auth consistency; keep SDK only if needed).
|
| 23 |
-
- Standardize API error schema (UI should not parse strings to detect failure modes).
|
| 24 |
-
|
| 25 |
-
## P2 — UI/UX, settings, admin, landing
|
| 26 |
-
- Split `static/dashboard.html` into modules:
|
| 27 |
-
- `static/dashboard.js`, `static/terminal.js`, `static/agent.js`, `static/settings.js`, `static/admin.js`, `static/mcp.js`, `static/rag.js`
|
| 28 |
-
- `static/theme.css`
|
| 29 |
-
- Fix UI inconsistencies:
|
| 30 |
-
- theme tokens shared across login + dashboard
|
| 31 |
-
- consistent spacing, typography, button states, error banners
|
| 32 |
-
- terminal sizing/fit reliability (debounce + visible-only fitting)
|
| 33 |
-
- Separate Settings vs Admin dashboard:
|
| 34 |
-
- Settings: provider configs, tokens status, terminal layout, workspace directory, MCP registry
|
| 35 |
-
- Admin: user/role management, global toggles, indexing jobs, audit logs
|
| 36 |
-
- Create a “blazing” landing page:
|
| 37 |
-
- `/` marketing/intro + CTA
|
| 38 |
-
- keep `/login` and `/app` as dedicated routes (or similar)
|
| 39 |
-
|
| 40 |
-
## P2 — Provider auth parity (Codex/Gemini/Claude)
|
| 41 |
-
- Keep provider auth out of git; source from env/HF Secrets.
|
| 42 |
-
- Support “Codex-like” auth file generation when a CLI requires it:
|
| 43 |
-
- Codex: `~/.codex/.auth.json` and `~/.codex/auth.json` from `CODEX_*` (or fallback envs).
|
| 44 |
-
- Gemini/Claude: prefer env (`GEMINI_API_KEY`, `ANTHROPIC_API_KEY`); add file-based auth only if required and documented.
|
| 45 |
-
- Optional: SSH key support via Secrets:
|
| 46 |
-
- `SSH_PRIVATE_KEY` (+ optional `SSH_PUBLIC_KEY`, `SSH_KNOWN_HOSTS`)
|
| 47 |
-
|
| 48 |
-
## P2 — Codex workspace directory (UI)
|
| 49 |
-
- Add a per-user “workspace directory” setting.
|
| 50 |
-
- Enforce an allowlisted root (e.g. `/data/codex/workspace/<user>`), prevent traversal, ensure it exists.
|
| 51 |
-
|
| 52 |
-
## P2 — Stream Codex events in Agent mode
|
| 53 |
-
- Use `/api/codex/cli/stream` for agent execution.
|
| 54 |
-
- UI: render streaming events progressively (agent text, tool events, final summary + usage).
|
| 55 |
-
- Add stop/reconnect handling.
|
| 56 |
-
|
| 57 |
-
## P2/P3 — MCP registry
|
| 58 |
-
- Add a first-class MCP registry:
|
| 59 |
-
- per-user servers + optional global templates
|
| 60 |
-
- “test connection”, “list tools”, allow/deny tool lists
|
| 61 |
-
- import/export `mcp.json`
|
| 62 |
-
|
| 63 |
-
## P3 — RAG + indexing (docs/web/GitHub) + “password manager”
|
| 64 |
-
- Clarify “password manager” scope:
|
| 65 |
-
- secure vault for secrets (high-risk; encryption + audit required), or
|
| 66 |
-
- indexed notes (lower-risk but still private)
|
| 67 |
-
- Implement indexing connectors:
|
| 68 |
-
- document uploads
|
| 69 |
-
- website crawl (depth, allowlist, robots, rate limits)
|
| 70 |
-
- GitHub repo indexing (branch/path filters, token support via Secrets)
|
| 71 |
-
- Build a jobs UI: progress, retries, errors, and access controls.
|
| 72 |
-
|
| 73 |
-
## P3 — P2P pubsub chat + account manager
|
| 74 |
-
- Implement account manager concepts:
|
| 75 |
-
- identities/devices, room/topic membership, permissions, moderation tools
|
| 76 |
-
- Transport:
|
| 77 |
-
- WebRTC DataChannel (P2P) + server signaling
|
| 78 |
-
- fallback to server pubsub when P2P fails
|
| 79 |
-
- UX:
|
| 80 |
-
- rooms, presence, delivery status, network mode indicators
|
| 81 |
-
|
| 82 |
-
## Engineering hygiene (ongoing)
|
| 83 |
-
- Add `.env.example`, `docs/TROUBLESHOOTING.md`, `docs/ARCHITECTURE.md`, `docs/SECURITY_DEPLOYMENT.md`
|
| 84 |
-
- Add lint/tests + CI:
|
| 85 |
-
- Python: `ruff`, `pytest`
|
| 86 |
-
- basic security smoke tests for endpoint gating
|
| 87 |
|
|
|
|
| 1 |
+
# Plan
|
| 2 |
|
| 3 |
+
This repo’s roadmap lives in `PLANS.md`.
|
| 4 |
|
| 5 |
+
- Roadmap: `PLANS.md`
|
| 6 |
+
- Status checklist: `TASKS.md`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
TASKS.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Tasks Checklist
|
| 2 |
+
|
| 3 |
+
This file tracks the implementation status of `PLANS.md`. Update this checklist as work progresses.
|
| 4 |
+
|
| 5 |
+
Legend:
|
| 6 |
+
- [x] done
|
| 7 |
+
- [ ] pending
|
| 8 |
+
- [~] in progress
|
| 9 |
+
|
| 10 |
+
## P0 — Security + correctness
|
| 11 |
+
- [x] Gate dangerous endpoints server-side (`/ws/terminal`, `/api/codex*`, `/api/mcp*`).
|
| 12 |
+
- [x] Define WebSocket auth transport (token in query string for `/ws/terminal`).
|
| 13 |
+
- [x] Add capability flags (`ENABLE_TERMINAL`, `ENABLE_CODEX`, `ENABLE_MCP`, `ENABLE_INDEXING`) with safe defaults.
|
| 14 |
+
- [x] Add `SECURITY.md` with threat model + guidance.
|
| 15 |
+
|
| 16 |
+
## P1 — Backend refactor + lifecycle
|
| 17 |
+
- [x] Refactor backend into modules under `app/` and keep `uvicorn main:app` working.
|
| 18 |
+
- [x] Add FastAPI lifespan management for MCP subprocess and device-login cleanup.
|
| 19 |
+
- [ ] Unify Codex integration further (decide SDK vs CLI as primary, remove redundant paths if safe).
|
| 20 |
+
- [ ] Standardize API error schema across endpoints (single shape for UI).
|
| 21 |
+
|
| 22 |
+
## P2 — UI/UX, settings, admin, landing
|
| 23 |
+
- [~] Landing + route split (`/` landing, `/login`, `/app`) and UI redirects updated.
|
| 24 |
+
- [ ] Split `static/dashboard.html` into JS/CSS modules.
|
| 25 |
+
- [ ] Theme tokens shared across login + dashboard (single source of truth).
|
| 26 |
+
- [ ] Separate Settings vs Admin dashboard (dedicated pages/sections + RBAC).
|
| 27 |
+
|
| 28 |
+
## P2 — Provider auth parity (Codex/Gemini/Claude)
|
| 29 |
+
- [x] Codex auth file generation from env/secrets (`~/.codex/.auth.json` and `~/.codex/auth.json`).
|
| 30 |
+
- [ ] Gemini auth file parity (only if CLI requires; otherwise env-only with docs).
|
| 31 |
+
- [ ] Claude auth file parity (only if CLI requires; otherwise env-only with docs).
|
| 32 |
+
- [x] Optional SSH key support via Secrets (`SSH_PRIVATE_KEY`, `SSH_PUBLIC_KEY`, `SSH_KNOWN_HOSTS`).
|
| 33 |
+
|
| 34 |
+
## P2 — Codex workspace directory (UI)
|
| 35 |
+
- [x] Add UI setting for Codex working directory.
|
| 36 |
+
- [x] Enforce allowlisted root server-side and create directories as needed.
|
| 37 |
+
|
| 38 |
+
## P2 — Stream Codex events in Agent mode
|
| 39 |
+
- [x] Use `/api/codex/cli/stream` for agent execution.
|
| 40 |
+
- [x] UI renders streaming events + partial text (agent mode and chat target).
|
| 41 |
+
- [ ] Stop/reconnect improvements (resume stream after transient disconnects).
|
| 42 |
+
|
| 43 |
+
## P2/P3 — MCP registry
|
| 44 |
+
- [ ] First-class MCP registry storage (per-user + templates).
|
| 45 |
+
- [ ] “Test connection”, “list tools”, tool allow/deny UI.
|
| 46 |
+
- [ ] Import/export `mcp.json` via UI with validation.
|
| 47 |
+
|
| 48 |
+
## P3 — RAG + indexing (docs/web/GitHub) + “password manager”
|
| 49 |
+
- [ ] Clarify “password manager” scope and threat model.
|
| 50 |
+
- [ ] Document upload indexing connector.
|
| 51 |
+
- [ ] Website crawler indexing (depth/allowlist/robots/rate limits).
|
| 52 |
+
- [ ] GitHub repo indexing connector (branch/path filters + token support).
|
| 53 |
+
- [ ] Jobs UI (progress/retries/errors/access controls).
|
| 54 |
+
|
| 55 |
+
## P3 — P2P pubsub chat + account manager
|
| 56 |
+
- [ ] Account manager: identities/devices, memberships, permissions, moderation.
|
| 57 |
+
- [ ] Transport: WebRTC DataChannel + signaling, with server pubsub fallback.
|
| 58 |
+
- [ ] UX: rooms, presence, delivery status, network mode indicators.
|
| 59 |
+
|
| 60 |
+
## Engineering hygiene
|
| 61 |
+
- [x] Add `.env.example`.
|
| 62 |
+
- [x] Add `docs/ARCHITECTURE.md`, `docs/SECURITY_DEPLOYMENT.md`, `docs/TROUBLESHOOTING.md`.
|
| 63 |
+
- [x] Add lint/tests + CI (`ruff`, `pytest`, `.github/workflows/ci.yml`).
|
| 64 |
+
|
app/routes/base.py
CHANGED
|
@@ -25,10 +25,19 @@ async def get_config():
|
|
| 25 |
|
| 26 |
@router.get("/")
|
| 27 |
async def read_index():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
return FileResponse(str(_STATIC / "index.html"))
|
| 29 |
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
@router.get("/health")
|
| 32 |
async def health_check():
|
| 33 |
return {"status": "ok"}
|
| 34 |
-
|
|
|
|
| 25 |
|
| 26 |
@router.get("/")
|
| 27 |
async def read_index():
|
| 28 |
+
return FileResponse(str(_STATIC / "landing.html"))
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
@router.get("/login")
|
| 32 |
+
async def read_login():
|
| 33 |
return FileResponse(str(_STATIC / "index.html"))
|
| 34 |
|
| 35 |
|
| 36 |
+
@router.get("/app")
|
| 37 |
+
async def read_app():
|
| 38 |
+
return FileResponse(str(_STATIC / "dashboard.html"))
|
| 39 |
+
|
| 40 |
+
|
| 41 |
@router.get("/health")
|
| 42 |
async def health_check():
|
| 43 |
return {"status": "ok"}
|
|
|
static/dashboard.html
CHANGED
|
@@ -1396,7 +1396,7 @@
|
|
| 1396 |
supabase = window.supabase.createClient(config.supabase_url, config.supabase_key);
|
| 1397 |
|
| 1398 |
const { data: { session } } = await supabase.auth.getSession();
|
| 1399 |
-
if (!session) { window.location.href = '/'; return; }
|
| 1400 |
window.__sbAccessToken = (session.access_token || '').trim();
|
| 1401 |
supabase.auth.onAuthStateChange((_event, nextSession) => {
|
| 1402 |
window.__sbAccessToken = (nextSession?.access_token || '').trim();
|
|
@@ -1463,7 +1463,7 @@
|
|
| 1463 |
|
| 1464 |
document.getElementById('logout-btn').addEventListener('click', async () => {
|
| 1465 |
await supabase.auth.signOut();
|
| 1466 |
-
window.location.href = '/';
|
| 1467 |
});
|
| 1468 |
|
| 1469 |
initProviderPresets();
|
|
|
|
| 1396 |
supabase = window.supabase.createClient(config.supabase_url, config.supabase_key);
|
| 1397 |
|
| 1398 |
const { data: { session } } = await supabase.auth.getSession();
|
| 1399 |
+
if (!session) { window.location.href = '/login'; return; }
|
| 1400 |
window.__sbAccessToken = (session.access_token || '').trim();
|
| 1401 |
supabase.auth.onAuthStateChange((_event, nextSession) => {
|
| 1402 |
window.__sbAccessToken = (nextSession?.access_token || '').trim();
|
|
|
|
| 1463 |
|
| 1464 |
document.getElementById('logout-btn').addEventListener('click', async () => {
|
| 1465 |
await supabase.auth.signOut();
|
| 1466 |
+
window.location.href = '/login';
|
| 1467 |
});
|
| 1468 |
|
| 1469 |
initProviderPresets();
|
static/index.html
CHANGED
|
@@ -60,7 +60,7 @@
|
|
| 60 |
// Check if already logged in
|
| 61 |
const { data: { session } } = await supabase.auth.getSession();
|
| 62 |
if (session) {
|
| 63 |
-
window.location.href = '/
|
| 64 |
}
|
| 65 |
} catch (error) {
|
| 66 |
console.error('Error initializing Supabase:', error);
|
|
@@ -103,12 +103,12 @@
|
|
| 103 |
if (type === 'register') {
|
| 104 |
if (result.data && result.data.session) {
|
| 105 |
// Email verification is disabled, user is logged in
|
| 106 |
-
window.location.href = '/
|
| 107 |
} else {
|
| 108 |
showAlert('Registration successful! Please check your email to verify (if enabled) or try logging in.', 'success');
|
| 109 |
}
|
| 110 |
} else {
|
| 111 |
-
window.location.href = '/
|
| 112 |
}
|
| 113 |
} catch (error) {
|
| 114 |
showAlert(error.message);
|
|
|
|
| 60 |
// Check if already logged in
|
| 61 |
const { data: { session } } = await supabase.auth.getSession();
|
| 62 |
if (session) {
|
| 63 |
+
window.location.href = '/app';
|
| 64 |
}
|
| 65 |
} catch (error) {
|
| 66 |
console.error('Error initializing Supabase:', error);
|
|
|
|
| 103 |
if (type === 'register') {
|
| 104 |
if (result.data && result.data.session) {
|
| 105 |
// Email verification is disabled, user is logged in
|
| 106 |
+
window.location.href = '/app';
|
| 107 |
} else {
|
| 108 |
showAlert('Registration successful! Please check your email to verify (if enabled) or try logging in.', 'success');
|
| 109 |
}
|
| 110 |
} else {
|
| 111 |
+
window.location.href = '/app';
|
| 112 |
}
|
| 113 |
} catch (error) {
|
| 114 |
showAlert(error.message);
|
static/landing.html
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
|
| 4 |
+
<head>
|
| 5 |
+
<meta charset="UTF-8" />
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
| 7 |
+
<title>autonomy-labs</title>
|
| 8 |
+
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
|
| 9 |
+
</head>
|
| 10 |
+
|
| 11 |
+
<body class="min-h-screen bg-gradient-to-b from-gray-950 via-gray-900 to-gray-950 text-white">
|
| 12 |
+
<header class="border-b border-white/10">
|
| 13 |
+
<div class="mx-auto max-w-6xl px-5 py-4 flex items-center justify-between">
|
| 14 |
+
<div class="flex items-center gap-3">
|
| 15 |
+
<div class="h-9 w-9 rounded-xl bg-blue-600/20 border border-blue-500/30 flex items-center justify-center">
|
| 16 |
+
<span class="text-blue-300 font-black">A</span>
|
| 17 |
+
</div>
|
| 18 |
+
<div class="leading-tight">
|
| 19 |
+
<div class="font-semibold tracking-tight">autonomy-labs</div>
|
| 20 |
+
<div class="text-xs text-gray-400">chat · terminals · autonomous mode</div>
|
| 21 |
+
</div>
|
| 22 |
+
</div>
|
| 23 |
+
<div class="flex items-center gap-2">
|
| 24 |
+
<a href="/login"
|
| 25 |
+
class="px-3 py-2 rounded-lg text-sm text-gray-200 hover:text-white hover:bg-white/5 border border-white/10">Login</a>
|
| 26 |
+
<a href="/app"
|
| 27 |
+
class="px-3 py-2 rounded-lg text-sm bg-blue-600 hover:bg-blue-700 font-semibold border border-blue-500/40">Open
|
| 28 |
+
App</a>
|
| 29 |
+
</div>
|
| 30 |
+
</div>
|
| 31 |
+
</header>
|
| 32 |
+
|
| 33 |
+
<main class="mx-auto max-w-6xl px-5 py-14">
|
| 34 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-10 items-center">
|
| 35 |
+
<div>
|
| 36 |
+
<div
|
| 37 |
+
class="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1 text-xs text-gray-300">
|
| 38 |
+
<span class="h-2 w-2 rounded-full bg-green-400"></span>
|
| 39 |
+
FastAPI + Supabase + Docker (HF Spaces)
|
| 40 |
+
</div>
|
| 41 |
+
<h1 class="mt-5 text-4xl lg:text-5xl font-black tracking-tight">
|
| 42 |
+
Build faster with chat, terminals, and autonomous workflows.
|
| 43 |
+
</h1>
|
| 44 |
+
<p class="mt-4 text-gray-300 text-lg leading-relaxed">
|
| 45 |
+
A lightweight UI that combines AI chat, PTY-backed terminals, and an agent mode that can stream execution
|
| 46 |
+
events.
|
| 47 |
+
Designed for Hugging Face Spaces and local development.
|
| 48 |
+
</p>
|
| 49 |
+
<div class="mt-7 flex flex-wrap gap-3">
|
| 50 |
+
<a href="/login"
|
| 51 |
+
class="px-5 py-3 rounded-xl bg-blue-600 hover:bg-blue-700 font-semibold border border-blue-500/40">Get
|
| 52 |
+
started</a>
|
| 53 |
+
<a href="/app"
|
| 54 |
+
class="px-5 py-3 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 text-gray-200">Open app</a>
|
| 55 |
+
<a href="/health"
|
| 56 |
+
class="px-5 py-3 rounded-xl bg-white/5 hover:bg-white/10 border border-white/10 text-gray-200">Health
|
| 57 |
+
check</a>
|
| 58 |
+
</div>
|
| 59 |
+
<div class="mt-8 grid grid-cols-1 sm:grid-cols-2 gap-4">
|
| 60 |
+
<div class="rounded-2xl border border-white/10 bg-white/5 p-4">
|
| 61 |
+
<div class="text-sm font-semibold">Secure execution gates</div>
|
| 62 |
+
<div class="text-sm text-gray-400 mt-1">Terminal/Codex/MCP are server-side gated behind Supabase auth.</div>
|
| 63 |
+
</div>
|
| 64 |
+
<div class="rounded-2xl border border-white/10 bg-white/5 p-4">
|
| 65 |
+
<div class="text-sm font-semibold">Streaming agent UX</div>
|
| 66 |
+
<div class="text-sm text-gray-400 mt-1">Live progress and partial text rendering for long runs.</div>
|
| 67 |
+
</div>
|
| 68 |
+
</div>
|
| 69 |
+
</div>
|
| 70 |
+
|
| 71 |
+
<div class="relative">
|
| 72 |
+
<div
|
| 73 |
+
class="absolute -inset-6 bg-gradient-to-tr from-blue-600/30 via-purple-600/20 to-cyan-500/20 blur-3xl rounded-full">
|
| 74 |
+
</div>
|
| 75 |
+
<div class="relative rounded-2xl border border-white/10 bg-gray-950/40 p-5 shadow-2xl">
|
| 76 |
+
<div class="flex items-center justify-between">
|
| 77 |
+
<div class="text-sm font-semibold text-gray-200">What you get</div>
|
| 78 |
+
<div class="text-xs text-gray-400">MVP · extensible roadmap</div>
|
| 79 |
+
</div>
|
| 80 |
+
<ul class="mt-4 space-y-3 text-sm text-gray-300">
|
| 81 |
+
<li class="flex gap-3"><span class="text-blue-400">●</span> Chat with markdown + math rendering</li>
|
| 82 |
+
<li class="flex gap-3"><span class="text-blue-400">●</span> Multi-tab terminals over WebSockets (PTY)</li>
|
| 83 |
+
<li class="flex gap-3"><span class="text-blue-400">●</span> Agent mode with optional Codex CLI streaming</li>
|
| 84 |
+
<li class="flex gap-3"><span class="text-blue-400">●</span> MCP tooling hooks (feature-flagged)</li>
|
| 85 |
+
<li class="flex gap-3"><span class="text-blue-400">●</span> Ready for indexing / P2P / admin features</li>
|
| 86 |
+
</ul>
|
| 87 |
+
<div class="mt-6 rounded-xl border border-white/10 bg-white/5 p-4 text-xs text-gray-400">
|
| 88 |
+
Tip: set secrets in HF Spaces → Settings → Variables and secrets, then restart the Space.
|
| 89 |
+
</div>
|
| 90 |
+
</div>
|
| 91 |
+
</div>
|
| 92 |
+
</div>
|
| 93 |
+
</main>
|
| 94 |
+
|
| 95 |
+
<footer class="border-t border-white/10">
|
| 96 |
+
<div class="mx-auto max-w-6xl px-5 py-8 flex flex-col sm:flex-row gap-2 sm:items-center sm:justify-between">
|
| 97 |
+
<div class="text-sm text-gray-400">autonomy-labs</div>
|
| 98 |
+
<div class="text-sm text-gray-500">See `PLANS.md` and `TASKS.md` for the roadmap.</div>
|
| 99 |
+
</div>
|
| 100 |
+
</footer>
|
| 101 |
+
</body>
|
| 102 |
+
|
| 103 |
+
</html>
|
| 104 |
+
|