Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Twyne

Twyne is a writer-first editing room. It opens with an anti-tabula-rasa interview so a draft starts from context instead of a blank page, then keeps that brief in front of every editor, judge, and margin note for the rest of the piece.

Features

  • Rich-text drafting with Tiptap, Qwik City, Vite, and Tailwind CSS.
  • Anti-tabula-rasa project interview for title, format, audience, goal, tone, constraints, and success signal — with typed follow-ups (multiple choice, fill-in-the-blanks, scales) generated from what you've already said.
  • A room of five editorial personas that read from your brief and draft and leave grounded feedback — and that read along as you write, not only when you ask.
  • Rubric scoring gated on relevance: a Target Fit judge decides whether the draft is about the right thing, and caps the shape metrics when it isn't.
  • Voice: hear each editor in their own voice, record spoken margin notes, and answer the interview out loud.
  • Citation detection for URLs, DOIs, ISBNs, author-year citations, and footnote markers.
  • Comments panel for review notes and threaded replies.
  • Apparatus research panel (pluggable providers) for searching and pulling sources while writing.
  • Convex backend for sync, with Better Auth (passkeys) sign-in and writer-owned ATProto / Standard.site publishing, including canonical Twyne readers and publication/document verification links.
  • BYOK AI: bring your own key in Settings, stored in your browser and never sent to a server.
  • Installable PWA with brand favicons and per-article OpenGraph share cards.

The editorial room

Four panels sit beside the manuscript: Cast (the five editors), Rubric (the galley proof), Marginalia (your notes), and Apparatus (sources). Each tab carries an unread count, so work that arrives while you're looking elsewhere isn't silent.

The room reads as you write

Convening the room is deliberate and expensive — five model calls over the whole manuscript. Alongside it, a background pass runs on a narrower brief: once you've written ~300 net new words and stopped typing for two minutes, all five editors read only the new paragraphs, plus a digest of how the draft has been moving.

Those arrive as quieter "in passing" notes in the Cast panel. Two spend guards sit on top — a five-minute floor between passes and a per-session cap — because this runs without you asking. Turn it off with Read as I write in the room settings.

The same digest goes along when you do press Convene, so the deliberate pass knows the trajectory rather than re-reading a cold snapshot.

The rubric grades against this piece

The static feature scorer measures shape — sentence-length variance, type-token ratio, paragraph balance. It never reads the brief, so fluent prose about the wrong subject used to score 10/10 on three categories.

A Target Fit judge now scores relevance independently of craft, and caps every shape-derived criterion by it. Lowering target fit can only ever lower the grade, never raise it.

The criteria themselves are yours to shape. Twyne ships a fixed spine so a score in March means the same thing in June; you can disable or reweight any of it, add criteria of your own ("stays in second person", "every section ends on an image") for the room to judge, or ask it to suggest criteria fitted to your format — proposals you accept, never applied silently. Customise anything and a second "by your weights" score appears beside the editorial grade. Every pass is recorded, so the panel shows the run of grades rather than a snapshot.

Voice

What Needs
Hear an editor, memo, or review read aloud BYOK speech provider, or Twyne-hosted voice (Pro)
Read the selection (or whole draft) aloud same
Record a spoken margin note microphone + BYOK or hosted transcription
Answer the interview out loud same

Each of the five editors has their own voice, per provider — Fish Audio names voices by id and OpenAI by name, so the mapping is per-provider rather than one shared field. Spoken notes keep both the recording and the transcript: the transcript threads, resolves and @-mentions like any other note, and you edit it before it saves. Audio stays local and does not sync.

BYOK providers

Keys live in your browser (IndexedDB) and are never sent to a Twyne server. Settings → AI lets you set a default and override any individual feature.

  • Language: OpenAI, Anthropic, Google, DeepSeek, OpenRouter, Ollama, Z.ai / GLM, MiniMax, and any OpenAI- or Anthropic-compatible endpoint. The desktop build also auto-registers a local Gemma 4 E4B served on loopback.
  • Speech: OpenAI (or an OpenAI-compatible endpoint) for both narration and transcription; Fish Audio for voice only.

Fish Audio speaks but cannot think, so it is never offered to the persona, rubric or interview features — configuring it alone won't make those features try a client path they can't complete. Its s2.1-pro-free model works without API credit; transcription (/v1/asr) does not, and needs a funded API balance.

Requirements

  • Bun 1.3.x or newer (install + build).
  • Node ≥ 20 (runs the SSR server; server.js uses node:http).

Optional: devenv for a reproducible shell with pinned Bun. With devenv + direnv installed, the shell activates automatically when you cd into the repo (the .envrc handles it).

Environment

Copy .env.example to .env.local and fill in at least VITE_CONVEX_URL, VITE_CONVEX_SITE_URL, and BETTER_AUTH_SECRET. VITE_* / PUBLIC_* values are inlined at build time. See .env.example for the full annotated list.

Development

bun install
bun run dev   # Convex dev + Vite SSR

Or, with devenv:

devenv shell   # enter the pinned shell
bun install
bun run dev

The app runs locally with Vite, usually at http://localhost:5173/.

Build

bun run build

The build emits browser assets to dist/ and server output to server/.

Run a built server

bun run build.client && bun run build.server
node server.js

The server listens on PORT, defaulting to 3000.

Deployment

Twyne deploys to Railway (Bun build, Node runtime) via railway.json and railpack.json. Custom domain: twyne.love. See docs/DEPLOYMENT.md for service setup, environment variables, and the custom-domain steps.

Desktop app

A native desktop build wraps the hosted app via Electrobun:

bun run desktop         # dev build + launch
bun run desktop.build   # production bundle into ./build

See docs/DEPLOYMENT.md for config, the TWYNE_DESKTOP_URL dev override, and platform caveats.

Releases

Releases use Bumpy bump files to generate changelog entries and version tags. The repo installs a pre-push hook on bun install that runs bumpy check --hook pre-push.

bun run release:add      # add a bump file for a change
bun run release:version  # consume bump files, update CHANGELOG.md, bump version
bun run release:publish  # create git tags and GitHub releases

Tagged releases are built by GitHub Actions. Each release uploads a twyne-<version>.tar.gz bundle containing the source, lockfile, production build output, and server entry point so people can download and run that version.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages