crimata-os/ui/index.html
Andrew Gundersen 31b5e321a1 Add crimata-agent and redesign agentic OS UI
- crimata-agent (TypeScript, port 7702): WebSocket server + HTTP /events
  endpoint, Claude tool-use loop (render/remove/call_api/show_cursor_response),
  session.start fires on first browser connection to seed the canvas
- OS UI redesigned: light grey canvas (#e8e8e8), no dock bar, cursor dot,
  Cmd+Space input bubble above cursor, elements placed by agent
- Canvas elements: app_icon (floating icons with running dot), window (no-chrome
  content cards), cursor_response (text + action pills)
- Component system: HTML fragments fetched from /components/{app}/{name}.html,
  inline scripts re-executed after injection
- contacts/crimata.json: added icon, defaultComponent, components[], api[]
- dock: apps.h/c/main.c extended to parse and serve components + api from
  crimata.json; BUF_SIZE increased for richer JSON output
- ui/components/contacts/list.html + card.html: first component pair
- provision.sh: installs crimata-agent, adds WebSocket + /events + /components
  nginx locations, fixes /auth/ prefix stripping

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 15:52:05 -05:00

64 lines
1.8 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Crimata</title>
<link rel="stylesheet" href="styles/canvas.css" />
<link rel="stylesheet" href="styles/window.css" />
<link rel="stylesheet" href="styles/cursor.css" />
<link rel="stylesheet" href="styles/login.css" />
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
</head>
<body x-data="os" @keydown.window="handleKeydown" @mousemove.window="trackCursor">
<!-- Login overlay (shown until authenticated) -->
<div id="login-overlay" x-show="!authed" x-cloak>
<div class="login-card">
<h1>Crimata</h1>
<input
type="text"
x-model="loginUsername"
placeholder="Username"
@keydown.enter="$refs.loginPassword.focus()"
autocomplete="username"
/>
<input
type="password"
x-model="loginPassword"
placeholder="Password"
@keydown.enter="submitLogin"
x-ref="loginPassword"
autocomplete="current-password"
/>
<button @click="submitLogin">Sign in</button>
<div class="login-error" x-text="loginError"></div>
</div>
</div>
<!-- Infinite canvas — elements placed by the agent -->
<div id="canvas"></div>
<!-- Cursor dot -->
<div id="cursor-dot" x-show="authed" x-cloak></div>
<!-- Input bubble (Cmd+Space) — follows cursor -->
<div id="cursor-bubble"
x-show="inputMode"
x-cloak
:style="`left:${cursorX}px; top:${cursorY}px`"
>
<input
id="cursor-input"
type="text"
x-model="cursorQuery"
@keydown.enter="submitQuery"
@keydown.escape="exitInputMode"
placeholder="Ask anything…"
x-ref="cursorInput"
/>
</div>
<script src="js/os.js"></script>
</body>
</html>