Public Kitchen Report

Back to app

Not reviewed by AI (1)

These files are too big or are one very long line, so the AI review skipped them. The rest of the report is complete. If a file matters to you, look at it yourself.

  • 1 file is one very long line (often minified or generated)

Scores

Score details and supporting evidence for each check.

98 / 100

All promised features found

Features found in source

31.5 of 32 checked features (98%); 0 couldn't be verified; partial features count half.

The AI read 36 of 54 source files.

Features found in the code

Found: 31; Partly: 1; Missing: 0; Couldn't verify: 0

App specification source review: 31.5 of 32 features found in source (98.44%)

Show the 32 features
  • ◐ Download and prepare the optional Kokoro voice package with visible setup progress. — partly

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift, Sources/Leaf/LocalKokoroWorker.swift

    performInstall downloads runtime/model with stage text shown in settings; progress is text-only, no numeric progress.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift#performInstall

  • ✓ Open an unencrypted EPUB and display its readable chapter text, title, and author. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/EPUBImporter.swift, Sources/Leaf/DemoBook.swift

    EPUBImporter.load parses title/author/chapters and rejects encrypted EPUBs; ReaderModel.load displays imported book.

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/EPUBImporter.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#openBook, Sources/ReaderCore/EPUBImporter.swift#load

  • ✓ Navigate between pages using the reader’s page controls. — found

    Files checked: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/PageText.swift

    Footer prev/next buttons call turnPage; turnPage computes destination page and repaginates.

    Evidence: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift#turnPage

  • ✓ Jump to a chapter from the contents sidebar. — found

    Files checked: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/ListeningExperience.swift

    Contents sidebar buttons call selectChapter, which sets chapterIndex and repaginates.

    Evidence: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift#selectChapter

  • ✓ Adjust reading text size while preserving the current passage during page reflow. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/PageText.swift

    Font size slider triggers repaginate; repaginate anchors on readingOffset/session offset.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift#repaginate

  • ✓ Reopen a previously opened book from the library. — found

    Files checked: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/BookLibrary.swift

    Library list buttons call openLibraryBook, which resolves URL and loads with saved position.

    Evidence: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/ReaderModel.swift#openLibraryBook

  • ✓ Filter the library by book title or author. — found

    Files checked: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/BookLibrary.swift, Sources/Leaf/DemoBook.swift

    Search field filters library by title or author case-insensitively.

    Evidence: Sources/Leaf/BookLibraryView.swift

    Files from your spec: Sources/Leaf/BookLibraryView.swift

  • ✓ Remove a library entry while keeping the original EPUB and saved bookmarks. — found

    Files checked: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/BookLibrary.swift

    Remove button calls removeLibraryBook, which only drops the library entry; EPUB and bookmark stores untouched

    Evidence: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/BookLibraryView.swift, Sources/Leaf/ReaderModel.swift#removeLibraryBook

  • ✓ Restore saved reading and narration positions when returning to a book. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingPosition.swift, Sources/Leaf/BookLibrary.swift

    applyRestoredPosition restores chapter, text and speech offsets; ReadingPosition and LibraryBook persist them

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingPosition.swift, Sources/Leaf/BookLibrary.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#applyRestoredPosition, Sources/Leaf/ReadingPosition.swift, Sources/Leaf/BookLibrary.swift

  • ✓ Save selected text as a bookmark for the current book. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReaderAnnotations.swift, Sources/Leaf/BookLibrary.swift

    bookmarkSelectedText appends a TextBookmark from the selection and saves it via TextBookmarkStore

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReaderAnnotations.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#bookmarkSelectedText, Sources/Leaf/ReaderAnnotations.swift

  • ✓ Jump to a saved bookmark’s passage. — found

    Files checked: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingPosition.swift

    Sidebar bookmark button calls openBookmark, which jumps to the chapter and page containing the passage

    Evidence: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift#openBookmark

  • ✓ Delete a saved bookmark. — found

    Files checked: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingPosition.swift

    Sidebar xmark and in-page remove button both call removeBookmark, which deletes and saves

    Evidence: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/ReaderView.swift, Sources/Leaf/ReaderModel.swift#removeBookmark

  • ✓ Read book text aloud using an installed Mac voice. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/DemoBook.swift

    speak uses AVSpeechSynthesizer with a chosen installed voice; settings list Mac voices

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingSettingsView.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#speak, Sources/Leaf/ReadingSettingsView.swift

  • ✓ Read book text aloud offline using an installed Kokoro voice. — found

    Files checked: Sources/Leaf/SpeechSettings.swift, Sources/Leaf/CloudNarrator.swift, Sources/Leaf/LocalKokoroWorker.swift

    Local provider config, CloudNarrator local branch, and Kokoro worker generate found in source

    Evidence: Sources/Leaf/SpeechSettings.swift, Sources/Leaf/CloudNarrator.swift, Sources/Leaf/LocalKokoroWorker.swift

    Files from your spec: Sources/Leaf/SpeechSettings.swift#configuration, Sources/Leaf/CloudNarrator.swift#prepare, Sources/Leaf/LocalKokoroWorker.swift#generate

  • ✓ Read book text aloud using an OpenRouter speech model. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift, Sources/ReaderCore/CloudSpeech.swift

    speak uses cloud config; prepare calls client.speech; OpenRouter speech POST found in source

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift, Sources/ReaderCore/CloudSpeech.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#speak, Sources/Leaf/CloudNarrator.swift#prepare, Sources/ReaderCore/CloudSpeech.swift#speech

  • ✓ Pause and resume narration. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift, Sources/Leaf/ReaderView.swift

    toggleReading pause/resume and CloudNarrator pause/resume found in source

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#toggleReading, Sources/Leaf/CloudNarrator.swift

  • ✓ Change narration pace. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift

    Pace picker, updateRate, and cloud setRate found in source

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift#updateRate

  • ✓ Move backward or forward by sentence during an active or paused listening session. — found

    Files checked: Sources/Leaf/LeafApp.swift, Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/SentenceNavigation.swift

    Arrow commands, navigateReading, and SentenceNavigation.destination found in source

    Evidence: Sources/Leaf/LeafApp.swift, Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/SentenceNavigation.swift

    Files from your spec: Sources/Leaf/LeafApp.swift, Sources/Leaf/ReaderModel.swift#navigateReading, Sources/ReaderCore/SentenceNavigation.swift#destination

  • ✓ Start narration from a clicked word or sentence. — found

    Files checked: Sources/Leaf/PageText.swift, Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/CloudSpeech.swift

    PageText mouseUp onSeek and ReaderModel.seek found in source

    Evidence: Sources/Leaf/PageText.swift, Sources/Leaf/ReaderModel.swift

    Files from your spec: Sources/Leaf/PageText.swift, Sources/Leaf/ReaderModel.swift#seek

  • ✓ Follow narration with word or sentence highlighting. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift, Sources/Leaf/PageText.swift

    Word/sentence highlight found in source: CloudNarrator tick emits ranges, ReaderModel sets highlight, PageText paints it.

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift, Sources/Leaf/PageText.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift, Sources/Leaf/CloudNarrator.swift#tick, Sources/Leaf/PageText.swift

  • ✓ Open a fullscreen listening view during a listening session. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReaderView.swift, Sources/Leaf/ListeningExperience.swift

    toggleListeningView, fullscreen sync, and ListeningExperience overlay found in source.

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReaderView.swift, Sources/Leaf/ListeningExperience.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#toggleListeningView, Sources/Leaf/ReaderView.swift#syncListeningFullscreen, Sources/Leaf/ListeningExperience.swift

  • ✓ Preview a local or cloud voice using fixed sample text. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingSettingsView.swift, Sources/ReaderCore/CloudSpeech.swift

    previewCloudVoice uses fixed sample text; settings buttons for local and cloud preview found in source.

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/ReadingSettingsView.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/ReaderModel.swift#previewCloudVoice

  • ✓ Cancel an ongoing Kokoro setup. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift, Sources/Leaf/LocalCommand.swift

    cancelInstall cancels task; LocalCommand terminates subprocess and throws CancellationError, shown in source.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift, Sources/Leaf/LocalCommand.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift#cancelInstall

  • ✓ Retry or repair Kokoro setup. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift, Sources/Leaf/LocalKokoroWorker.swift

    install() and Repair/check setup button re-run performInstall, found in source.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift#install

  • ✓ Remove downloaded Kokoro files. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift, Sources/Leaf/LocalKokoroWorker.swift

    Remove download button calls local.remove(), which deletes the Kokoro root directory and clears state.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/LocalKokoro.swift#remove

  • ✓ Save an OpenRouter API key securely in macOS Keychain. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift, Sources/Leaf/ReaderModel.swift

    Save key button calls saveKey(), which stores the key via Keychain SecItemAdd/Update.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift#saveKey

  • ✓ Remove the saved OpenRouter API key. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift, Sources/Leaf/ReaderModel.swift

    Remove key button calls removeKey(), which deletes the Keychain item via SecItemDelete.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift#removeKey

  • ✓ Refresh the available OpenRouter speech-model list. — found

    Files checked: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift, Sources/ReaderCore/CloudSpeech.swift

    Refresh models button awaits refreshModels(), which fetches the speech model catalog from OpenRouter.

    Evidence: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift, Sources/ReaderCore/CloudSpeech.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/SpeechSettings.swift#refreshModels

  • ✓ Request audio transcription timestamps for cloud highlighting, with a visible fallback to estimated timing when alignment fails. — found

    Files checked: Sources/Leaf/CloudNarrator.swift, Sources/ReaderCore/CloudSpeech.swift, Sources/Leaf/ReadingSettingsView.swift

    prepare() requests timings when transcribed mode; on failure falls back to estimated timings with a warning.

    Evidence: Sources/Leaf/CloudNarrator.swift, Sources/ReaderCore/CloudSpeech.swift

    Files from your spec: Sources/Leaf/ReadingSettingsView.swift, Sources/Leaf/CloudNarrator.swift#prepare, Sources/ReaderCore/CloudSpeech.swift#timings

  • ✓ Look up selected text in macOS Dictionary. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/DictionaryLookup.swift, Sources/Leaf/DictionaryLookupView.swift

    lookUpSelectedText uses LocalDictionary DCSCopyTextDefinition and shows result in DictionaryLookupView.

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/DictionaryLookup.swift, Sources/Leaf/DictionaryLookupView.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#lookUpSelectedText, Sources/Leaf/DictionaryLookup.swift#definition, Sources/Leaf/DictionaryLookupView.swift

  • ✓ Request an online definition through OpenRouter when the local dictionary has no result and a key is saved. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/CloudSpeech.swift, Sources/Leaf/ReadingSettingsView.swift

    Local dictionary first, then OpenRouter dictionaryDefinition with saved key; found in source

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/ReaderCore/CloudSpeech.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#lookUpSelectedText, Sources/ReaderCore/CloudSpeech.swift#dictionaryDefinition

  • ✓ Prevent automatic display and system idle sleep while narration or a voice preview is active. — found

    Files checked: Sources/Leaf/ReaderModel.swift, Sources/Leaf/PlaybackActivity.swift, Sources/Leaf/ReaderView.swift

    setActive disables idle system and display sleep; called for speaking or preview; found in source

    Evidence: Sources/Leaf/ReaderModel.swift, Sources/Leaf/PlaybackActivity.swift

    Files from your spec: Sources/Leaf/ReaderModel.swift#updatePlaybackActivity, Sources/Leaf/PlaybackActivity.swift#setActive

Static AI review of the source. Partial features count half. Actual run verification: Not tested; source presence and a responding demo do not prove the features work.

82 / 100

Good, small improvements suggested

Security screening

3 security issue(s) found; serious issues reduce this score most. No scan guarantees safety.

  • medium · Archive entry paths passed to unzip without full sanitization · Sources/ReaderCore/EPUBImporter.swift

    What to do: Validate the resolved path stays within the archive root and reject absolute or traversal paths before invoking unzip; consider a native ZIP reader instead of shelling out.

  • medium · Unpinned third-party Python dependencies installed during local voice setup · Sources/Leaf/Resources/LocalKokoro.requirements.txt

    What to do: Pin and verify the requirements file hash or use a lockfile with hashes; document the trust boundary and consider sandboxing the worker process.

  • low · Model refresh network call lacks explicit timeout handling · Sources/Leaf/SpeechSettings.swift

    What to do: Add a timeout and cancellation to the model refresh request and surface failures without blocking the settings UI.

57 / 100

Some setup steps missing

Setup files

Present: README, run entry point, App specification or AGENTS. Missing: environment example, known install command. Static check in .; code was not executed. Checks README, environment example, install and run scripts, app specification or AGENTS, confirmed How to run it (confirmed) and run manifest (absent). The app was not executed.

  • ✓ README — README.md
  • ✕ Environment example
  • ✕ Install command
  • ✓ Run entry point
  • ✓ App specification or AGENTS — Saved App specification
  • ✓ Confirmed How to run it
  • ✕ Run manifest

Not checked

Not checked

Dependency & license health

Dependency and license evidence has not been checked.

      Source coverage: Sampled — some eligible source files were omitted

      Dependency vulnerability check: Inconclusive — dependency coverage is incomplete

      Build not run by CookThisApp.

      Suggestions (4)

      Most serious first · Page 1

      • Archive entry paths passed to unzip without full sanitization

        Medium — could affect users in some situations; plan a fix.

        A crafted EPUB could cause unzip to read entries outside the intended archive path or trigger unexpected unzip behavior, potentially exposing local files or crashing the importer.

        Review finding — does not by itself block publishing.

        Fix hint: Validate the resolved path stays within the archive root and reject absolute or traversal paths before invoking unzip; consider a native ZIP reader instead of shelling out.

        Open

        ai-security · Sources/ReaderCore/EPUBImporter.swift
      • Unpinned third-party Python dependencies installed during local voice setup

        Medium — could affect users in some situations; plan a fix.

        Users who run Kokoro setup download and execute a large Python dependency tree from the network; a compromised package or index could run arbitrary code on the user's Mac.

        Review finding — does not by itself block publishing.

        Fix hint: Pin and verify the requirements file hash or use a lockfile with hashes; document the trust boundary and consider sandboxing the worker process.

        Open

        ai-security · Sources/Leaf/Resources/LocalKokoro.requirements.txt
      • Model refresh network call lacks explicit timeout handling

        Low — limited impact; fix during routine maintenance.

        If OpenRouter is slow or unreachable, the settings UI can remain in a loading state and the user cannot easily recover.

        Review finding — does not by itself block publishing.

        Fix hint: Add a timeout and cancellation to the model refresh request and surface failures without blocking the settings UI.

        Open

        ai-security · Sources/Leaf/SpeechSettings.swift
      • Platform check: macOS selected but no macOS project found

        Low — an improvement hint for the developer, with no confirmed user harm.

        Review finding — does not by itself block publishing.

        Fix hint: Review the platforms in your listing Basics. This information does not affect the score or publication.

        Open

        platform-check ·

      Kitchen Report

      Current run: generation 2

      Leaf · Version 01a1c524-8990-7e18-ac12-42284f15d3df

      Report complete.

      Live provider analysis

      Ordinary dependency advisories are disclosed warnings and allow publication. Harmful source, malicious packages and unresolved rights or license blockers prevent publication.

      Features found in source are not proof the app works. Actual run verification: Not tested. License and rights eligibility requires the seller’s declarations; dependency license compatibility: Not checked. Checks do not guarantee safety or production readiness.

      Download reportView findings and fixes

      Our estimate: $7–12 in AI usage, plus your own time.

      How we estimate

      We estimate AI usage for repeated edits and context reads, priced at Claude Sonnet 5.5 rates. Repeated reads use the provider's cached-input price.

      The developer sets the price; this estimate is guidance only.

      Formula v4 · AI usage estimate · 5 rework iterations · 16× context · claude-sonnet-5-5 · Price table 2

      Source checks

      Source check ✓ 10/11/2026

      1. 1. Unpacking · ✓ Done
      2. 2. Secret scan · ✓ Done
      3. 3. Safety scan (S1) · ✓ Done
      4. 4. Dependency scan (S2) · ✓ Done
        For developers: code quality

        Improvement hints only; these do not contribute to buyer headline scores.

        Architecture / structure: 79 / 100 (AI structure review)

        Code cleanliness: 77 / 100 (AI maintainability review)

        Test presence: 0 test files found (presence signal only). Coverage: Not checked.

        Source size: 6734 LOC (metric, not a scored check).

        • ReaderModel is a large god-object mixing import, speech, bookmarks, lookup and persistence; splitting would aid review. Sources/Leaf/ReaderModel.swift
        • CloudNarrator cache and chunk queueing are subtle; a brief comment on eviction and lookahead policy would help. Sources/Leaf/CloudNarrator.swift
        • EPUBImporter shells out to /usr/bin/unzip; document the sandbox/availability assumption for packaged builds. Sources/ReaderCore/EPUBImporter.swift

        Help us improve CookThisApp

        0/2000