varynth 0.1.1

Varynth local coding workspace with a TUI, secure tools, MCP, goals and an operator dashboard
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="color-scheme" content="dark">
  <meta name="description" content="Varynth local coding workspace with a TUI, secure tools, MCP, goals and an operator dashboard">
  <title>Varynth Control Room</title>
  <link rel="icon" href="/favicon.svg" type="image/svg+xml">
  <link rel="preload" href="/assets/geist-latin.woff2" as="font" type="font/woff2" crossorigin>
  <link rel="stylesheet" href="/assets/control-room.css">
  <script type="module" src="/assets/control-room.mjs"></script>
</head>
<body>
  <a class="skip-link" href="#workspace">Skip to workspace</a>
  <div class="shell">
    <header class="app-header">
      <a class="brand" href="/" aria-label="Varynth Control Room">
        <img src="/assets/mark.svg" alt="" width="30" height="30">
        <span>Varynth</span><span class="brand-surface">Control Room</span>
      </a>
      <div class="header-workspace"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#terminal"></use></svg><span id="workspace-path">Workspace</span></div>
      <div class="header-actions">
        <button class="icon-button mobile-sessions" id="sessions-toggle" type="button" aria-label="Open sessions" aria-controls="session-rail" aria-expanded="false" title="Sessions"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#panel-left"></use></svg></button>
        <button class="connection-button" id="connection-open" type="button" title="Connection settings"><span class="status-dot" id="connection-dot"></span><span id="connection-status">Connecting</span><svg class="icon small" aria-hidden="true"><use href="/assets/icons.svg#chevron-down"></use></svg></button>
        <button class="icon-button" id="inspector-toggle" type="button" aria-label="Toggle inspector" aria-controls="inspector" aria-expanded="true" title="Inspector"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#panel-right"></use></svg></button>
      </div>
    </header>

    <aside class="session-rail" id="session-rail" aria-label="Sessions">
      <div class="rail-heading"><h2>Sessions</h2><button class="icon-button drawer-close" id="sessions-close" aria-label="Close sessions" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#x"></use></svg></button></div>
      <button class="button new-session" id="new-session" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#plus"></use></svg>New session</button>
      <label class="search-box"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#search"></use></svg><input id="session-search" type="search" aria-label="Search sessions" placeholder="Search sessions" autocomplete="off"></label>
      <div class="session-list" id="sessions" aria-label="Saved sessions"><div class="quiet-empty">Loading sessions…</div></div>
      <footer class="rail-footer"><span class="status-dot good"></span><span>Local workspace</span><a class="icon-button" href="/diff" aria-label="Open diff viewer" title="Diff viewer"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#file-diff"></use></svg></a></footer>
    </aside>

    <main class="workspace" id="workspace" tabindex="-1">
      <div class="workspace-heading">
        <div class="session-identity"><h1 id="session-title">New session</h1><span id="session-subtitle">Loading workspace</span></div>
        <div class="workspace-controls"><span class="runtime-state" id="runtime-state">Idle</span><button class="icon-button" id="pause-session" type="button" aria-label="Pause session" title="Pause at the next model boundary" disabled><svg class="icon" aria-hidden="true"><use id="pause-icon" href="/assets/icons.svg#pause"></use></svg></button><button class="icon-button" id="context-open" type="button" aria-label="Edit session context" title="Edit context" disabled><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#braces"></use></svg></button><a class="icon-button" href="/diff" aria-label="View diff" title="Diff viewer"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#file-diff"></use></svg></a></div>
      </div>
      <div class="workspace-tabs" role="tablist" aria-label="Session views">
        <button id="tab-conversation" class="tab active" role="tab" aria-selected="true" aria-controls="conversation-panel" tabindex="0" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#message-square"></use></svg>Conversation</button>
        <button id="tab-activity" class="tab" role="tab" aria-selected="false" aria-controls="activity-panel" tabindex="-1" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#activity"></use></svg>Activity<span id="activity-count" class="count">0</span></button>
        <button id="tab-approvals" class="tab" role="tab" aria-selected="false" aria-controls="approvals-panel" tabindex="-1" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#shield-check"></use></svg>Approvals<span id="approval-count" class="count">0</span></button>
        <button id="tab-studio" class="tab" role="tab" aria-selected="false" aria-controls="studio-panel" tabindex="-1" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#settings-2"></use></svg>Studio</button>
      </div>
      <div class="inline-error" id="page-error" role="alert" hidden></div>
      <section class="conversation-panel content-panel" id="conversation-panel" role="tabpanel" aria-labelledby="tab-conversation">
        <div class="conversation" id="log" aria-label="Conversation">
          <div class="conversation-empty"><img src="/assets/mark.svg" alt="" width="44" height="44"><h2>New session</h2><p>No messages yet.</p></div>
        </div>
      </section>
      <section class="content-panel activity-panel" id="activity-panel" role="tabpanel" aria-labelledby="tab-activity" hidden>
        <div class="panel-toolbar"><h2>Live activity</h2><label class="compact-select">Show<select id="event-filter" aria-label="Filter activity"><option value="all">All events</option><option value="tools">Tools</option><option value="system">System</option><option value="errors">Errors</option></select></label><button class="icon-button" id="clear-events" type="button" aria-label="Clear activity view" title="Clear view"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#x"></use></svg></button></div>
        <div class="event-feed" id="events" aria-label="Live events"><div class="quiet-empty">No events yet.</div></div>
      </section>
      <section class="content-panel approvals-panel" id="approvals-panel" role="tabpanel" aria-labelledby="tab-approvals" hidden>
        <div class="panel-toolbar"><h2>Pending approvals</h2><span class="muted" id="approval-summary">No pending requests</span></div>
        <div id="approvals" class="approval-list"><div class="quiet-empty">No pending requests.</div></div>
      </section>
      <section class="content-panel studio-panel" id="studio-panel" role="tabpanel" aria-labelledby="tab-studio" hidden>
        <div class="studio-toolbar"><div><h2>Studio</h2><p>Configure the local runtime and theme.</p></div><button class="icon-button" id="studio-refresh" type="button" aria-label="Refresh Studio" title="Refresh Studio"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#refresh-cw"></use></svg></button></div>
        <div class="inline-error studio-error" id="studio-error" role="alert" hidden></div>
        <div class="studio-grid">
          <section class="studio-section"><div class="section-heading"><h3>Provider profile</h3><span class="state-label" id="studio-provider-state">Not loaded</span></div><dl class="data-list" id="studio-provider"><div><dt>Provider</dt><dd>—</dd></div><div><dt>Profile</dt><dd>—</dd></div><div><dt>Model</dt><dd>—</dd></div></dl><form class="studio-form" id="studio-provider-form"><label>Profile<select id="studio-profile-select" aria-label="Provider profile"><option value="">Current profile</option></select></label><div class="studio-form-grid"><label>Id<input id="studio-profile-id" type="text" autocomplete="off"></label><label>Kind<input id="studio-profile-kind" type="text" autocomplete="off"></label><label>Base URL<input id="studio-profile-base-url" type="url" autocomplete="off"></label><label>Model<input id="studio-profile-model" type="text" autocomplete="off"></label><label>API key env<input id="studio-profile-api-key-env" type="text" autocomplete="off"></label><label>Auth<input id="studio-profile-auth" type="text" autocomplete="off"></label><label>Project<input id="studio-profile-project" type="text" autocomplete="off"></label><label>Location<input id="studio-profile-location" type="text" autocomplete="off"></label></div><button class="button subtle" type="submit">Save profile</button><div class="inline-error form-error" id="studio-provider-error" role="alert" hidden></div></form></section>
          <section class="studio-section"><div class="section-heading"><h3>MCP servers</h3><span class="muted" id="studio-mcp-count">0</span></div><div class="studio-list" id="studio-mcp"><div class="quiet-empty">No MCP servers returned.</div></div><form class="studio-form" id="studio-mcp-form"><div class="studio-form-grid studio-form-grid-compact"><label>Id<input id="studio-mcp-id" type="text" autocomplete="off" required></label><label>HTTP URL<input id="studio-mcp-url" type="url" autocomplete="off" required></label></div><button class="button subtle" type="submit">Add HTTP server</button><div class="inline-error form-error" id="studio-mcp-error" role="alert" hidden></div></form></section>
          <section class="studio-section"><div class="section-heading"><h3>Installed skills</h3><span class="muted" id="studio-skill-count">0</span></div><div class="studio-chip-list" id="studio-skills"><span class="muted">No installed skills returned.</span></div><form class="studio-form" id="studio-skill-form"><label>Source<textarea id="studio-skill-source" rows="3" spellcheck="false" placeholder="SKILL.md or github.com/owner/repo"></textarea></label><button class="button subtle" type="submit">Install skill</button><div class="inline-error form-error" id="studio-skill-error" role="alert" hidden></div></form></section>
          <section class="studio-section"><div class="section-heading"><h3>Curated plugins</h3><span class="muted" id="studio-plugin-count">0</span></div><div class="studio-list" id="studio-plugins"><div class="quiet-empty">No curated plugins returned.</div></div></section>
          <section class="studio-section theme-section"><div class="section-heading"><div><h3>Theme tokens</h3><p class="section-note">Paste JSON or CSS custom properties.</p></div><span class="state-label" id="theme-state">Not loaded</span></div><textarea id="theme-input" class="theme-input" rows="9" spellcheck="false" aria-label="Theme tokens" placeholder='{"background":"oklch(0.15 0.02 260)","radius":"6px"}'></textarea><div class="theme-actions"><label class="button subtle theme-file-label" for="theme-file"><svg class="icon small" aria-hidden="true"><use href="/assets/icons.svg#arrow-up"></use></svg>Upload theme<input id="theme-file" type="file" accept=".json,.css,application/json,text/css" hidden></label><button class="button subtle" id="theme-load" type="button">Reload</button><button class="button subtle" id="theme-apply" type="button">Apply</button><button class="button primary" id="theme-save" type="button">Save theme</button><button class="icon-button" id="theme-export" type="button" aria-label="Export theme" title="Export theme"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#arrow-up"></use></svg></button></div><div class="inline-error" id="theme-error" role="alert" hidden></div><a class="tweakcn-link" href="https://tweakcn.com/editor/theme" target="_blank" rel="noreferrer">Open tweakcn editor <svg class="icon small" aria-hidden="true"><use href="/assets/icons.svg#arrow-up"></use></svg></a></section>
        </div>
      </section>
      <form class="composer" id="form">
        <div class="composer-field" id="composer-dropzone"><label class="sr-only" for="input">Message</label><textarea id="input" rows="3" placeholder="What are we working on?" spellcheck="false"></textarea><div class="attachment-chips" id="attachment-chips" aria-live="polite"></div></div>
        <div class="composer-toolbar"><label class="composer-model"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#layers"></use></svg><span class="sr-only">Model</span><select id="model" aria-label="Model"><option value="">Loading models…</option></select></label><label id="attachment-picker" class="icon-button attachment-picker" for="attachment-input" aria-label="Attach image" title="Attach image"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#plus"></use></svg></label><input id="attachment-input" type="file" accept="image/*" multiple hidden><span class="composer-status" id="composer-status">Ready</span><button class="button primary send" id="send" type="submit" disabled><span>Send</span><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#arrow-up"></use></svg></button></div>
      </form>
    </main>

    <aside class="inspector" id="inspector" aria-label="Runtime inspector">
      <div class="inspector-heading"><h2>Inspector</h2><button class="icon-button" id="inspector-close" type="button" aria-label="Close inspector" title="Close inspector"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#x"></use></svg></button></div>
      <section class="inspector-section"><h3>Runtime</h3><dl class="data-list" id="runtime-data"><div><dt>Provider</dt><dd>Not connected</dd></div></dl></section>
      <section class="inspector-section"><div class="section-heading"><h3>Token usage</h3><span class="state-label" id="usage-source">Not reported</span></div><dl class="data-list usage-list"><div><dt>Input</dt><dd id="usage-input">—</dd></div><div><dt>Output</dt><dd id="usage-output">—</dd></div><div><dt>Total</dt><dd id="usage-total">—</dd></div></dl><div class="context-label"><span>Context estimate</span><span id="context-estimate">—</span></div></section>
      <section class="inspector-section" id="goal-section" hidden><div class="section-heading"><h3>Goal</h3><span class="state-label" id="goal-status"></span></div><p class="goal-condition" id="goal-text"></p><div class="goal-meta" id="goal-meta"></div><p class="goal-verdict" id="goal-verdict" hidden></p></section>
      <section class="inspector-section"><div class="section-heading"><h3>Skills</h3><span class="muted" id="skill-count">0</span></div><div class="skill-list" id="skills"><span class="muted">No skills loaded</span></div></section>
      <section class="inspector-section"><div class="section-heading"><h3>Health checks</h3><button class="icon-button" id="check-health" type="button" aria-label="Run health checks" title="Run checks"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#refresh-cw"></use></svg></button></div><div class="health-list" id="doctor"><span class="muted">Not checked</span></div></section>
      <section class="inspector-section"><div class="section-heading"><h3>Gateway</h3><span class="state-label" id="gateway-label">Offline</span></div><div class="gateway-actions"><button class="button subtle" id="gateway-connect" type="button"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#wifi"></use></svg><span>Connect</span></button><button class="icon-button" id="gateway-ping" type="button" aria-label="Ping gateway" title="Ping gateway" disabled><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#radio"></use></svg></button><button class="icon-button" id="gateway-status" type="button" aria-label="Refresh runtime status" title="Refresh status"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#refresh-cw"></use></svg></button></div><div class="gateway-latency" id="gateway-latency">—</div></section>
      <section class="inspector-section"><div class="section-heading"><h3>Channels</h3></div><dl class="data-list" id="channels"><div><dt>Dashboard</dt><dd>Local</dd></div></dl></section>
    </aside>
  </div>
  <button class="drawer-backdrop" id="drawer-backdrop" type="button" aria-label="Close side panel" hidden></button>
  <dialog class="settings-dialog" id="connection-dialog" aria-labelledby="connection-title">
    <form id="connection-form"><div class="dialog-heading"><h2 id="connection-title">Connection</h2><button class="icon-button" id="connection-close" type="button" aria-label="Close connection settings"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#x"></use></svg></button></div><label class="form-field">Dashboard token<input id="gateway-token" type="password" placeholder="Dashboard token" autocomplete="off" spellcheck="false"></label><p class="form-note">Kept in this page only.</p><div id="connection-error" class="inline-error" role="alert" hidden></div><div class="dialog-actions"><button class="button subtle" id="clear-token" type="button">Clear token</button><button class="button primary" type="submit">Connect</button></div></form>
  </dialog>
  <dialog class="context-dialog" id="context-dialog" aria-labelledby="context-title"><form id="context-form"><div class="dialog-heading"><h2 id="context-title">Session context</h2><button class="icon-button" id="context-close" type="button" aria-label="Close context editor"><svg class="icon" aria-hidden="true"><use href="/assets/icons.svg#x"></use></svg></button></div><label class="form-field">Text messages<textarea id="context-input" rows="14" spellcheck="false"></textarea></label><p class="form-note">Text-only context. Applied at the next turn.</p><div class="inline-error" id="context-error" role="alert" hidden></div><div class="dialog-actions"><button class="button subtle" id="context-cancel" type="button">Cancel</button><button class="button primary" id="context-save" type="submit">Replace context</button></div></form></dialog>
  <div class="toast" id="toast" role="status" aria-live="polite" hidden></div>
</body>
</html>