Přeskočit na obsah
Inflexion

Případová studie · Nuppo a Šeptem

Jak jsme postavili dvě aplikace pro macOS od prvního řádku po vydání a co se cestou nepovedlo.

dvě aplikace pro macOS · Swift bez Xcode · vydání zdarma · aktualizace přes Sparkle

40 dní

od prvního commitu po první vydání. U Nuppa 40 dní, u Šeptem 39. Datum vydání si ověříte na GitHubu.

den s commitem vydání

Každý čtvereček je jeden den od 22. 9. do 2. 11. Svítí dny, kdy přibyl aspoň jeden commit: u Nuppa 11, u Šeptem 8. Mezi nimi jsou týdny bez jediného.

  • 2aplikace ke stažení zdarma ve veřejných vydáních na GitHubu
  • 0 Kčstojí stažení obou aplikací. Vývojářský program Applu neplatíme.

Obojí si ověříte na stránkách vydání na GitHubu a na webech aplikací.

Rámec

Obě aplikace jsou naše. Rozhodnutí taky, i ta špatná.

Nuppo a Šeptem jsou dvě aplikace pro macOS, které si studio postavilo samo. Žádný klient, žádné zadání, žádný cizí termín. Od 1. a 2. listopadu jsou obě ke stažení zdarma.

U zakázky se rozhodnutí dá opřít o zadání. Tady ne. Rozsah, vydání zdarma, volbu přepisu i podobu ikony jsme rozhodli my a nikdo jiný je neponese. Proto je tahle studie i ukázkou, jak rozhodujeme, když rozhodujeme za někoho.

Pracujeme s moderními technologiemi, které nám zrychlují práci a iterace. Odborný lidský nadhled ale zůstává u každého rozhodnutí a každý výstup se ověřuje na stroji. Kde to bylo vidět, ukazují sekce níž.

Nejde se schovat za klienta.

Ikona aplikace Nuppo
Nuppo 22. 9. → 1. 11.commity v 11 dnech · dnes 0.9.0
Ikona aplikace Šeptem
Šeptem 24. 9. → 2. 11.commity v 8 dnech · dnes 0.9.1
Nuppo a Šeptem: první commit, vydání a dnešní verze

Výchozí stav

Ztrácet se ve screenshotech a diktovat česky s čárkami.

Nuppo vzniklo z jednoho problému majitele studia: ztrácel se v nových i starých screenshotech. První verze byla polička v notchi Macu, kam se screenshoty sbíhají a odkud se dají přetáhnout, kam jsou potřeba.

Pak přibývalo to, co bylo potřeba. Stažené soubory a poznámky už první den, později hrající skladba, časovač, přehled lokálních serverů a stav terminálových AI agentů. Z poličky na screenshoty se stal praktický pomocník. Víc věcí po ruce, méně pracného hledání jinde.

Šeptem řeší jiný problém: diktovat česky. S čárkami, se jmény a s angličtinou uprostřed věty. Obecné diktovací nástroje se češtině zvlášť nevěnují a naše analýza z 24. září v tom viděla místo, kde jde udělat líp. Obojí jsou nástroje, které jsme chtěli mít sami.

Začali jsme tím, co nás štvalo.

Nuppo · nahráno v ukázkovém režimu
Nuppo · screenshot z poličky v notchi rovnou do terminálu. Skutečná aplikace.
Ukázka · nic se nenahrává
Řečeno

no a ehm pošli mi to do pátku

Vloženo

Pošli mi to do pátku.

Vloženo: Pošli mi to do pátku.

Šeptem · simulace: podržte tlačítko, nebo ho vyberte a podržte mezerník. Vycpávková slova zmizí, přibude velké písmeno a tečka.

PředAPo

První commit měl 1 045 řádků a jiný název.

Nuppo se první den jmenovalo NotchShelf a mělo 11 souborů o 1 045 řádcích: panel v notchi, screenshoty, poznámky. Šeptem začalo o dva dny později rovnou použitelné. V prvním commitu bylo 29 souborů, 2 726 řádků a diktát na klávesu fn.

Dnes je z toho dvojice vydaných aplikací s weby a automatickými aktualizacemi. V prvním commitu nebylo skoro nic z toho: ani název, ani ikona, ani způsob, jak se k lidem dostanou. Zůstalo jádro nápadu.

Z prvního commitu se stal produkt.

první commit
  1. 22. 9.NotchShelf+1 045 řádků11 souborů · panel v notchi, screenshoty, poznámky
  2. 24. 9.Šeptem+2 726 řádků29 souborů · diktát na klávesu fn
Čísla z gitové historie. Repozitáře jsou soukromé, ověřit je nejde.
Dnes · vydánoIkona aplikace NuppoIkona aplikace Šeptem
  • název a ikona
  • web
  • vydání na GitHubu
  • automatické aktualizace
Co v prvním commitu nebylo a dnes je

Fáze 01Rozsah

Plán byl větší než výsledek. Zbylo to, co obstálo.

Analýza Šeptem z 24. září počítala s pěti fázemi: dalšími cloudovými přepisy, přepisem za běhu řeči, offline modelem a vlastními příkazy včetně překladu. V kódu zůstal jeden přepis se záložním modelem a historie v souborech, ne v databázi.

Nuppo mělo být placené: licence, zkušební doba, čekací listina, notarizace. Všechno se napsalo. Pak jsme 1. listopadu rozhodli, že bude zdarma. Je to vedlejší projekt a pracovní nástroj a nechtěli jsme za něj platit roční poplatek Applu ani řešit prodej.

Šeptem zase nemá offline model a přepis přijde až po puštění klávesy. Bez internetu se nahrávka uloží a počká. Raději to přiznáme, než abychom slibovali víc, než umíme.

Škrtat umíme.

Šeptem@@ plán 24. 9. → realita @@

  1. Škrtnuto: Další cloudové přepisy (ElevenLabs, Soniox)
  2. Škrtnuto: Offline model Parakeet
  3. Škrtnuto: Přepis za běhu řeči
  4. Škrtnuto: Historie v databázi SQLite
  5. Škrtnuto: Vlastní příkazy a překlad
  6. Zbylo: Přepis přes Groq Whisper se záložním modelem
  7. Zbylo: Historie v souborech

5 deletions(−), 2 insertions(+)

Nuppo@@ placená verze → zdarma, 1. 11. @@

  1. Škrtnuto: Prodej přes App Store (sandbox by vzal čtení Plochy a Stažených)
  2. Škrtnuto: Developer ID, notarizace a DMG
  3. Škrtnuto: Licence a zkušební doba 14 dní
  4. Škrtnuto: Čekací listina
  5. Zbylo: Vydání zdarma, vlastní certifikát

4 deletions(−), 1 insertions(+)

Fáze 02Volba nástrojů

Nativní Swift bez Xcode, protože fn a notch jinak nejdou.

Obě aplikace jsou ve Swiftu a staví se z terminálu, bez Xcode. Důvod není ideologický: klávesa fn, Zpřístupnění i vkládání textu fungují spolehlivě jen nativně. Cena: vzhled Liquid Glass u Nuppa jsme museli dokreslit sami, nativní rozhraní se s naší verzí SDK nepřeložilo.

Čísla výrobců se měří na čtených textech z Wikipedie. My diktujeme hovorově, s anglicismy, jmény a čísly. Proto jsme 35 vět nadiktovali vlastním hlasem a nechali je přepsat.

V měření skončily dva modely Whisper přes službu Groq. Větší chyboval u 11,7 % slov a odpovídal za 0,85 s, rychlejší u 12,2 % za 0,55 s. Klíč si každý uživatel zadá vlastní, takže Šeptem nemá náš server a nic z hlasu k nám neodchází.

Rozhodlo číslo, ne reklama.

Měření přepisu na 35 větách vlastního hlasu
ModelChybovost slovLatence, medián
Whisper large-v3 (hlavní)11,7 %0,85 s
Whisper large-v3 turbo (záloha)12,2 %0,55 s
Groq, 35 vět vlastního hlasu, upravené nahrávky. Větší model je přesnější, menší rychlejší. Stupnice nezačínají nulou.

Fáze 03Značka

Název, ikonu a písmo jsme vybírali ve více kolech.

Nuppo se přejmenovalo ještě před vydáním. NotchShelf, Nupo i Pluck narazily na existující produkty. Přejmenování stálo migraci dat a jedno pravidlo: identita, kterou zná systém, zůstala stará, aby se nikomu neztratilo nastavení.

Ikona Nuppa, postavička visící z notche se screenshotem v ruce, měla tři verze za jediný den. Šeptem dostalo tři návrhy loga a vybralo háček jako vlnu. Písmo se vybíralo ve dvou kolech, nejdřív ze čtyř kandidátů, pak ze šesti serifů, a zvítězil Gloock.

Vzhled se nedá navrhnout naslepo. První Liquid Glass v Nuppu byl zabílený a plochý a ke správnému vzhledu vedla čtyři kola se screenshoty.

Značka se nehádá, vybírá se.

  1. Název NuppaNotchShelfNupoPluckNuppotři názvy narazily na existující produkty
  2. Ikona Nuppapostavička z notchetři verze za jediný den, 23. 9.
  3. Logo Šeptemháček jako vlnatři návrhy
  4. Písmo ŠeptemGloockdvě kola: čtyři kandidáti, pak šest serifů
#ff5a28 rumělka Šeptem · písmo Gloock
Ikona aplikace Nuppo#ff9f5a broskvová Nuppa · akcent jde v appce změnit

Fáze 04Stavba

Nahrávka je na disku dřív, než odejde. To je celá spolehlivost.

Šeptem je řetěz pěti kroků: podržíte fn, appka nahrává, zvuk se zapisuje na disk, odešle se k přepisu a hotový text se vloží tam, kde máte kurzor. Podstatné je pořadí. Nahrávka leží na disku dřív, než cokoli opustí Mac.

Tím se řeší, co se pokazí. Když spadne síť, nahrávka počká a přepíše se sama. Když vložení propadne mimo textové pole, text zůstane ve schránce a kartička nabídne Kopírovat. Když se vloží jinam, fn a V ho vloží znovu.

Kolem modelu stojí filtry. Na tichu Whisper vymýšlí věty jako „Titulky vytvořil JohnyX“, appka je zahodí. Text pak dostane čárky a českou typografii. Moderní nástroje nám zrychlují psaní kódu, ale co smí appka ztratit, rozhodl člověk: nic.

Diktát se neztratí.

  1. Podržíte fnappka nahrává – proběhlo
  2. Nahrávka na diskdřív, než cokoli opustí Mac – proběhlo
  3. PřepisGroq Whisper, vlastní klíč – proběhlo
  4. Filtr a úpravapryč s vymyšlenými větami, čárky – proběhlo
  5. Vloženítam, kde máte kurzor – proběhlo
Text je tam, kde máte kurzor. Celý řetěz proběhl.
Ukázka toku jedné nahrávky. Přepínače poruchu jen simulují, nic se neodesílá.

Fáze 05Zkouška

Skutečné používání ukázalo, co v kódu vidět nebylo.

Šeptem se začalo používat první den. AirPods přepnou do telefonního režimu a zvuk zhorší, proto appka nahrává z vestavěného mikrofonu. Později jsme museli hlídat, aby systém AirPods nebo iPhone nevybral jako výchozí vstup. U dvouminutových diktátů navíc Whisper kazí úseky a ztrácí diakritiku, proto se pokažené části přepisují znovu.

Nejnepříjemnější byly zápisy ze schůzek. Po nastavení zařízení se zvukový engine restartoval asi pětkrát za sekundu a mikrofon prakticky nenahrával. A při hovoru v Safari macOS potlačí ozvěnu, takže v nahrávce chyběl hlas. Opravili jsme příčiny a přidali varování pro ztlumený mikrofon.

U Nuppa tlačítko ⋯ nedostávalo kliky a nepomohlo ani další ladění v SwiftUI, takže jsme sáhli o vrstvu níž do AppKitu. Detekce aplikací na celé obrazovce funguje u Chromu až se třetím signálem. Proč, nevíme, a máme to zapsané.

Každá chyba má v historii svůj commit.

opravy · příznak, příčina, oprava
  1. NuppoTlačítko ⋯ nedostává kliky

    příčina
    Tlačítko v SwiftUI události nedostávalo, ladění nepomohlo
    oprava
    Kliky přebírá AppKit, o vrstvu níž
  2. ŠeptemNahrávka s AirPods zní špatně

    příčina
    Bluetooth sluchátka se přepnou do telefonního režimu
    oprava
    Výchozí je vestavěný mikrofon
  3. ŠeptemNadiktovaný text zmizel

    příčina
    Vložení propadlo mimo textové pole a schránka se obnovila
    oprava
    Nevložený přepis zůstane ve schránce, kartička Kopírovat
  4. ŠeptemSystém vybral AirPods nebo iPhone

    příčina
    Výchozí vstup systému se změnil
    oprava
    Appka hlídá výchozí vstup
  5. ŠeptemDlouhý diktát má pokažené úseky

    příčina
    Whisper kazí úseky u dvouminutových nahrávek
    oprava
    Pokažené úseky se přepíšou znovu zvlášť
  6. ŠeptemZápis schůzky bez hlasu

    příčina
    Smyčka asi pěti restartů zvukového enginu za sekundu
    oprava
    Nastavení zařízení bez smyčky, hlídání výpadku zvuku
  7. ŠeptemPři hovoru chybí hlas

    příčina
    macOS při hovoru potlačí ozvěnu a pošle plochý signál
    oprava
    Zpracování hlasu a varování při ztlumeném mikrofonu
  8. NuppoChrome na celé obrazovce

    stav
    Detekce funguje až se třetím signálem. Proč, nevíme. Máme to zapsané.

Vydání

Bez účtu u Applu: vlastní certifikát a aktualizace přes Sparkle.

Apple chce za vývojářský program 99 dolarů ročně. Obě aplikace jsou zdarma a Nuppo je vedlejší projekt, tak jsme se rozhodli ho neplatit. Cena je vidět hned: při prvním spuštění macOS hlásí, že aplikaci nemohl zkontrolovat, a otevře ji až na výslovné přání.

Aplikace ale podepisujeme. Vlastním certifikátem, který platí deset let, ne podpisem pro jedno sestavení. Ne kvůli Gatekeeperu, ten certifikát neuzná. Kvůli oprávněním: podpis, který se mění s každým buildem, by po každé aktualizaci smazal přístup k Ploše, Stažených souborům nebo Zpřístupnění.

Aktualizace jdou přes Sparkle a podepisujeme je vlastním klíčem. Řetěz je pokaždé stejný: podpis, ZIP se součtem SHA-256, podpis aktualizace, seznam verzí a vydání na GitHubu. Zdrojový kód zůstává soukromý, veřejné je jen to, co si můžete stáhnout.

Zdarma neznamená bez řemesla.

.zipSEPTEM DEV · VLASTNÍ PODPIS
  1. Podpis certifikátemvlastní, platí deset let
  2. ZIP a součet SHA-256
  3. Podpis aktualizacevlastní klíč Sparkle
  4. Seznam verzíappcast
  5. Vydání na GitHubu
  6. Sparkle u uživatele
Dialog Gatekeeperu na macOS 14: Šeptem nelze otevřít, protože Apple nemůže zkontrolovat škodlivý software
Takhle vypadá první spuštění ZIPu na macOS 14. Otevře se pravým tlačítkem a volbou Otevřít.

Web

Dva weby bez sledování a instalace jedním příkazem.

Oba weby jsou statické, v Astru, na Vercelu. Bez analytiky a bez Google Fonts, písma jsou přibalená. Web Nuppa stál dva dny po prvním commitu, web Šeptem až v posledních dvou dnech před vydáním.

Vedle ZIPu nabízí každá aplikace instalaci jedním příkazem. Skript ověří součet SHA-256, nainstaluje a odstraní karanténu, takže Gatekeeper nezasáhne. Instalace skriptem z internetu ale není pro každého, proto je vedle návod na ruční postup pro macOS 14 i 15.

Weby ukazují, ne tvrdí. U Nuppa si ukázku vyzkoušíte bez stažení a smyčky jsou nahrané ze skutečné aplikace v demo režimu. U Šeptem je na webu živá ukázka úpravy textu.

Náhled webu Nuppa
Načte se skutečný web nuppo.inflexion.cz.
Náhled webu Šeptem
Načte se skutečný web septem.inflexion.cz.
instalace jedním příkazem
curl -fsSL https://nuppo.inflexion.cz/install.sh | sh
curl -fsSL https://septem.inflexion.cz/install.sh | sh

Co netvrdíme

Co aplikace neumí a co si ověříte sami.

Něco aplikace neumí a říkáme to dopředu. Nuppo čte z obrázku angličtinu, čísla a kód, češtinu ne, protože ji rozpoznávání textu v macOS 14 neumí. Šeptem potřebuje internet a vlastní klíč, bez nich nepřepíše. U obou macOS při prvním spuštění zobrazí varování.

Kód je soukromý, takže si ho nepřečtete. Proto se studie opírá o to, co ověřit jde: veřejná vydání, živé weby a chování aplikací. Jednu věc máme ověřenou na vlastní oči: 2. listopadu si verze 0.9.0 Šeptem stažená z GitHubu sama našla a nainstalovala 0.9.1.

Raději to řekneme sami.

Ověřeno

  • 2. 11. · Šeptem 0.9.0 sama našla a nainstalovala 0.9.1 přes Sparkle (macOS 14)
  • 1. 11. a 2. 11. · obě vydání jsou veřejně na GitHubu
  • 2. 11. · Gatekeeper na macOS 14: otevření pravým tlačítkem (Šeptem)
  • 24. 9. · přepis změřen na vlastním hlase

Omezení

  • Nuppo nečte češtinu z obrázku
  • Šeptem funguje jen s internetem a vlastním klíčem
  • macOS ukáže varování při prvním spuštění

Péče

Po vydání práce nekončí.

Šeptem vyšlo 2. listopadu jako 0.9.0 a o pětadvacet minut později jako 0.9.1. Nová ikona, web a okno O aplikaci se do první verze nevešly, tak šly hned do druhé.

Pak přišlo skutečné používání. Ukázalo, že nastavení obsahuje to, co běžný uživatel řešit nemá: modely, adresu API, jazyk. Schováváme je do sbalené sekce Pokročilé s tlačítkem Obnovit výchozí. K tomu přibývá průvodce prvním spuštěním, který odškrtává mikrofon, Zpřístupnění, klávesu fn i klíč.

A pak zkouška, na kterou jsme čekali. Stáhli jsme ZIP s 0.9.0 z GitHubu, otevřeli pravým tlačítkem a zvolili Zkontrolovat aktualizace. Sparkle nabídl 0.9.1 s poznámkou k vydání a po restartu běžela nová verze. Bez Applu, bez obchodu s aplikacemi, jen GitHub a vlastní podpis.

Vydání je začátek, ne konec.

  1. Nuppo 0.9.0
  2. Šeptem 0.9.0
  3. Šeptem 0.9.1
  4. aktualizace 0.9.0 na 0.9.1 přes Sparkle
Dialog Gatekeeperu na macOS 14: Šeptem nelze otevřít, protože Apple nemůže zkontrolovat škodlivý softwareOkno Sparkle: nová verze Šeptem 0.9.1 je k dispozici, máte 0.9.0Okno Sparkle Updating Šeptem: Ready to Install
Ukázka: okna Sparkle jsou překreslená podle skutečných snímků z 2. 11. (17:54 až 17:55, macOS 14), anglicky, jak je kreslila ještě 0.9.0.

Závěr

Kdo dotáhne vlastní produkt, ví, co zakázka stojí.

Postup byl u obou aplikací stejný: nápad z vlastní potřeby, malý rozsah, měření tam, kde se dá, vydání a opravy podle používání. Nic z toho není objev. Zajímavé je, že to jde dotáhnout i bez všeho, co vydání obvykle usnadňuje: bez Applu, bez notarizace, bez prodejce.

Zahodili jsme hotovou licenci, hotovou čekací listinu a část plánu Šeptem. Zahozená práce stojí míň než zahozené vydání, ale stojí. A rozhodnutí o obchodním modelu patří před práci na jeho technice. To si odnášíme do každé zakázky.

Moderní nástroje nám pomáhají jít rychleji. Úsudek, co dělat, co škrtnout a kdy říct, že něco není ověřeno, zůstává u lidí. Klient dostane radu, ne obhajobu už vynaložené práce.

Dvě aplikace jsou důkaz, že produkt dotáhneme.

Dva projekty. Jeden podpis.

Metodika

Co v téhle studii nenajdete.

Počty stažení ani uživatelů, tržby, srovnání s konkurencí a zdrojový kód, ten je soukromý. Vydání a jejich data, živé weby a chování samotných aplikací si můžete ověřit sami. Čísla z gitové historie, tedy 40 dní, 1 045 a 2 726 řádků, ověřit nejdou, repozitáře jsou soukromé. Říkáme to rovnou.

Chcete vlastní produkt místo další vizitky?

Popište nám, co potřebujete postavit, nebo si nejdřív spočítejte, co by vám vlastní systém ušetřil.