axis / public /index.html
smridhgupta's picture
Update public/index.html
a7469a6 verified
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<title>Axis · Client</title>
<style>
:root {
--bg:#0b0f17; --fg:#e6eef8; --muted:#a9b7c6; --card:#121825; --accent:#7aa2f7;
--ok:#38d39f; --bad:#ff6b6b; --line:#1a2336; --ink:#0e1422;
}
*{box-sizing:border-box}
body{
margin:0;font:15px/1.55 system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,'Helvetica Neue',Arial;
background: radial-gradient(1200px 600px at 10% -10%,#122034,transparent),var(--bg);
color:var(--fg)
}
header{padding:36px 20px 10px;max-width:1100px;margin:0 auto}
.badge{display:inline-block;padding:4px 10px;border:1px solid #2c3650;border-radius:999px;font-size:12px;color:var(--muted)}
h1{margin:12px 0 8px;font-size:28px;letter-spacing:.2px}
.sub{color:var(--muted);margin:0 0 18px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;color:var(--muted)}
.grid{display:grid;grid-template-columns:1.2fr 1fr;gap:18px;max-width:1100px;padding:0 20px 36px;margin:0 auto}
.grid-1{display:grid;grid-template-columns:1fr;gap:18px;max-width:1100px;padding:0 20px 36px;margin:0 auto}
.card{background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0));border:1px solid var(--line);border-radius:14px;padding:16px}
.card h3{margin:0 0 8px;font-size:16px}
.muted{color:var(--muted)}
a{color:#9ec1ff;text-decoration:none}
.ok{color:var(--ok)} .bad{color:var(--bad)}
pre{position:relative;background:var(--ink);color:#cfe3ff;padding:12px;border-radius:10px;overflow:auto;border:1px solid var(--line);margin:0 0 10px}
code,pre,textarea{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace}
.btn{background:var(--accent);color:#0b0f17;border:none;padding:10px 14px;border-radius:10px;cursor:pointer;font-weight:600}
.btn.secondary{background:transparent;color:#cfe3ff;border:1px solid var(--line)}
.btn:disabled{filter:grayscale(.5);opacity:.7;cursor:not-allowed}
.btns{display:flex;gap:10px;flex-wrap:wrap}
.copy{position:absolute;top:8px;right:8px;background:transparent;border:1px solid var(--line);color:var(--fg);border-radius:8px;padding:6px 8px;cursor:pointer}
ul.check{list-style:none;padding:0;margin:8px 0 0}
ul.check li{margin:6px 0;padding-left:24px;position:relative}
ul.check li:before{content:"✓";position:absolute;left:0;top:0;color:var(--ok)}
.pill{display:inline-block;padding:2px 8px;border:1px solid var(--line);border-radius:999px;font-size:12px;color:var(--muted)}
footer{max-width:1100px;margin:0 auto 32px;padding:0 20px;color:var(--muted)}
.kvs{display:flex;gap:10px;flex-wrap:wrap;margin-top:8px}
.kvs .k{padding:6px 10px;border:1px solid var(--line);border-radius:8px;background:rgba(255,255,255,.02)}
@media (max-width:1000px){.grid{grid-template-columns:1fr}}
/* Screenshot cards */
figure.shoot{
margin:16px 0 0;padding:10px;border:1px solid var(--line);border-radius:14px;
background:linear-gradient(180deg,rgba(255,255,255,.015),rgba(255,255,255,0));
}
figure.shoot .shot-wrap{
position:relative;overflow:hidden;border-radius:12px;
}
figure.shoot img{
display:block;width:100%;height:auto;transform:scale(1.001);
transition:transform .35s ease, filter .35s ease;
filter:saturate(1.05) contrast(1.02);
background:#0c111b;
}
figure.shoot:hover img{transform:scale(1.02)}
figure.shoot figcaption{margin-top:8px;font-size:13px;color:var(--muted)}
.chip{display:inline-block;font-size:11px;border:1px solid var(--line);border-radius:999px;padding:2px 8px;margin-right:6px;color:var(--muted)}
</style>
</head>
<body>
<header>
<span class="badge">Axis · Agent (Client-First)</span>
<h1>TanDev Axis</h1>
<p class="sub">
Use the <b>client</b> folder ( <code>/client/</code> ) to plan and run tasks locally with a safe, step-by-step UX.
The server <b>does not execute commands</b> — it only plans/assists.
</p>
<div class="row">
<div>Live status: <span id="live" class="ok">Checking…</span></div>
<div></div>
<div>Model: <span id="modelName" class="pill"></span></div>
<div></div>
<div><a href="/status">/status</a></div>
</div>
</header>
<section class="grid">
<!-- DOWNLOAD -->
<div class="card">
<h3>Download the client folder</h3>
<p class="muted">Grab the folder that includes <code>client.py</code> and <code>key.json</code>.</p>
<div class="btns" style="margin:10px 0 6px">
<a id="dlZip" class="btn" target="_blank">📦 Download client.zip</a>
<a id="dlPy" class="btn secondary" target="_blank">🧠 client.py</a>
<a id="dlKey" class="btn secondary" target="_blank">🔑 key.json</a>
<a id="browseClient" class="btn secondary" target="_blank">📁 Browse /client/</a>
</div>
<div class="kvs" style="margin-top:6px;font-size:14px">
<div class="k"><b>Folder:</b> <code>/client/</code></div>
<div class="k"><b>Script:</b> <code>client.py</code></div>
<div class="k"><b>Key file:</b> <code>key.json</code></div>
</div>
<p class="muted" style="margin-top:10px">Prefer CLI? Clone or fetch files directly:</p>
<pre style="margin-top:6px">
git clone https://huggingface.co/spaces/tandevllc/axis
cd axis/client
python3 client.py --server https://tandevllc-axis.hf.space
</pre>
</div>
<!-- WHY CLIENT -->
<div class="card">
<h3>Why this client?</h3>
<ul class="check">
<li>Local-only execution with danger checks (no server-side command execution)</li>
<li>Plan preview, dry-run, and per-step confirmation</li>
<li>Rich UI + transcripts saved to <code>~/.llama3_agent/sessions/</code></li>
<li>Edit the JSON plan in your <code>$EDITOR</code> before running</li>
</ul>
<p class="muted" style="margin-top:8px">Built by TanDev · Axis.</p>
</div>
</section>
<section class="grid-1">
<!-- INSTALL & RUN -->
<div class="card">
<h3>Install & Run</h3>
<p class="muted"><b>macOS/Linux</b></p>
<pre data-os="unix"><button class="copy" aria-label="Copy">Copy</button><code id="unixCmds">
# 1) Python deps
python3 -m pip install --upgrade pip
pip install rich click requests
# 2) Download client files (buttons above also work)
# curl -O {BASE}/client/client.py
# curl -O {BASE}/client/key.json
# or:
# wget {BASE}/client/client.py && wget {BASE}/client/key.json
# 3) Run
python3 client.py
</code></pre>
<p class="muted" style="margin-top:8px"><b>Windows (PowerShell)</b></p>
<pre data-os="win"><button class="copy" aria-label="Copy">Copy</button><code id="winCmds">
py -m pip install --upgrade pip
py -m pip install rich click requests
Invoke-WebRequest -Uri "{BASE}/client/client.py" -OutFile "client.py"
Invoke-WebRequest -Uri "{BASE}/client/key.json" -OutFile "key.json"
py client.py
</code></pre>
<p class="muted" style="margin-top:10px">
<span class="chip">API key</span> Set <code>LLAMA_API_KEY</code> or edit <code>key.json</code><code>{"api_key":"YOUR_KEY"}</code>.
In the client: <code>:apikey set</code> / <code>:apikey clear</code>.
</p>
</div>
<!-- USAGE -->
<div class="card">
<h3>Usage cheatsheet</h3>
<pre><button class="copy" aria-label="Copy">Copy</button><code>
# Start
python3 client.py
# Plan hotkeys:
# [a] Execute all [s] Step-by-step [e] Edit plan
# [d] Toggle dry-run [c] Cancel
# Danger gate: warns on risky shell like `rm -rf /`, `curl | sh`, `mkfs.*`, etc.
# Logs:
# ~/.llama3_agent/sessions/<timestamp>/
</code></pre>
</div>
</section>
<!-- TUTORIAL -->
<section class="grid-1">
<div class="card">
<h3>Tutorial: Plan → Review → Execute (client-side)</h3>
<p class="muted">
The Axis client asks the server to <b>plan</b>, lets you <b>review</b> the steps,
and then <b>runs locally</b> with safety checks. The server <u>never</u> executes shell commands.
</p>
<ol style="margin:0 0 12px 18px">
<li><b>Launch</b> the client:
<pre><button class="copy" aria-label="Copy">Copy</button><code>
python3 client.py
</code></pre>
</li>
<li><b>Describe the task</b> (“scaffold a Flask app and run it”). Client calls <code>/infer</code> and shows a plan.</li>
<li><b>Review</b> and choose: <b>[a]</b> all • <b>[s]</b> step-by-step • <b>[e]</b> edit • <b>[d]</b> dry-run • <b>[c]</b> cancel.</li>
<li><b>Danger gate</b> prompts for risky shell; type <code>proceed</code> to continue.</li>
<li><b>Inspect results</b> (stdout/stderr, bytes written, previews). Saved under:
<pre><button class="copy" aria-label="Copy">Copy</button><code>~/.llama3_agent/sessions/&lt;timestamp&gt;/</code></pre>
</li>
</ol>
<!-- Shots (use HF resolve URLs so they always load) -->
<figure class="shoot">
<div class="shot-wrap">
<img id="shotA" alt="Plan & Execute: Flask scaffold, venv install, local run" loading="lazy"/>
</div>
<figcaption>
<b>Screenshot A — Plan & Execute:</b> planned a Flask scaffold, created files, installed deps in a venv,
and ran commands locally with rich stdout/stderr panels.
</figcaption>
</figure>
<figure class="shoot">
<div class="shot-wrap">
<img id="shotB" alt="LLM Respond: pure text response step inside the flow" loading="lazy"/>
</div>
<figcaption>
<b>Screenshot B — LLM Respond:</b> use <code>respond</code>/<code>respond_llm</code> when you just need
narrative guidance or an answer—no shell required.
</figcaption>
</figure>
<figure class="shoot">
<div class="shot-wrap">
<img id="shotC" alt="Generate File: wrote gallery.html then explained how to open it" loading="lazy"/>
</div>
<figcaption>
<b>Screenshot C — Generate File:</b> wrote <code>gallery.html</code> with <code>generate_file</code> and
confirmed how to open it. Great for content, stubs, and docs.
</figcaption>
</figure>
<p class="muted" style="margin-top:12px">
<b>Meta commands</b>: <code>:server</code>, <code>:apikey set|clear</code>, <code>:history</code>,
<code>:open &lt;path&gt;</code>, <code>:clear</code>, <code>:help</code>.
</p>
<p class="muted" style="margin-top:4px">
<b>Tip:</b> Best with Llama-3-8B; TinyLlama on HF is fine for light tasks. Scaffold apps, write articles,
manipulate files/dirs, and run OS-aware shell—locally and safely.
</p>
</div>
</section>
<footer>
<p>Axis · Agent — Client delivery by TanDev. Status: <a href="/status">/status</a></p>
</footer>
<script>
const BASE = window.location.origin;
// Live status/model
(async function ping(){
try {
const r = await fetch('/status');
const j = await r.json();
document.getElementById('live').textContent = r.ok ? 'Running' : ('HTTP '+r.status);
if (j && j.model) document.getElementById('modelName').textContent = j.model;
} catch { document.getElementById('live').textContent = 'Unknown'; }
})();
// All three buttons point to the folder (your request)
const HF_TREE_CLIENT = "https://huggingface.co/spaces/tandevllc/axis/tree/main/client/";
document.getElementById('dlZip').href = HF_TREE_CLIENT;
document.getElementById('dlPy').href = HF_TREE_CLIENT;
document.getElementById('dlKey').href = HF_TREE_CLIENT;
document.getElementById('browseClient').href = HF_TREE_CLIENT;
// Fill BASE placeholder in code blocks
function fill(id){
const el = document.getElementById(id);
if(!el) return;
el.textContent = el.textContent.replaceAll('{BASE}', BASE);
}
fill('unixCmds'); fill('winCmds');
// Copy buttons
for (const pre of document.querySelectorAll('pre')) {
const btn = pre.querySelector('.copy'); if (!btn) continue;
btn.addEventListener('click', async () => {
const code = pre.querySelector('code').innerText;
try { await navigator.clipboard.writeText(code); btn.textContent='Copied'; }
catch { btn.textContent='Failed'; }
setTimeout(()=>btn.textContent='Copy', 1200);
});
}
// ---- Images (use HF resolve URLs so they always load even if /static isn't served) ----
// Change these filenames if your repo filenames differ.
const HF_STATIC_BASE = "https://huggingface.co/spaces/tandevllc/axis/resolve/main/static";
const SHOT_A = HF_STATIC_BASE + "/tutorial-plan-flask.png";
const SHOT_B = HF_STATIC_BASE + "/tutorial-llm-respond.png";
const SHOT_C = HF_STATIC_BASE + "/tutorial-generate-file.png";
document.getElementById('shotA').src = SHOT_A;
document.getElementById('shotB').src = SHOT_B;
document.getElementById('shotC').src = SHOT_C;
</script>
</body>
</html>