Files
finrod/CHANGELOG.md
João Pedro Battistella Nadas a058665b5b feat: vim p/P paste from system clipboard
Vim's default p/P pastes from its internal unnamed register, which
is useless when the text to translate lives in another app's
clipboard. Override both in normal mode to read navigator.clipboard
.readText() and insert at (after) or before the cursor.

Caveats: requires browser clipboard permission (prompted on first
use), HTTPS or localhost. Both already satisfied — finrod is served
over the wildcard TLS cert.
2026-06-09 16:41:52 +02:00

2.9 KiB

Changelog

All notable changes to finrod are documented here.

Format: Keep a Changelog. Versioning: Semantic Versioning.

[Unreleased]

Added

  • Vim bindings in the input via CodeMirror 6 + @replit/codemirror-vim (loaded from esm.sh, no build step). Supports i/Esc, hjkl, word/line motions, dd/yy/p, undo/redo, / search, : command line. Auto-disabled on touch devices (detected via (pointer: coarse)) where modal editing fights the virtual keyboard.
  • Shift-H / Shift-L cycle focus across the page controls (source → target → model → editor → button) like Shift-Tab / Tab. Also overridden in vim normal mode (replacing vim's viewport-top/bottom default) so the same shortcut works to leave the editor.
  • p / P in vim normal mode paste from the system clipboard at / before the cursor (vim's default registers are skipped — the realistic source for a translator is another app, not an in-editor yank).
  • On page load, the model dropdown defaults to whichever model Ollama already has hot — skips the 5-15 s disk-reload pain on the first translation. After load it follows the user's manual selection.

Changed

  • Editor font-size pinned to 1rem to match the output pane (CodeMirror 6 ships smaller by default).

[0.1.0] - 2026-06-09

First release. Stateless translator UI that proxies streaming requests to Ollama on radagast.

Added

  • FastAPI backend with three endpoints:
    • GET /api/models — filtered (gemma,aya by default) list from Ollama's /api/tags
    • POST /api/translate — streams Ollama's NDJSON /api/generate response back to the browser
    • GET /api/loaded — proxies Ollama's /api/ps for the currently-loaded model
    • GET /healthz — for Kubernetes probes
  • Single-page UI:
    • Source / target / model dropdowns (30+ languages, "Auto-detect" source)
    • Token-by-token streaming into the output pane with a blinking caret
    • Live status line: spinner while waiting for first token, pulsing dot during streaming, elapsed time and token count
    • Glowing border on the output pane during streaming
    • Loaded-model indicator ( prefix in dropdown, "Hot: … — unloads in Xm" status line); refreshes on page load, on translation completion, and 500 ms after typing pauses
    • ⌘/Ctrl-Enter to translate from the input
    • Dark mode, inline SVG favicon (Star of Fëanor)
  • Dockerfile: two-stage uv build, slim Python 3.13 runtime
  • build.sh: multi-arch (amd64 + arm64) manual push to Scaleway, tags :latest, :<git-short-sha>, and :<pyproject-version>
  • Cluster deploy via the valinor repo at apps/finrod/ (bjw-s app-template, internal-only ingress at finrod.jpnadas.xyz)

Fixed

  • Lock against public PyPI explicitly — the workstation's global uv config had pointed uv.lock sources at the dexterenergy private artifact registry, which 401'd inside Docker