A runnable, self-hosted web interface so the whole workflow can be tested end to end: record or upload audio in the browser, watch it transcribe and summarise, browse a library, play back, and export. What changed: - server/app/store.py: SQLite + on-disk audio storage for recordings (stdlib only). - server/app/pipeline.py: background task audio -> transcribe -> summarise via the existing provider layer, updating status (queued/transcribing/summarising/done/error). - server/app/main.py: web API - POST upload, list, detail, audio (Range), delete, and export (txt/md/srt/vtt/json) - and serves the SPA at /. - server/app/web/: Plaud-style single-page UI (index.html, styles.css, app.js). Sidebar library, in-browser recording (MediaRecorder) + file upload, live status polling, audio player, summary (overview/key points/actions), timestamped transcript, exports. - server/Dockerfile + README: two-minute run instructions (default provider: Groq free tier for both Whisper + LLM), and a Docker option. - config: env prefix switched OPENSCRIBE_ -> NIGHTJAR_ to match the brand and the site tutorials; .env.example rewritten with a ready Groq quick-start. - state/TODO: web app recorded as done. Why: - User asked for a Plaud-like web interface to test how it all works. Nothing testable existed before (marketing site is a brochure; pipeline was unwired). This delivers a real, runnable product demo and effectively lands M5/M6 for the HTTP providers. Notes: - Slim by design: AI is offloaded to the configured provider, so no local ML deps needed for the demo. Byte-compiles clean; JS passes node --check. Local faster-whisper still needs its model (M5) for the fully-offline path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
38 lines
1.2 KiB
HTML
38 lines
1.2 KiB
HTML
<!doctype html>
|
|
<!-- SPDX-License-Identifier: GPL-3.0-only -->
|
|
<html lang="en-GB">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Nightjar</title>
|
|
<link rel="stylesheet" href="/styles.css" />
|
|
</head>
|
|
<body>
|
|
<header class="topbar">
|
|
<div class="brand"><span class="dot"></span> Nightjar</div>
|
|
<div class="providers" id="providers" title="Configured AI providers"></div>
|
|
</header>
|
|
|
|
<main class="layout">
|
|
<aside class="sidebar">
|
|
<div class="actions">
|
|
<button id="recBtn" class="btn primary">● Record</button>
|
|
<label class="btn" for="upload">Upload</label>
|
|
<input id="upload" type="file" accept="audio/*" hidden />
|
|
</div>
|
|
<div id="recTimer" class="rec-timer" hidden>00:00 · recording…</div>
|
|
<ul id="list" class="list"></ul>
|
|
</aside>
|
|
|
|
<section class="detail" id="detail">
|
|
<div class="empty">
|
|
<h2>Record or upload audio</h2>
|
|
<p>Nightjar transcribes it and writes a summary using the AI you configured. Your
|
|
recordings appear on the left.</p>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<script src="/app.js"></script>
|
|
</body>
|
|
</html>
|