kanade-client 0.43.68

End-user-facing Tauri Client App for the kanade endpoint-management system. Talks to the LocalSystem agent over the KLP Named Pipe (SPEC §2.12); presents a tray + window UI for notifications / health / self-service jobs.
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- Default product name; main.ts swaps both this and the header
         brand text to the operator-configured client_display_name once
         the agent handshake lands. Mirrors the Rust source of truth
         kanade_shared::DEFAULT_CLIENT_DISPLAY_NAME (and main.ts's
         DEFAULT_DISPLAY_NAME) — keep all in sync. -->
    <title>端末管理支援ツール</title>
    <link rel="stylesheet" href="/src/style.css" />
  </head>
  <body>
    <div id="app">
      <!-- Slim header: brand + a single connection status dot. No
           session / protocol / pc internals (operator-facing noise). -->
      <header class="app-header">
        <!-- Brand = タクト (baton) mark + the product name. The mark is
             the same baton-only geometry as the SPA's leftmost icon
             (no 奏 kanji). The name text defaults to the built-in
             product name and is replaced by main.ts with the
             operator-configured client_display_name after handshake. -->
        <div class="brand">
          <svg
            class="brand-mark"
            xmlns="http://www.w3.org/2000/svg"
            viewBox="40 30 180 140"
            role="img"
            aria-label="baton"
          >
            <defs>
              <linearGradient id="brand-baton" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0" stop-color="#5b3a8c" />
                <stop offset="0.5" stop-color="#d4a017" />
                <stop offset="1" stop-color="#2a9d8f" />
              </linearGradient>
            </defs>
            <path d="M 54 60 A 12 12 0 1 1 68 41 L 212 162 Z" fill="url(#brand-baton)" />
          </svg>
          <span class="brand-name">端末管理支援ツール</span>
        </div>
        <div class="conn conn-connecting" id="conn" title="エージェント接続状態">
          <span class="conn-dot"></span>
          <span class="conn-label">接続待ち</span>
        </div>
      </header>

      <div class="layout">
        <!-- Left sidebar nav. Home / Notifications / Health are fixed;
             the job categories below the divider are injected by main.ts
             from `jobs.list` (only categories that actually have jobs). -->
        <nav class="sidebar" id="sidebar">
          <button class="nav-item active" data-view="home">
            <i class="nav-icon" data-lucide="layout-dashboard"></i>
            <span class="nav-label">ホーム</span>
          </button>
          <button class="nav-item" data-view="notifications">
            <i class="nav-icon" data-lucide="bell"></i>
            <span class="nav-label">通知</span>
            <span class="nav-badge badge" id="nav-notif-badge" hidden></span>
          </button>
          <button class="nav-item" data-view="health">
            <i class="nav-icon" data-lucide="heart-pulse"></i>
            <span class="nav-label">端末ヘルス</span>
          </button>
          <div class="nav-sep" id="nav-jobs-sep" hidden></div>
          <!-- Category nav items injected here (data-view="jobs" data-category=…). -->
          <div id="nav-categories"></div>
          <!-- Client build version, dim at the sidebar foot (mirrors the SPA's
               /api/version badge). Filled by main.ts from the `app_version`
               command; shows the *running* binary's version. -->
          <div class="sidebar-version" id="app-version" title="クライアントのバージョン" hidden></div>
        </nav>

        <main class="content">
          <!-- Home / dashboard -->
          <section class="view" id="view-home">
            <h2 class="view-title">ホーム</h2>
            <div class="dash-cards">
              <button class="dash-card" data-view="health" id="card-health">
                <i class="dash-icon" data-lucide="heart-pulse"></i>
                <div class="dash-card-body">
                  <span class="dash-card-label">端末ヘルス</span>
                  <span class="dash-card-value" id="card-health-value">読み込み中…</span>
                </div>
              </button>
              <button class="dash-card" data-view="notifications" id="card-notif">
                <i class="dash-icon" data-lucide="bell"></i>
                <div class="dash-card-body">
                  <span class="dash-card-label">通知</span>
                  <span class="dash-card-value" id="card-notif-value"></span>
                </div>
              </button>
              <div class="dash-card dash-card-static" id="card-runs" hidden>
                <i class="dash-icon" data-lucide="loader"></i>
                <div class="dash-card-body">
                  <span class="dash-card-label">実行中のジョブ</span>
                  <span class="dash-card-value" id="card-runs-value"></span>
                </div>
              </div>
            </div>
          </section>

          <!-- Notifications -->
          <section class="view" id="view-notifications" hidden>
            <h2 class="view-title">
              通知 <span class="badge" id="notif-badge" hidden></span>
            </h2>
            <div id="notifications"></div>
          </section>

          <!-- Health (check: jobs) -->
          <section class="view" id="view-health" hidden>
            <h2 class="view-title">端末ヘルス</h2>
            <div id="health"><p class="muted">読み込み中…</p></div>
          </section>

          <!-- Jobs for the selected category (client: jobs). One view,
               re-rendered per selected category. -->
          <section class="view" id="view-jobs" hidden>
            <h2 class="view-title" id="jobs-view-title">ジョブ</h2>
            <div id="jobs-list"></div>
          </section>

          <!-- Persistent run status panel: shows live progress of any
               jobs.execute regardless of the active view. -->
          <section class="runs-panel" id="runs-section" hidden>
            <h2 class="view-title">実行状況</h2>
            <div id="runs"></div>
          </section>
        </main>
      </div>
    </div>

    <!-- All notifications surface as native OS toasts (#102/#635); there
         is no in-app toast container or blocking modal in the DOM. -->

    <script type="module" src="/src/main.ts"></script>
  </body>
</html>