main
John Lauer 0.1.9: a dead dashboard server toasts once, not every poll b2793c7 1mo ago
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Antigravity in Hydrogen</title><link rel="icon" href="/dashboard/icon.svg"><style>
:root{color-scheme:dark;--bg:#0d1117;--surface:#161b22;--surface2:#1c232c;--line:#262d36;--text:#e6edf3;--muted:#8b949e;--teal:#00b8b1;--led-green:#3fb950;--led-amber:#d29922;--led-red:#f85149;--sans:"Familjen Grotesk",system-ui,sans-serif;--body:system-ui,-apple-system,"Segoe UI",sans-serif;--mono:"JetBrains Mono",ui-monospace,Consolas,monospace}
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:15px var(--body)}
header{height:44px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:8px;padding:0 16px}header img{width:18px;height:18px}header strong{font:600 15px var(--sans)}header span{color:var(--muted);font-size:13px}.spacer{flex:1}
button,a{touch-action:manipulation}button{background:var(--surface);color:var(--text);border:1px solid var(--line);border-radius:6px;padding:8px 12px;cursor:pointer;font:inherit}button:hover,button:focus-visible{border-color:var(--teal)}button.primary{background:rgba(0,184,177,.13);border-color:rgba(0,184,177,.45);color:#00d4cb}button[disabled]{opacity:.5;cursor:wait}
main{padding:16px}h1{font:700 30px var(--sans);margin:0 0 8px}h2{font:600 19px var(--sans);margin:0 0 6px}p{line-height:1.6;color:var(--muted);margin:0 0 10px}a{color:var(--teal)}code{font:12.5px var(--mono);background:var(--surface2);padding:1px 5px;border-radius:4px}
.leds{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 18px}.led-pill{display:inline-flex;align-items:center;gap:7px;background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:5px 11px;font-size:12.5px}.led-pill .dot{width:8px;height:8px;border-radius:50%;background:#555}.led-pill[data-state=ok] .dot{background:var(--led-green)}.led-pill[data-state=busy] .dot{background:var(--led-amber)}.led-pill[data-state=bad] .dot{background:var(--led-red)}.led-pill b{font-weight:600}.led-pill span{color:var(--muted)}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:16px}.card{padding:20px;background:var(--surface);border:1px solid var(--line);border-radius:12px}.card .row{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}.hint{font-size:12.5px;color:var(--muted);margin-top:10px}
dialog{width:min(900px,95vw);background:var(--surface);color:var(--text);border:1px solid var(--line);border-radius:12px}dialog::backdrop{background:#0008}pre{white-space:pre-wrap;word-break:break-word;font:12.5px var(--mono);max-height:60vh;overflow:auto}.close{float:right}
#toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);background:var(--surface);padding:10px 14px;border:1px solid var(--teal);border-radius:8px;display:none;max-width:80vw}#toast.err{border-color:var(--led-red)}#toast.ok{border-color:var(--led-green)}
@media(max-width:720px){header span{display:none}}
</style><header><img src="/dashboard/icon.svg" alt=""><strong title="adom/antigravity dashboard">Antigravity</strong><span>Google's agent in Hydrogen</span><div class="spacer"></div><span id="machine">Container</span><button id="help" title="Show or hide starter prompts" aria-label="Starter prompts">?</button><button id="settings" title="Integration details" aria-label="Integration details"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="m10 2 4 0 1 3 3 2 3 0 1 4-2 2-1 3 1 3-4 2-2-2-3-1-3 1-2-4 2-2 1-3-1-3 4-2z"/><circle cx="12" cy="12" r="3"/></svg></button></header>
<main>
<div id="newbie"></div>
<div class="leds" id="leds" role="status" aria-label="Antigravity status">
  <span class="led-pill" data-state="" id="led-ext"><i class="dot"></i><b>Extension</b><span>checking</span></span>
  <span class="led-pill" data-state="" id="led-cli"><i class="dot"></i><b>CLI</b><span>checking</span></span>
  <span class="led-pill" data-state="" id="led-signin"><i class="dot"></i><b>Sign-in</b><span>checking</span></span>
  <span class="led-pill" data-state="" id="led-editor"><i class="dot"></i><b>Editor</b><span>checking</span></span>
  <span class="led-pill" data-state="" id="led-rt"><i class="dot"></i><b>Runtime</b><span>checking</span></span>
</div>
<h1>Try Google Antigravity, inside your Adom workspace.</h1>
<p>Antigravity is Google's agent-first coding tool. This installs its VS Code extension into your Hydrogen editor and its <code>agy</code> command line into your container, so it sits next to Claude Code, Codex and Kimi. Nothing touches Windows or macOS itself.</p>
<div class="grid">
  <section class="card"><h2>1. The editor extension</h2><p>Puts the Antigravity side bar in your editor (its own icon on the activity bar). Sign in with your Google account inside that panel; in a Hydrogen workspace that same sign-in covers the CLI.</p>
    <div class="row"><button class="primary" id="install-ext">Install the extension</button><button id="reload">Reload the editor</button></div>
    <div class="hint" id="ext-hint">From Open VSX (Google.google-antigravity). A fresh install needs one editor reload.</div></section>
  <section class="card"><h2>2. The command line</h2><p>The <code>agy</code> CLI runs Antigravity's agent in a terminal, the way Claude and Codex have their TUIs.</p>
    <div class="row"><button class="primary" id="install-cli">Install the CLI</button><button id="tui">Open an Antigravity terminal</button></div>
    <div class="hint" id="cli-hint">Official installer into ~/.local/bin/agy. First run: <code>agy</code> prints a Google sign-in link when it cannot open a browser. Headless: set <code>GEMINI_API_KEY</code> and <code>modelProvider: gemini</code> in ~/.gemini/antigravity-cli/settings.json.</div></section>
  <section class="card"><h2>3. Use it</h2><p>Open the Antigravity side bar in your editor (its own icon on the activity bar) and sign in with Google the first time. The AI launch bar's Antigravity icon does the same; its TUI entry runs <code>agy</code>.</p>
    <div class="row"><button class="primary" id="open">Open Antigravity</button><button id="open-new">New conversation</button></div>
    <div class="hint" id="open-hint">Needs Hydrogen 1.0.224 or later, which serves forwarded ports the way this panel expects. On an older Hydrogen or on Web Hydrogen the panel is blank, and this button opens Antigravity's UI as a tab instead.</div></section>
  <section class="card"><h2>What it is</h2><p>An agent that plans, writes and verifies across your files and a browser, with its own workflows and artifacts. Free tier from Google; the extension and CLI both need a Google sign-in.</p>
    <div class="row"><a href="https://antigravity.google/docs" target="_blank">Antigravity docs</a><a href="https://antigravity.google/docs/cli/install/" target="_blank">CLI install and auth</a><a href="https://open-vsx.org/extension/Google/google-antigravity" target="_blank">The extension on Open VSX</a></div></section>
</div>
</main>
<dialog id="details"><button class="close" id="close-details">Close</button><h2>Local integration</h2><pre id="context"></pre></dialog>
<div id="toast" role="status"></div>
<script src="/dashboard/vendor/newbie-panel.js"></script><script>
const $=s=>document.querySelector(s);let toastT=null;
function toast(s,kind){const t=$('#toast');t.textContent=s;t.className=kind||'';t.style.display='block';clearTimeout(toastT);toastT=setTimeout(()=>t.style.display='none',kind==='err'?7000:4000)}
const panel=AdomNewbiePanel.mount({mount:'#newbie',app:'antigravity',ai:'antigravity',appName:'Antigravity',slug:'antigravity',toggleButton:'#help',phrases:['Install Antigravity into my workspace','Open Antigravity and show me what it can do','Sign me in to the Antigravity CLI']});
function led(id,state,text){const e=$(id);e.dataset.state=state;e.querySelector('span').textContent=text}
function render(s){$('#machine').textContent=(s.runtime==='wsl2'?'WSL2':s.runtime==='lima'?'Lima':'Linux')+' · '+s.container.hostname;
 led('#led-ext',s.extension.installed?'ok':'bad',s.extension.installed?('installed '+(s.extension.versions[0]||'')):'not installed');
 led('#led-cli',s.cli.installed?(s.cli.duplicate?'busy':'ok'):'bad',s.cli.installed?((s.cli.version||'installed')+(s.cli.linkedToExtensionCopy?' · the extension\'s copy':s.cli.duplicate?' · second copy, click Link the CLI':'')):'not installed');
 led('#led-signin',s.signin&&s.signin.signedIn?'ok':'bad',s.signin&&s.signin.signedIn?('signed in'+(s.signin.email?' as '+s.signin.email:'')+(s.signin.extension.signedIn&&s.signin.cli.signedIn?' · extension + CLI':s.signin.extension.signedIn?' · extension':' · CLI')):'not signed in');
 led('#led-editor',s.editor.reachable?'ok':'busy',s.editor.reachable?('adom-vscode '+s.editor.adomVscode):'editor not reachable');
 led('#led-rt','ok',s.runtime==='wsl2'?'WSL2 container':s.runtime==='lima'?'Lima container':'Linux container');
 $('#open').disabled=!s.extension.installed;$('#open').title=s.panelWorks?'Opens the Antigravity side bar in the editor':(s.hub&&s.hub.up?'This editor path-proxies ports (panel blank): opens Antigravity\'s UI as a tab':'Install the extension and reload the editor first');
 $('#open-hint').textContent=s.panelWorks?'The side bar renders here (Hydrogen serves forwarded ports as <port>.localhost). Ctrl+Shift+L starts a new conversation; Ctrl+L adds a selection.':'This editor still path-proxies ports, so the side-bar panel is blank; Open Antigravity shows the same UI as a tab. Hydrogen 1.0.224+ fixes the panel.';
 $('#install-ext').textContent=s.extension.installed?'Reinstall / update the extension':'Install the extension';
 $('#install-cli').textContent=s.cli.installed?(s.cli.duplicate?'Link the CLI to the extension\'s copy':'Relink the CLI'):(s.cli.extensionCopy?'Link the CLI to the extension\'s copy':'Install the CLI');window.__ag=s}
async function refresh(){try{const r=await fetch('/api/status');render(await r.json());if(window.__down){window.__down=false;toast('Dashboard server is back','ok')}}catch(e){if(!window.__down){window.__down=true;toast('This dashboard\'s server is not answering (it restarts when you open Antigravity from the dock again)','err')}}}
async function post(path,body,btn,busyText){const old=btn?btn.textContent:'';if(btn){btn.disabled=true;btn.textContent=busyText||'Working…'}try{const r=await fetch(path,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(body||{})});const j=await r.json();if(j.ok===false)toast(j.error||j.output||'failed','err');else toast(j.next||j.note||'Done','ok');await refresh();return j}catch(e){toast(e.message,'err')}finally{if(btn){btn.disabled=false;btn.textContent=old}}}
$('#install-ext').onclick=e=>post('/api/install-extension',{},e.currentTarget,'Installing the extension…');
$('#install-cli').onclick=e=>post('/api/install-cli',{},e.currentTarget,'Installing agy…');
$('#reload').onclick=e=>post('/api/reload-editor',{},e.currentTarget,'Reloading…');
$('#open').onclick=async e=>{const j=await post('/api/open',{},e.currentTarget,'Opening…');if(j&&j.ok&&j.url){toast('Opening Antigravity in this tab…','ok');setTimeout(()=>{location.href=j.url},400)}};
$('#open-new').onclick=e=>post('/api/open',{new:true},e.currentTarget,'Opening…');
$('#tui').onclick=e=>post('/api/tui',{},e.currentTarget,'Opening a terminal…');
async function inspect(){try{const r=await fetch('/api/status');$('#context').textContent=JSON.stringify(await r.json(),null,2);$('#details').showModal()}catch(e){toast(e.message,'err')}}
$('#settings').onclick=inspect;$('#close-details').onclick=()=>$('#details').close();
refresh();setInterval(refresh,15000);
window.adomAntigravity={state:()=>fetch('/state').then(r=>r.json()),refresh,inspect,selfCheck:()=>AdomNewbiePanel.selfCheck()};
</script></html>