diff --git a/docs/hosted-service.md b/docs/hosted-service.md deleted file mode 100644 index 097bd63..0000000 --- a/docs/hosted-service.md +++ /dev/null @@ -1,43 +0,0 @@ - -# Nightjar hosted service (commercial) - -How 12 Hobbies Studio commercialises the open-source project: a managed backend so people -can use Nightjar without self-hosting. The device and app stay open; the studio runs the -transcription, summaries, storage and API. - -Status: **marketing site live, service in preparation.** No billing/signup yet; the site -captures leads (register interest). Pricing below is **indicative**. - -## Plan lineup (live on the site) - -| Plan | Price (indicative) | AI backend | Notes | -|------|--------------------|-----------|-------| -| **Self-host** | Free, forever | your own | full source + docs, community support | -| **Cloud Starter** | from GBP 6/mo | commercial API | 10 hrs audio/mo, 10 GB, email support | -| **Cloud Pro** | from GBP 18/mo | commercial API | 40 hrs/mo, priority, 100 GB, team sharing | -| **Private** | from GBP 39/mo | self-hosted open models | audio never touches a 3rd-party AI; DPA | - -The Cloud tiers use best-in-class commercial AI (cheap per-minute, good margin). The -Private tier processes everything on our own hardware (see `docs/infrastructure.md`) for a -privacy / sovereignty guarantee. All hosted data kept in the EU/UK. - -## Placeholders to confirm before launch - -- **Contact mailbox:** the site's forms/CTAs use `hello@12hobbies.studio` - create that - mailbox or change it. -- **Real pricing + quotas:** the numbers above are indicative. -- **Trademark clearance** for "Nightjar" (see `docs/naming.md`). - -## Roadmap to actually sell it (not built yet) - -- Metering (hours of audio, storage) per account. -- Signup + billing (e.g. Stripe) wired to plan entitlements. -- Provisioning: create a tenant, route jobs to the right backend (commercial vs Private - node), enforce quotas. -- Provision the backend infra (`docs/infrastructure.md`) at first beta / paying users. -- Data-processing agreement + retention policy for the Private tier. - -## Marketing site - -Built in WordPress on ApisCP (`howler.qsplace.co.uk`), served at -`nightjar.12hobbies.studio`. Reproducible content and build notes are in `site/`. diff --git a/docs/infrastructure.md b/docs/infrastructure.md deleted file mode 100644 index c3cd4ef..0000000 --- a/docs/infrastructure.md +++ /dev/null @@ -1,103 +0,0 @@ - -# Nightjar hosted backend - infrastructure plan - -Plan for the infrastructure that runs the **hosted** Nightjar service (the commercial -plans). The open-source project itself does not require any of this; self-hosters run -their own. This is for 12 Hobbies Studio to operate the managed service. - -Status: **plan only, not provisioned** (decided 2026-07). Stand it up at first beta / -paying users. See `docs/hosted-service.md` for the plan tiers this maps to. - -## Two backends, matching the two plan families - -| Plan family | AI runs on | Infra | -|-------------|-----------|-------| -| **Cloud Starter / Pro** | commercial API (Groq / OpenAI / Anthropic) | small orchestration node; heavy compute offloaded | -| **Private** | self-hosted open models (faster-whisper + local LLM) | a GPU node; audio never leaves our hardware | - -Cloud tiers are cheap to run (compute is per-minute on a commercial provider, keeping the -GBP 6 / 18 pricing profitable). The Private tier needs real hardware but is the privacy / -sovereignty story. - -## Primary option: self-host on the MS-02 cluster (best for small scale) - -Hardware on hand: **3x Minisforum MS-02-class mini-workstations**, one fitted with an -**NVIDIA RTX 3050 6GB**. High-core CPUs, dual 10GbE, NVMe, PCIe GPU slot. This is a strong -small-scale backend and a better fit for the Private tier than rented cloud. - -### Node roles - -- **Node A (RTX 3050) - AI worker.** faster-whisper on the GPU + a local LLM (Ollama) for - summaries. This is the Private-tier engine; models run on our own hardware. -- **Node B - app tier.** FastAPI ingest + open API, Postgres (accounts, metadata, - billing), Redis queue, reverse proxy. -- **Node C - storage + overflow.** MinIO (S3-compatible object storage for audio), a CPU - transcription worker for extra throughput, backups, and HA spare. - -Dual 10GbE makes shared storage and job distribution between the three effortless. Run -Docker Compose per node, or k3s / Docker Swarm across all three for failover. - -### The RTX 3050 6GB in practice - -- **Transcription: excellent.** faster-whisper (CTranslate2, int8) runs whisper - medium/large-v3 within 6GB and several times faster than real-time - hundreds of hours - of audio per day on one GPU. Far beyond small-scale need. -- **Summaries: fine with 7-8B models.** A quantised 8B model (Llama 3.1 8B, Qwen2.5 7B, - Mistral 7B at Q4) fits in 6GB and writes good summaries in seconds. 13B+ will not fit in - VRAM; for bigger, use CPU (slower) or add a larger GPU later. Not needed for summaries. - -So the single 3050 covers both AI jobs the Private tier needs. Cloud tiers barely touch -this hardware (orchestration + storage only). - -### Getting to it from the internet: Cloudflare Tunnel - -Do not expose the home/office IP or open ports. We are already on Cloudflare - run a -**Cloudflare Tunnel**: the nodes make an outbound connection and `api.nightjar...` is served -through Cloudflare with TLS and DDoS protection, no inbound ports, no static IP. Free. - -### Caveats of self-hosting a paid service - -- **Uptime / power / bandwidth.** Fine for beta / early customers. Add a UPS, decent - upload bandwidth, tunnel resilience. For SLA-bound customers later, consider colo or a - hybrid. -- **Backups.** NVMe fails. Keep offsite backups of Postgres + audio (cheap cloud object - storage target). -- **Data residency.** On our own UK premises - a strong Private-tier pitch ("processed on - our own hardware in the UK, never sent to a third-party AI"). Mind UK GDPR obligations. -- **When we outgrow it.** Many concurrent Private customers, or wanting large LLMs - add - VRAM / a second GPU, or a cloud GPU node. - -## Fallback / alternative option: cloud VMs (Hetzner) - -If self-hosting uptime is a concern, or to launch before the cluster is ready: - -- **Phase 1 (Cloud tiers):** one small Hetzner VM (CPX31, 4 vCPU / 8 GB, ~EUR 15/mo, EU - region for GDPR). Docker Compose: FastAPI + workers + Redis + Postgres + Caddy/LE. - Object storage via Hetzner Object Storage (~EUR 5/mo). AI offloaded to a commercial API. - All-in ~EUR 20-30/mo. -- **Phase 2 (Private tier):** a CPU-optimised (CCX23/33, ~EUR 30-60/mo) or GPU VM for - self-hosted whisper + LLM. Priced into the Private tier. - -A hybrid also works: MS-02 cluster does the compute; a tiny cloud VM (or just the -Cloudflare Tunnel) is the public front door. - -## Architecture (both options) - -``` -device --sync--> ingest API --> queue --> transcription worker --> summary (LLM) - | (GPU or commercial) (local or commercial) - v - Postgres (metadata/accounts) object storage (audio + artefacts) - | - open REST API + exports <-- app / customers -``` - -## Provisioning checklist (when ready) - -- [ ] Decide compute home: MS-02 cluster (primary) vs cloud (fallback) vs hybrid. -- [ ] Cloudflare Tunnel for `api.nightjar...` (if self-hosting). -- [ ] Docker Compose (or k3s): FastAPI, workers, Redis, Postgres, MinIO/Object Storage. -- [ ] GPU node: faster-whisper (CUDA) + Ollama (7-8B) for the Private tier. -- [ ] Backups (Postgres + audio) offsite; UPS on the nodes. -- [ ] Metering + billing hookup for the plans (see `docs/hosted-service.md`). -- [ ] Data-processing agreement + retention policy (Private tier). diff --git a/docs/naming.md b/docs/naming.md deleted file mode 100644 index 745ad2d..0000000 --- a/docs/naming.md +++ /dev/null @@ -1,52 +0,0 @@ - -# Naming and branding - -Record of the naming due-diligence and the decision to brand the product **Nightjar**. - -Reviewed July 2026. - -## Decision - -- **Product / commercial brand: Nightjar.** The site is live at - `https://nightjar.12hobbies.studio`. -- **The repository is still named `openscribe`** for now. Renaming the whole codebase - (repo, SPDX headers, firmware namespaces, docs) is a separate, larger task - deferred - until decided. "OpenScribe" survives only as the original project name in code history. - -## Why not "OpenScribe" - -"OpenScribe" failed a due-diligence screen for a commercial brand: - -- **Domains:** every desirable exact-match is taken. `openscribe.com` (parked, for sale - since 2009), `openscribe.ai` (parked, for sale), `.net/.org/.app/.dev` registered, - `.org` is an active dictation product, `.io`/`.co` host live sites. -- **GitHub:** 33 repos match "openscribe", several in the same category (an AI medical - scribe at ~188 stars, dictation apps, transcription tools). Heavy in-category collision. -- **Trademark:** descriptive ("Open" + "Scribe"), so weak/hard to register, and there is - at least one live commercial product on the exact name in the same class. Not cleared. - -## Why "Nightjar" - -- A nightjar is a bird with a famously distinctive call - evocative, memorable, and it - does **not** collide inside the AI/voice/transcription category (the trap OpenScribe hit). -- GitHub name collisions: ~104 (vs 5,000+ for the coined alternative "Recita", and far - lower than dictionary words like murmur/cadence/quill). -- As a bird name applied to AI software it is an **arbitrary mark** - a strong, defensible - trademark position (unrelated to the goods). - -## Names screened and rejected - -- **Mockingjay** - Hunger Games / Lionsgate trademark, aggressively enforced. Hard avoid. -- **Lyrebird, Fathom** - already established voice-AI / AI-notetaker brands (in-category - traps like OpenScribe). -- **Murmur, Cadence, Quill, Cairn, Keepsake** - dictionary words: taken domains + heavy - GitHub collisions. -- **Recita** - coined but turns out common (Italian word), ~5,000 GitHub matches. - -## Caveats / follow-ups - -- Every short name has its exact-match `.com` squatted; Nightjar is no exception. Domain - routes: `getnightjar.com` / a modern TLD if free at a registrar / the studio subdomain - (current: `nightjar.12hobbies.studio`). -- A **formal trademark clearance** (USPTO / UK IPO / EUIPO, ideally via an IP attorney) is - the last step before spending on the brand. This screen is not a legal clearance. diff --git a/site/README.md b/site/README.md deleted file mode 100644 index 4acadd5..0000000 --- a/site/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Nightjar marketing site - -The content and tooling for the public marketing site at -**https://nightjar.12hobbies.studio** (the commercial front for the project; see -`../docs/hosted-service.md`). - -The live site is **WordPress on ApisCP** (`howler.qsplace.co.uk`, EU/Hetzner), on the -`12hobbies` account as a subdomain. This directory is the reproducible source: the page -content, navigation, contact-form config, and the tooling used to push it all through the -ApisCP API. - -## Layout - -``` -pages/ Block-editor content for each page (one file per page) - home.html front page (landing) - how-it-works.html workflow + architecture diagrams (inline SVG) + detailed steps - bring-your-own-ai.html - guides.html hub linking the three tutorials - connect-your-ai.html tutorial: per-provider .env config - self-host-the-server.html tutorial: install -> configure -> run - build-the-device.html tutorial: parts, flashing, case (+ device illustration) - open-source.html hosted-plans.html about.html contact.html - _navigation.html the header navigation (wp_navigation block content) -cf7-form-config.php Contact Form 7 form template + mail config (honeypot spam protection) -tools/apiscp.php SOAP helper that drives ApisCP / wp-cli remotely (see below) -``` - -Images are **inline SVG** inside Custom HTML blocks (no uploads, no SVG-upload security -concerns; the device illustration has an animated status light). - -## How the site is managed - -WordPress is driven remotely through the ApisCP SOAP API via `tools/apiscp.php`, which -exposes `wordpress_cli` (wp-cli) and file operations. Page content is pushed to a temp -file on the server and applied with `wp post update ` (avoids command-length -and quoting limits). Example: - -``` -php -d extension=openssl -d extension=soap tools/apiscp.php \ - file_put_file_contents /var/www//.tmp.html '@@pages/home.html' true false -php -d extension=openssl -d extension=soap tools/apiscp.php \ - wordpress_cli 'post update /var/www//.tmp.html' '[]' nightjar.12hobbies.studio '' -``` - -### Secrets - -`tools/apiscp.php` reads the ApisCP API key from a local scratch file -(`C:/temp/claudetemp/apiscp.key`) that is **never committed**. Supply the key out-of-band -and keep it out of the repo. The `.gitignore` already excludes secrets. - -## Site facts - -- Comments are disabled site-wide (Disable Comments plugin + closed defaults). -- The contact form is Contact Form 7 with a hidden **honeypot** field for spam protection; - every submission is also stored in the database via Flamingo. -- TLS is Let's Encrypt (valid cert for `nightjar.12hobbies.studio`). The old - `openscribe.12hobbies.studio` host redirects here. diff --git a/site/cf7-form-config.php b/site/cf7-form-config.php deleted file mode 100644 index 72f69d7..0000000 --- a/site/cf7-form-config.php +++ /dev/null @@ -1,29 +0,0 @@ -get_properties(); - -$p['form'] = implode("\n", array( - '

Your name
[text* your-name autocomplete:name]

', - '

Your email
[email* your-email autocomplete:email]

', - '

I am interested in
[select interest "Hosted plans" "Early access to the code" "Building a device" "Something else"]

', - '

Message
[textarea* your-message]

', - '[honeypot website-hp id:website-hp nomessage:true]', - '

[submit "Send message"]

', -)); - -$p['mail']['recipient'] = 'hello@12hobbies.studio'; -$p['mail']['sender'] = 'Nightjar '; -$p['mail']['subject'] = 'Nightjar enquiry from [your-name]'; -$p['mail']['additional_headers'] = 'Reply-To: [your-email]'; -$p['mail']['body'] = "Name: [your-name]\nEmail: [your-email]\nInterested in: [interest]\n\nMessage:\n[your-message]\n\n-- Sent from nightjar.12hobbies.studio"; - -$cf->set_properties($p); -$cf->save(); - -echo $cf->shortcode() . "\n"; diff --git a/site/pages/_navigation.html b/site/pages/_navigation.html deleted file mode 100644 index 636572e..0000000 --- a/site/pages/_navigation.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/site/pages/about.html b/site/pages/about.html deleted file mode 100644 index 757aa9a..0000000 --- a/site/pages/about.html +++ /dev/null @@ -1 +0,0 @@ -

About

Nightjar is a project by 12 Hobbies Studio, a maker studio that builds open, self-hostable tools.

12 Hobbies Studio makes small, open-source projects across hardware and software. The through-line is simple: build in the open, keep the data with the person who made it, and let anyone reproduce the whole thing from the repository alone. Firmware and software are copyleft, hardware is open-hardware licensed, and documentation is share-alike.

Nightjar is the studio flagship: an AI voice recorder that gives you the convenience people expect from a commercial device, without giving up ownership of your hardware, your recordings, or your choice of AI. The hosted plans exist so the studio can sustainably maintain and grow the open project while offering a managed option to anyone who wants it.

Get in touch

Questions, ideas, or interest in a hosted plan or early access to the code? We would love to hear from you.

Nightjar is an independent open-source project inspired by the Plaud class of device. It is not affiliated with, endorsed by, or derived from Plaud.

diff --git a/site/pages/bring-your-own-ai.html b/site/pages/bring-your-own-ai.html deleted file mode 100644 index 8f7a63f..0000000 --- a/site/pages/bring-your-own-ai.html +++ /dev/null @@ -1 +0,0 @@ -

Bring your own AI

This is the difference. A commercial recorder locks you to its cloud. Nightjar lets you point transcription and summaries at whatever you want.

Transcription and summarisation each target a provider you choose in configuration. Use a fully local model for maximum privacy, an open-standard endpoint, or a commercial API for the best quality. There is no lock-in, and you can switch at any time. Self-hosted or not, it is your choice and your data.

Language and summaries

  • OpenAI, or any OpenAI-compatible endpoint
  • Anthropic Claude
  • Groq for fast, low-cost inference
  • Local models via Ollama or LM Studio, fully offline
  • Gemini through its OpenAI-compatible endpoint

Transcription

  • faster-whisper, self-hosted, running on your own machine
  • Any OpenAI-compatible audio endpoint, such as OpenAI Whisper or Groq
  • Your own whisper server

How it is configured

Each provider is a few lines of configuration on the server: a provider name, a base URL, an API key and a model. Almost every provider speaks the same OpenAI-compatible protocol, so a single setting covers most of the ecosystem. Anthropic Claude has its own dedicated integration. Pick a provider, drop in the details, and Nightjar does the rest.

diff --git a/site/pages/build-the-device.html b/site/pages/build-the-device.html deleted file mode 100644 index aca1c95..0000000 --- a/site/pages/build-the-device.html +++ /dev/null @@ -1,26 +0,0 @@ -

Build the device

The Nightjar recorder is built from off-the-shelf parts and a printed case. No custom circuit board required. Here is what goes into one.

- -
- - - - - - - - - - - NIGHTJAR - - - -
- -

The parts

  • An ESP32-S3 board with PSRAM. This is the brain: it has WiFi, Bluetooth and enough memory to buffer audio. A compact board with an onboard microphone and card slot keeps the whole thing tiny.
  • A microphone. A digital I2S MEMS microphone for clean, low-noise audio.
  • A microSD card. Where recordings are written. 16 to 32 GB is plenty.
  • A small LiPo battery and a charging circuit, so it runs off the mains or on the go.
  • A button and a status light for control and feedback.

A full bill of materials with exact parts and wiring ships with the project. Indicative cost is under thirty pounds, plus a printed case.

-

Step 1: Flash the firmware

The firmware is built with PlatformIO. Connect the board over USB and flash it.

cd nightjar/firmware
-pio run -t upload
-pio device monitor

The serial monitor confirms the board booted, found its microphone and card, and is ready to record.

-

Step 2: Print the case

The enclosure is a parametric model you can print in a couple of hours. Because it is parametric, you can re-tune it to the exact board and battery you chose, then print the two halves and snap them together around the electronics.

-

Step 3: Provision and record

Open the app, connect to the device over Bluetooth, and give it your WiFi details and your server address. Press the button to record. Put it on charge, and it uploads on its own. That is the whole loop.

-

Want the software side first? See self-host the server and connect your AI. Or skip the build entirely with a hosted plan.

diff --git a/site/pages/connect-your-ai.html b/site/pages/connect-your-ai.html deleted file mode 100644 index 3cd0f51..0000000 --- a/site/pages/connect-your-ai.html +++ /dev/null @@ -1,24 +0,0 @@ -

Connect your AI

Nightjar does not hard-wire a single AI vendor. Transcription and summaries each target a provider you choose in the server config. This guide shows the exact settings for each.

-

All settings live in the server’s .env file. Change them, restart the server, and the new provider is live. Nothing else needs to change on the device or in the app.

-

Summaries and chat (the language model)

Set LLM_PROVIDER to one of ollama, openai_compatible, or anthropic.

-

Fully local (Ollama)

The default. Everything stays on your machine, no API key, no cloud. Install Ollama, pull a model, and point Nightjar at it.

NIGHTJAR_LLM_PROVIDER=ollama
-NIGHTJAR_OLLAMA_URL=http://localhost:11434
-NIGHTJAR_OLLAMA_MODEL=llama3.1
-

OpenAI, or anything OpenAI-compatible

One setting covers OpenAI, Groq, OpenRouter, Together, LocalAI, vLLM, LM Studio, and Gemini’s OpenAI-compatible endpoint. Just change the base URL and model.

NIGHTJAR_LLM_PROVIDER=openai_compatible
-NIGHTJAR_LLM_BASE_URL=https://api.openai.com/v1
-NIGHTJAR_LLM_API_KEY=sk-...
-NIGHTJAR_LLM_MODEL=gpt-4o-mini

For Groq (fast and cheap), use https://api.groq.com/openai/v1. For a local model server on your LAN such as LM Studio, use http://localhost:1234/v1.

-

Anthropic Claude

Claude uses its own integration.

NIGHTJAR_LLM_PROVIDER=anthropic
-NIGHTJAR_LLM_API_KEY=sk-ant-...
-NIGHTJAR_LLM_MODEL=claude-opus-4-8
-

Transcription (speech to text)

Set TRANSCRIPTION_PROVIDER to local_whisper (self-hosted) or openai_compatible.

-

Local, self-hosted (faster-whisper)

NIGHTJAR_TRANSCRIPTION_PROVIDER=local_whisper
-NIGHTJAR_WHISPER_MODEL=base
-NIGHTJAR_WHISPER_DEVICE=cpu
-NIGHTJAR_WHISPER_COMPUTE_TYPE=int8

Larger models (small, medium, large-v3) are more accurate but slower. Set DEVICE=cuda if you have a GPU.

-

A hosted transcription API

NIGHTJAR_TRANSCRIPTION_PROVIDER=openai_compatible
-NIGHTJAR_TRANSCRIPTION_BASE_URL=https://api.openai.com/v1
-NIGHTJAR_TRANSCRIPTION_API_KEY=sk-...
-NIGHTJAR_TRANSCRIPTION_MODEL=whisper-1
-

Which should I choose?

  • Maximum privacy, zero cost per minute: local Whisper + a local Ollama model. Nothing leaves your machine.
  • Best quality, least setup: a commercial API for both. You pay per use, and accuracy is top-tier.
  • A balance: local transcription for privacy, a commercial model for the summary polish.
-

Not sure, or would rather not manage any of this? Our hosted plans run it all for you.

diff --git a/site/pages/contact.html b/site/pages/contact.html deleted file mode 100644 index d7bf1a3..0000000 --- a/site/pages/contact.html +++ /dev/null @@ -1 +0,0 @@ -

Contact

Register your interest in a hosted plan, or ask to be notified when the open-source code is released.

Tell us a little about what you are after. If it is a hosted plan, a rough idea of how many hours of audio you record per month helps us follow up with early-access pricing. We read every message.

[contact-form-7 id="55b5907" title="Contact form 1"]

Built by 12 Hobbies Studio. Nightjar is an independent open-source project and is not affiliated with Plaud.

diff --git a/site/pages/guides.html b/site/pages/guides.html deleted file mode 100644 index 0565885..0000000 --- a/site/pages/guides.html +++ /dev/null @@ -1,7 +0,0 @@ -

Guides

Everything you need to run Nightjar yourself: connect an AI provider, stand up the server, and build the device. Start anywhere.

-
-

Connect your AI

Point transcription and summaries at a local model, an open-standard endpoint, or a commercial API. Copy-paste config for each.

Read the guide →

-

Self-host the server

Stand up the Nightjar backend on your own machine or a small cloud box, from install to first transcript.

Read the guide →

-

Build the device

The parts, the firmware, and the printed case. From a bag of components to your first recording.

Read the guide →

-
-

New here? Start with How Nightjar works for the big picture, or if you would rather skip the setup entirely, see hosted plans.

diff --git a/site/pages/home.html b/site/pages/home.html deleted file mode 100644 index adc824b..0000000 --- a/site/pages/home.html +++ /dev/null @@ -1 +0,0 @@ -

Nightjar

An open-source, self-hosted AI voice recorder. Record on a small device, sync to your own server, and turn conversations into transcripts and summaries with any AI you choose. Own the hardware, own the data, own the workflow.


An AI note-taker you actually own

Nightjar is a pocket voice recorder in the spirit of the AI note-takers you have seen, rebuilt as open hardware and open software. A small ESP32-S3 device records to a memory card at the press of a button. Recordings sync to a mobile app and to a server you control, where they become searchable transcripts and structured summaries. No sealed box, no mandatory cloud, no per-minute bill.

Record

One button captures audio to a memory card. Sync over Bluetooth, WiFi, or automatic upload when on charge.

Understand

Your server transcribes and summarises each recording, with the AI provider you chose: local, open, or commercial.

Own it

Audio, transcripts and summaries live on your storage. A completely open API means nothing is locked away.


Explore

Nightjar is an independent open-source project inspired by the Plaud class of device. It is not affiliated with, endorsed by, or derived from Plaud. Built by 12 Hobbies Studio.

diff --git a/site/pages/hosted-plans.html b/site/pages/hosted-plans.html deleted file mode 100644 index 9bb5ca2..0000000 --- a/site/pages/hosted-plans.html +++ /dev/null @@ -1,9 +0,0 @@ -

Hosted plans

Nightjar is free to self-host. If you would rather not run a server, let 12 Hobbies Studio run the backend for you — with a plan to match how private you want it.

-

You always keep the open device and the open app. The difference between the cloud plans is where the AI runs. The Cloud plans use best-in-class commercial AI for speed, quality and value. The Private plan processes everything on our own servers in the EU with open models, so your audio never reaches a third-party AI at all.

-
-

Self-host

Free, forever

  • Run everything yourself
  • Your hardware, your AI keys
  • Full source and docs
  • Community support
-

Cloud Starter

from 6 pounds / month

  • Managed transcription and summaries
  • 10 hours of audio per month
  • 10 GB secure storage
  • Open API access, email support
-

Cloud Pro

from 18 pounds / month

  • Everything in Starter
  • 40 hours of audio per month
  • Priority processing, 100 GB storage
  • Team sharing, priority support
-

Private

from 39 pounds / month

  • Processed on our EU servers with open models
  • Your audio never touches a third-party AI
  • 40 hours of audio per month, 100 GB
  • Priority support, data-processing agreement
-
-

Plans and pricing shown are indicative while the hosted service is in preparation. Register your interest and we will confirm the details and early-access pricing. All hosted data is kept in the EU.

diff --git a/site/pages/how-it-works.html b/site/pages/how-it-works.html deleted file mode 100644 index 39d3f69..0000000 --- a/site/pages/how-it-works.html +++ /dev/null @@ -1,74 +0,0 @@ -

How Nightjar works

From a press of a button to a searchable, summarised transcript, every step runs on hardware and services you control. Here is the whole workflow, end to end.

-

The workflow at a glance

- -
- - - - - 1. Record - One button, to - microSD. No limit. - - 2. Sync - BLE, WiFi, or - on-charge upload - - 3. Transcribe - Your server + - your chosen AI - - 4. Summarise - Overview, points, - action items - - 5. Export - Audio, TXT, SRT, - VTT, MD, JSON - - - - - - -
- -

1. Record

The device is a small ESP32-S3 board with a digital MEMS microphone and a microSD card. A single button starts and stops recording; a status light shows what it is doing. Audio is written straight to the card as it is captured, so there is no length limit and nothing needs a network connection just to start recording. Each recording is saved with a small metadata file (duration, sample rate, and a unique id) so the rest of the pipeline can track it.

-

2. Sync

Nightjar has three independent ways to move recordings off the device, so one of them always fits your situation:

  • Bluetooth Low Energy handles control and status from the phone app: start or stop a recording, check the battery, and provision WiFi. It is low-power and always available.
  • WiFi to the app is the fast lane for transferring the actual audio. When your phone and the device are on the same network, recordings copy across quickly.
  • Independent upload on charge is the one that sets Nightjar apart. When the device is plugged in, it joins your WiFi on its own and uploads new recordings straight to your storage, with no phone involved. Leave it on the charger overnight and everything is waiting for you in the morning.
-

3. Transcribe

Once a recording reaches your server, it is transcribed into accurate, timestamped text. The transcription engine is your choice: a fully local model for maximum privacy, or a commercial speech-to-text API for the highest accuracy. Nothing is hard-wired to a single vendor.

-

4. Summarise

The transcript is then passed to a language model, which writes a structured summary: a short overview, the key points, and any action items. Again, the model is yours to pick, from a local model running on your own machine to a frontier commercial API. See Bring your own AI for the full list.

-

5. Export

Everything is available through a completely open REST API. Pull the original audio, the plain-text transcript, subtitle files (SRT or VTT), a Markdown summary, or the full record as JSON. Because the API is documented and open, you can wire Nightjar into whatever you already use.

-
-

How the pieces fit together

Four parts, all under your control, connected by an open API and a shared data model.

- -
- - - - Nightjar device - records to microSD - - Your server - Transcribe - Summarise - Open REST API + exports - - AI provider - local or commercial - - Your storage - S3 / WebDAV / NAS - - Phone app - Android and iOS - - sync - - uses - - - -
- -
  • The device captures audio and syncs it three ways.
  • Your server ingests recordings, runs transcription and summaries, and serves the open API.
  • Your AI provider does the language work, chosen by you and swappable any time.
  • Your storage and app keep and present everything. Nothing lives on someone else's cloud unless you choose it.
-

Ready to go deeper?

The guides walk through connecting an AI provider, self-hosting the server, and building the device yourself.

diff --git a/site/pages/open-source.html b/site/pages/open-source.html deleted file mode 100644 index 4976e63..0000000 --- a/site/pages/open-source.html +++ /dev/null @@ -1 +0,0 @@ -

Open source

Every part of Nightjar is open, from the circuit to the summary. Build it, improve it, keep it.

The ethos

The person who records the audio should own it. That principle runs through the whole project. Nothing depends on a service that can be taken away, and nothing traps your recordings in a format only one company can read.

  • Own your data. Audio and transcripts stay on your storage.
  • No lock-in. Open hardware, open firmware, open API.
  • Reproducible. Anyone can build the whole thing from the documentation alone.

What is open

  • Firmware for the ESP32-S3 device: recording, storage, sync and the on-device API.
  • Server that ingests recordings and runs transcription and summaries.
  • Mobile app for Android and iOS.
  • Hardware design and a bill of materials you can order.
  • 3D-printed case, parametric so it fits your exact build.

The firmware and software are copyleft, the hardware is open-hardware licensed, and the documentation is share-alike. Improvements stay open for everyone.

Build one

Off-the-shelf parts, a printed case, and a server you run. An ESP32-S3 with memory, an I2S microphone, a microSD card, a battery and a charging circuit. The firmware builds with common tooling, the case prints in a couple of hours, and the server runs on anything from a home NAS to a small cloud box.

The code is opening soon

The public repository is being prepared for release. Register your interest and we will let you know the moment it opens, so you can build, fork and contribute from day one.

diff --git a/site/pages/self-host-the-server.html b/site/pages/self-host-the-server.html deleted file mode 100644 index 394aa33..0000000 --- a/site/pages/self-host-the-server.html +++ /dev/null @@ -1,17 +0,0 @@ -

Self-host the server

The Nightjar server ingests recordings, transcribes them, writes summaries, and serves the open API. It runs happily on a home NAS, a mini-PC, or a small cloud box.

-

What you need

  • A machine running Linux (or Docker) with Python 3.11 or newer.
  • A few GB of RAM. More if you run a large local transcription model.
  • Somewhere to keep audio: a local disk, a NAS, or S3-compatible storage such as MinIO.
  • Optional: a local AI runtime (Ollama) if you want everything offline.
-

Step 1: Get the server

Clone the repository and enter the server directory.

git clone <nightjar-repo>
-cd nightjar/server

The public code is being prepared for release. Register interest to be notified when the repository opens.

-

Step 2: Install

python -m venv .venv
-. .venv/bin/activate
-pip install -r requirements.txt
-

Step 3: Configure

Copy the example config and edit it. Set your storage, and your AI providers (see Connect your AI).

cp .env.example .env
-# then edit .env:
-NIGHTJAR_STORAGE_BACKEND=local        # or s3 / webdav
-NIGHTJAR_LOCAL_MEDIA_DIR=./media
-NIGHTJAR_LLM_PROVIDER=ollama
-NIGHTJAR_TRANSCRIPTION_PROVIDER=local_whisper
-

Step 4: Run it

uvicorn app.main:app --host 0.0.0.0 --port 8000

Open http://your-server:8000/docs to browse the live API, and http://your-server:8000/health to confirm which providers are wired up.

-

Step 5: Point the device at it

In the phone app, set the server URL to your machine, and set the device’s upload target to your storage. From then on, recordings flow in automatically: the device uploads, the server transcribes and summarises, and the results appear in the app and through the API.

-

Keeping it running

For anything beyond testing, run the server under a process manager (a systemd service or a Docker container) so it restarts on reboot, and put it behind a reverse proxy with HTTPS. A small always-on box is ideal; a laptop that sleeps is not.

- diff --git a/site/tools/apiscp.php b/site/tools/apiscp.php deleted file mode 100644 index 7df960f..0000000 --- a/site/tools/apiscp.php +++ /dev/null @@ -1,79 +0,0 @@ - [json-arg ...] -// JSON args are decoded (so '["openscribe","/var/www/openscribe"]'-style or bare values work). - -$key = trim((string)file_get_contents('C:/temp/claudetemp/apiscp.key')); -if ($key === '') { fwrite(STDERR, "no api key\n"); exit(2); } - -$endpoint = 'https://howler.qsplace.co.uk:2083'; -// Use a locally-cached WSDL to avoid a second HTTPS fetch; fall back to remote. -$wsdl = is_file('C:/temp/claudetemp/apnscp.wsdl') - ? 'C:/temp/claudetemp/apnscp.wsdl' - : $endpoint . '/apnscp.wsdl'; -// The panel cert is valid, but this PHP build ships no CA bundle, so relax verify. -$ctx = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); -$client = new SoapClient($wsdl, [ - 'connection_timeout' => 30, - 'location' => $endpoint . '/soap?authkey=' . $key, - 'uri' => 'urn:net.apnscp.soap', - 'trace' => 1, - 'exceptions' => true, - 'cache_wsdl' => WSDL_CACHE_MEMORY, - 'stream_context' => $ctx, -]); - -$cmd = $argv[1] ?? ''; - -// Drive wp-cli with the command string read from a file (avoids all shell-quoting pain -// when passing large HTML content). Usage: --wpcli-file -if ($cmd === '--wpcli-file') { - $command = rtrim((string)file_get_contents($argv[2]), "\r\n"); - $host = $argv[3]; - $path = $argv[4] ?? ''; - try { - $res = $client->__soapCall('wordpress_cli', [$command, [], $host, $path]); - echo json_encode($res, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), "\n"; - exit(isset($res['success']) && !$res['success'] ? 1 : 0); - } catch (Throwable $e) { - fwrite(STDERR, 'ERROR: ' . $e->getMessage() . "\n"); - exit(1); - } -} - -if ($cmd === '--functions') { - $filter = strtolower($argv[2] ?? ''); - foreach ($client->__getFunctions() as $fn) { - if ($filter === '' || strpos(strtolower($fn), $filter) !== false) { - echo $fn, "\n"; - } - } - exit(0); -} - -if ($cmd === '') { fwrite(STDERR, "usage: php apiscp.php [json-arg ...]\n"); exit(2); } - -$args = []; -foreach (array_slice($argv, 2) as $a) { - if (strncmp($a, '@@', 2) === 0) { // @@path -> file contents as a string arg - $args[] = (string)file_get_contents(substr($a, 2)); - continue; - } - $d = json_decode($a, true); - $args[] = ($d === null && $a !== 'null') ? $a : $d; -} - -try { - $res = $client->__soapCall($cmd, $args); - echo json_encode($res, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), "\n"; -} catch (Throwable $e) { - fwrite(STDERR, 'ERROR: ' . $e->getMessage() . "\n"); - // surface the raw response for debugging (no secrets in it) - if (method_exists($client, '__getLastResponse')) { - fwrite(STDERR, "LAST RESPONSE: " . substr((string)$client->__getLastResponse(), 0, 600) . "\n"); - } - exit(1); -} diff --git a/state/DECISIONS.md b/state/DECISIONS.md index 8715aaa..32688de 100644 --- a/state/DECISIONS.md +++ b/state/DECISIONS.md @@ -3,49 +3,6 @@ > A dated, append only log of decisions and their rationale. Newest at the top. Never > rewrite past entries; if a decision is reversed, add a new entry that says so. -## 2026-07-05 - Backend infra: self-host on the MS-02 cluster (provision later) - -- **Decision:** The hosted service will run primarily on owned hardware - 3x Minisforum - MS-02-class mini-workstations, one with an RTX 3050 6GB - fronted by a Cloudflare Tunnel. - Node A (GPU) = AI worker (faster-whisper + local LLM), Node B = app/API/Postgres/Redis, - Node C = MinIO storage + overflow + HA. Cloud VMs (Hetzner) are the fallback/hybrid. - **Not provisioned yet**; stand up at first beta / paying users. Full plan: - `docs/infrastructure.md`. -- **Context:** User has the MS-02 cluster on hand and prefers self-host for small scale. -- **Rationale:** The 3050 handles whisper easily and a 7-8B summary model fits 6GB; owned - hardware is cheaper than cloud and strengthens the Private-tier privacy story (audio - never leaves our premises). Cloud fallback covers uptime-sensitive growth. -- **Consequences:** Need Cloudflare Tunnel, backups/UPS, and to mind home-hosting uptime; - 6GB VRAM caps local LLMs at ~8B until a bigger GPU is added. - -## 2026-07-05 - Commercialise via a managed "hosted" service + plan tiers - -- **Decision:** 12 Hobbies Studio offers a managed backend so people can use Nightjar - without self-hosting. Plans: Self-host (free), Cloud Starter (~GBP 6), Cloud Pro - (~GBP 18) on commercial AI, and Private (~GBP 39) on self-hosted open models (audio never - touches a third-party AI). Marketing site live; billing/signup not built yet (lead-gen - only). See `docs/hosted-service.md`. -- **Context:** User asked for commercial options where they host the backend. -- **Rationale:** Open project + managed convenience; the two backends map to the two plan - families. Cloud tiers keep good margin (cheap per-minute AI); Private is the privacy - premium. -- **Consequences:** Need metering, billing (Stripe), provisioning, a DPA, real pricing, and - a `hello@12hobbies.studio` mailbox before launch. - -## 2026-07-05 - Rebrand product to "Nightjar" (repo stays `openscribe` for now) - -- **Decision:** The product/commercial brand is **Nightjar** (site: - nightjar.12hobbies.studio). The repository keeps the name `openscribe` until a full - codebase rename is decided. -- **Context:** Due-diligence found "OpenScribe" unusable for a commercial brand (taken - domains, heavy in-category GitHub collision, weak/uncleared trademark). See - `docs/naming.md`. -- **Rationale:** "Nightjar" is distinctive, low-collision, and an arbitrary (strong) - trademark for AI software. Rejected: Mockingjay (Lionsgate TM), Lyrebird/Fathom - (in-category), dictionary words (taken/crowded), Recita (common). -- **Consequences:** Website rebranded. A full project/repo rename (SPDX, firmware - namespaces, docs, Forgejo repo) is deferred. Formal trademark clearance still needed. - ## 2026-07-03 - Pluggable AI providers (bring your own AI) - **Decision:** Transcription and summarisation each select a provider via config. LLM: diff --git a/state/PROJECT.md b/state/PROJECT.md index dbd4e29..a628e5a 100644 --- a/state/PROJECT.md +++ b/state/PROJECT.md @@ -53,16 +53,6 @@ device, browses the library, plays audio and shows transcripts and summaries. - The device syncs three ways as specified (BLE, WiFi-to-app, independent WiFi upload). - The whole stack is self-hostable and licensed for open reuse. -## Brand and commercial (2026-07) - -- **Product brand: Nightjar** (the repo is still named `openscribe`; rename deferred - see - `docs/naming.md`). -- **Marketing site:** live at https://nightjar.12hobbies.studio (WordPress on ApisCP; - content + tooling saved in `site/`). -- **Commercial model:** open project + a managed "hosted" backend with plan tiers - (`docs/hosted-service.md`); backend infra plan in `docs/infrastructure.md` (self-host on - the MS-02 cluster, provision later). - ## Key facts - Trunk branch: `main` diff --git a/state/TODO.md b/state/TODO.md index 9006bfc..7ded7e9 100644 --- a/state/TODO.md +++ b/state/TODO.md @@ -7,18 +7,6 @@ - [ ] (nothing active - M3 is next) -## Pending - brand + commercial (Nightjar) - -- [ ] Decide whether to rename the whole project/repo OpenScribe -> Nightjar (SPDX headers, - firmware namespaces, docs, Forgejo repo). Website already rebranded. See docs/naming.md. -- [ ] Formal trademark clearance for "Nightjar" (USPTO / UK IPO / EUIPO / attorney). -- [ ] Create the `hello@12hobbies.studio` mailbox (site forms/CTAs point at it) or change it. -- [ ] Confirm real hosted pricing + quotas (current numbers are indicative). -- [ ] Hosted service build: metering, Stripe billing + entitlements, tenant provisioning, - job routing (commercial vs Private node), DPA + retention policy. See docs/hosted-service.md. -- [ ] Provision backend infra at first beta/paying users (MS-02 cluster + Cloudflare Tunnel, - or Hetzner fallback). See docs/infrastructure.md. Optional: draft Docker Compose + tunnel config. - ## Pending (roughly in build order) - [ ] M3 Independent uploader: charge/VBUS detect -> powered mode, S3-compatible +